JavaFX - 使用图像创建自定义按钮

jer*_*ome 21 javafx

我想创建一个自定义按钮,按下或不按下两个状态,如切换按钮.我有两个图像要做(按下而不是按下),那么如何创建按钮并将其与我的图像一起显示?该按钮必须采用图像的大小.
我没有使用FXML.谢谢你的帮忙.

jew*_*sea 51

有几种不同的方法来实现这一点,我将概述我的最爱.

使用ToggleButton并为其应用自定义样式.我建议这是因为你需要的控件"就像一个切换按钮",但只是看起来与默认的切换按钮样式不同.

我首选的方法是在css中为按钮定义一个图形:

.toggle-button {
  -fx-graphic: url('http://icons.iconarchive.com/icons/aha-soft/desktop-buffet/128/Pizza-icon.png');
}

.toggle-button:selected {
  -fx-graphic: url('http://icons.iconarchive.com/icons/aha-soft/desktop-buffet/128/Piece-of-cake-icon.png');
}
Run Code Online (Sandbox Code Playgroud)

或使用附加的CSS定义背景图像.

// file imagetogglebutton.css deployed in the same package as ToggleButtonImage.class
.toggle-button {
  -fx-background-image: url('http://icons.iconarchive.com/icons/aha-soft/desktop-buffet/128/Pizza-icon.png');
  -fx-background-repeat: no-repeat;
  -fx-background-position: center;
}

.toggle-button:selected {
  -fx-background-image: url('http://icons.iconarchive.com/icons/aha-soft/desktop-buffet/128/Piece-of-cake-icon.png');
}
Run Code Online (Sandbox Code Playgroud)

我更喜欢-fx-graphic规范而不是-fx-background-*规范,因为设置背景图像的规则很棘手并且设置背景不会自动调整按钮的大小,而设置图形则会.

还有一些示例代码:

import javafx.application.Application;
import javafx.scene.*;
import javafx.scene.control.ToggleButton;
import javafx.scene.layout.StackPaneBuilder;
import javafx.stage.Stage;

public class ToggleButtonImage extends Application {
  public static void main(String[] args) throws Exception { launch(args); }
  @Override public void start(final Stage stage) throws Exception {
    final ToggleButton toggle = new ToggleButton();
    toggle.getStylesheets().add(this.getClass().getResource(
      "imagetogglebutton.css"
    ).toExternalForm());
    toggle.setMinSize(148, 148); toggle.setMaxSize(148, 148);
    stage.setScene(new Scene(
      StackPaneBuilder.create()
        .children(toggle)
        .style("-fx-padding:10; -fx-background-color: cornsilk;")
        .build()
    ));
    stage.show();
  }
}
Run Code Online (Sandbox Code Playgroud)

这样做的一些好处是:

  1. 您将获得默认的切换按钮行为,无需通过添加自己的焦点样式,鼠标和键处理程序等自行重新实现它.
  2. 如果您的应用程序被移植到不同的平台,例如移动设备,它将开箱即用,响应触摸事件而不是鼠标事件等.
  3. 您的样式与应用程序逻辑分离,因此更容易重新设置应用程序.

另一种方法是不使用css并仍使用ToggleButton,但在代码中设置图像图形:

import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.scene.*;
import javafx.scene.control.ToggleButton;
import javafx.scene.image.*;
import javafx.scene.layout.StackPaneBuilder;
import javafx.stage.Stage;

public class ToggleButtonImageViaGraphic extends Application {
  public static void main(String[] args) throws Exception { launch(args); }
  @Override public void start(final Stage stage) throws Exception {
    final ToggleButton toggle      = new ToggleButton();
    final Image        unselected  = new Image(
      "http://icons.iconarchive.com/icons/aha-soft/desktop-buffet/128/Pizza-icon.png"
    );
    final Image        selected    = new Image(
      "http://icons.iconarchive.com/icons/aha-soft/desktop-buffet/128/Piece-of-cake-icon.png"
    );
    final ImageView    toggleImage = new ImageView();
    toggle.setGraphic(toggleImage);
    toggleImage.imageProperty().bind(Bindings
      .when(toggle.selectedProperty())
        .then(selected)
        .otherwise(unselected)
    );

    stage.setScene(new Scene(
      StackPaneBuilder.create()
        .children(toggle)
        .style("-fx-padding:10; -fx-background-color: cornsilk;")
        .build()
    ));
    stage.show();
  }
}
Run Code Online (Sandbox Code Playgroud)

基于代码的方法的优点是,如果您不熟悉css,则不必使用css.

为了获得最佳性能并轻松移植到未签名的applet和webstart沙箱,请将图像与您的应用捆绑在一起,并通过相对路径网址引用它们,而不是从网上下载它们.

  • 我必须添加-fx-background-color:透明;在CSS中仅使我的按钮充满我的图像。 (2认同)

小智 7

您只需要创建自己继承自父级的类.在其上放置一个ImageView,在mousedown和mouse up事件上只需更改ImageView的图像.

public class ImageButton extends Parent {

    private static final Image NORMAL_IMAGE = ...;
    private static final Image PRESSED_IMAGE = ...;

    private final ImageView iv;

    public ImageButton() {
        this.iv = new ImageView(NORMAL_IMAGE);
        this.getChildren().add(this.iv);

        this.iv.setOnMousePressed(new EventHandler<MouseEvent>() {

            public void handle(MouseEvent evt) {
                iv.setImage(PRESSED_IMAGE);
            }

        });

        // TODO other event handlers like mouse up

    } 

}
Run Code Online (Sandbox Code Playgroud)