2013-06-18 47 views
4

目標:創建一個具有多個文本字體的圓形按鈕。用於懸停和多邊字體的圓形邊緣上的多個字體的較少CSS欺騙

示例:見RoundButtonWithMultipleFonts.java和RoundButtonWithMultipleFonts.css

RoundButtonWithMultipleFonts.java:

import javafx.application.Application; 
import javafx.event.EventHandler; 
import javafx.scene.Parent; 
import javafx.scene.Scene; 
import javafx.scene.control.Button; 
import javafx.scene.control.Control; 
import javafx.scene.control.Label; 
import javafx.scene.input.MouseEvent; 
import javafx.scene.layout.StackPane; 
import javafx.stage.Stage; 

public class RoundButtonWithMultipleFonts extends Application { 
    public static void main(String... args) { 
    launch(args); 
    } 

    @Override 
    public void start(Stage stage) throws Exception { 
    stage.setTitle("Button with multiple fonts?"); 
    stage.setScene(new Scene(getRoot(), 400, 400)); 
    stage.getScene().getStylesheets().addAll(getClass().getResource("RoundButtonWithMultipleFonts.css").toExternalForm()); 
    stage.sizeToScene(); 
    stage.show(); 
    } 

    private Parent getRoot() { 
    Button button = new Button(""); // The labels should be the buttons text 
    button.setOnMouseClicked(new EventHandler<MouseEvent>() { 
     @Override 
     public void handle(MouseEvent mouseEvent) { 
     System.out.println("Button clicked"); 
     } 
    }); 

    Label header = new Label("A Prideful Header"); // Label for big font on button 
    header.getStyleClass().addAll("header"); 

    Label footer = new Label("a humble footer"); // Label for small font on button 
    footer.getStyleClass().addAll("footer"); 

    // Since the labels are on top of the button, pass any events they capture to the button 
    configurePassThroughEvents(button, header, footer); 

    StackPane stack = new StackPane(); 
    stack.getChildren().addAll(button, header, footer); 

    return stack; 
    } 

    private void configurePassThroughEvents(Control targetControl, Control... sourceControls) { 
    MouseEventPassThrough passThroughEvent = new MouseEventPassThrough(targetControl); 
    for(Control sourceControl : sourceControls) { 
     sourceControl.setOnMouseClicked(passThroughEvent); 
     sourceControl.setOnMouseDragged(passThroughEvent); 
     sourceControl.setOnMouseDragEntered(passThroughEvent); 
     sourceControl.setOnMouseDragExited(passThroughEvent); 
     sourceControl.setOnMouseDragOver(passThroughEvent); 
     sourceControl.setOnMouseDragReleased(passThroughEvent); 
     sourceControl.setOnMouseEntered(passThroughEvent); 
     sourceControl.setOnMouseExited(passThroughEvent); 
     sourceControl.setOnMouseMoved(passThroughEvent); 
     sourceControl.setOnMousePressed(passThroughEvent); 
     sourceControl.setOnMouseReleased(passThroughEvent); 
    } 
    } 

    private static class MouseEventPassThrough implements EventHandler<MouseEvent> { 
    private final Control targetControl; 
    private MouseEventPassThrough(Control targetControl) { this.targetControl = targetControl; } 
    @Override public void handle(MouseEvent mouseEvent) { targetControl.fireEvent(mouseEvent); } 
    } 
} 

RoundButtonWithMultipleFonts.css:

.button { 
    -fx-border-width: 1px; 
    -fx-border-color: #000000; 
    -fx-border-radius: 45; 
    -fx-background-color: linear-gradient(#ffffff 0%, #cccccc 100%); 
    -fx-background-radius: 45; 
    -fx-padding: 50 100; 
} 
.button:hover { 
    -fx-background-color: linear-gradient(#ffffff 0%, coral 100%); 
} 

.label { 
    -fx-padding: 10; 
    -fx-background-color: cornflowerblue; 
} 

.header { 
    -fx-font-size: 110%; 
    -fx-font-weight: bold; 
    -fx-translate-y: -20; 
} 

.footer { 
    -fx-font-size: 80%; 
    -fx-translate-y: 20; 
} 

運行結果:

Mouse is over the corner of the button but not inside the buttons visual boundary. The button is showing as if the mouse is hovering over it, but the mouse is not over the visual boundary of the button as specified by the css border and background properties.

問題:

  1. 當在按鈕上的角部中的一個鼠標卷軸,該按鈕進入懸停狀態,但鼠標仍然外按鈕邊框和背景指示的按鈕的可視範圍。 (見圖)

  2. 這個例子使用了一個堆棧窗格,多個標籤,一個事件傳遞機制和CSS欺騙來給出包含多種字體文本的按鈕的外觀。

問題:

  1. 我怎麼可以指定只有當鼠標在與邊框或背景的CSS指定的按鈕視覺邊界碰撞的按鈕應該進入懸停狀態屬性?

  2. 是否有更簡單的方法來指定多個字體(與一般文本佈局)的按鈕比這個例子中做了什麼?理想情況下,我只想使用帶有嵌套節點的Button作爲文本。這將允許我在按鈕文本區域內放置任何我想要的內容,而不需要事件通過機制,StackPane和CSS欺騙。

回答

6

可以使用ButtonsetGraphic(Node node);方法按鈕設置你的自定義標籤。這裏是一個例子,

Label header = new Label("A Prideful Header"); 
header.getStyleClass().addAll("header"); 

Label footer = new Label("a humble footer"); 
footer.getStyleClass().addAll("footer"); 


VBox box = new VBox(); 
box.getChildren().addAll(header,footer); 

Button button = new Button(); 
button.setGraphic(box); 
+0

+ 1用於回答如何刪除StackPane,事件直通機制和一些CSS欺騙的需要。 我仍然在尋找一個答案,使鼠標進入視覺邊界時,按鈕只進入懸停狀態,由背景或邊框CSS屬性指定。如果您可以編輯您的答案以包含該問題的解決方案,我將選擇此作爲接受的答案。謝謝。 – axiopisty

+1

@axiopisty,我想你的圓形按鈕沒有解決方案,理由是:儘管它顯示了一個圓形的按鈕,它佔據/覆蓋了整個空間。你爲什麼不使用圖像而不是使用按鈕? –