4

目標:複数のテキスト フォントを持つ丸いボタンを作成します。

例: 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 の境界線と背景のプロパティで指定されたボタンの視覚的な境界線上にありません。

問題:

  1. マウスがボタンの角の 1 つをスクロールすると、ボタンはホバー状態になりますが、マウスはボタンの境界線と背景によって示されるボタンの視覚的な境界の外にあります。(画像参照)

  2. この例では、スタック ペイン、複数のラベル、イベント パス スルー メカニズム、CSS トリックを使用して、複数のフォントのテキストを含むボタンの外観を提供します。

質問:

  1. css で指定されているように、マウスがボタンの視覚的な境界と境界線または背景のプロパティで指定されている場合にのみ、ボタンがホバー状態になるように指定するにはどうすればよいですか?

  2. ボタンに複数のフォント (一般的なテキスト レイアウト) を指定する簡単な方法は、この例よりも簡単ですか? 理想的には、ネストされた Node を持つ Button をテキストとして使用したいだけです。これにより、イベント パス スルー メカニズム、StackPane、および css トリックを必要とせずに、ボタンのテキスト領域内に必要なものをすべて配置できます。

4

1 に答える 1