目標:創建一個具有多個文本字體的圓形按鈕。用於懸停和多邊字體的圓形邊緣上的多個字體的較少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;
}
運行結果:
問題:
當在按鈕上的角部中的一個鼠標卷軸,該按鈕進入懸停狀態,但鼠標仍然外按鈕邊框和背景指示的按鈕的可視範圍。 (見圖)
這個例子使用了一個堆棧窗格,多個標籤,一個事件傳遞機制和CSS欺騙來給出包含多種字體文本的按鈕的外觀。
問題:
我怎麼可以指定只有當鼠標在與邊框或背景的CSS指定的按鈕視覺邊界碰撞的按鈕應該進入懸停狀態屬性?
是否有更簡單的方法來指定多個字體(與一般文本佈局)的按鈕比這個例子中做了什麼?理想情況下,我只想使用帶有嵌套節點的Button作爲文本。這將允許我在按鈕文本區域內放置任何我想要的內容,而不需要事件通過機制,StackPane和CSS欺騙。
+ 1用於回答如何刪除StackPane,事件直通機制和一些CSS欺騙的需要。 我仍然在尋找一個答案,使鼠標進入視覺邊界時,按鈕只進入懸停狀態,由背景或邊框CSS屬性指定。如果您可以編輯您的答案以包含該問題的解決方案,我將選擇此作爲接受的答案。謝謝。 – axiopisty
@axiopisty,我想你的圓形按鈕沒有解決方案,理由是:儘管它顯示了一個圓形的按鈕,它佔據/覆蓋了整個空間。你爲什麼不使用圖像而不是使用按鈕? –