JavaFX-使用图像创建自定义按钮
我想创建一个自定义按钮,有两种状态按下或不按下,像一个切换按钮。我有两个图像来做这件事(按下和未按下),那么我如何创建按钮,并显示它与我的图像?按钮必须采用图像的大小。JavaFX-使用图像创建自定义按钮,javafx,Javafx,我想创建一个自定义按钮,有两种状态按下或不按下,像一个切换按钮。我有两个图像来做这件事(按下和未按下),那么我如何创建按钮,并显示它与我的图像?按钮必须采用图像的大小。 我没有使用FXML。 感谢您的帮助。您只需创建自己的类,该类继承自父类。 在上面放置一个ImageView,在mousedown和MouseUp事件上只需更改ImageView的图像 public class ImageButton extends Parent { private static final Image
我没有使用FXML。
感谢您的帮助。您只需创建自己的类,该类继承自父类。 在上面放置一个ImageView,在mousedown和MouseUp事件上只需更改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
}
}
公共类ImageButton扩展父类{
私有静态最终图像法线_图像=。。。;
私有静态最终图像按下_图像=。。。;
私人最终影像视图四;
公共图像按钮(){
this.iv=新图像视图(正常图像);
this.getChildren().add(this.iv);
this.iv.setOnMousePressed(新的EventHandler(){
公共无效句柄(MouseEvent evt){
iv.设置图像(按下图像);
}
});
//TODO其他事件处理程序,如鼠标悬停
}
}
实现这一点有几种不同的方法,我将概述我最喜欢的方法
使用并对其应用自定义样式。我建议这样做是因为您所需的控件“类似于切换按钮”,但看起来与默认的切换按钮样式不同
我的首选方法是在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');
}
或者使用附加的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');
}
与-fx background-*规范相比,我更喜欢-fx图形规范,因为设置背景图像样式的规则比较复杂,设置背景不会自动调整按钮与图像的大小,而设置图形则会
还有一些示例代码:
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();
}
}
这样做的一些好处是:
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();
}
}
基于代码的方法的优点是,如果与css不相似,则不必使用css
为了获得最佳性能并易于移植到未签名的小程序和webstart沙盒,请将图像与应用程序捆绑在一起,并通过相对路径URL引用它们,而不是从网上下载它们。前面两个答案的组合就达到了目的。谢谢从Button继承的新类。注意:在显示按钮之前应调用updateImages()
import javafx.event.EventHandler;
import javafx.scene.control.Button;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
public class ImageButton extends Button {
public void updateImages(final Image selected, final Image unselected) {
final ImageView iv = new ImageView(selected);
this.getChildren().add(iv);
iv.setOnMousePressed(new EventHandler<MouseEvent>() {
public void handle(MouseEvent evt) {
iv.setImage(unselected);
}
});
iv.setOnMouseReleased(new EventHandler<MouseEvent>() {
public void handle(MouseEvent evt) {
iv.setImage(selected);
}
});
super.setGraphic(iv);
}
}
导入javafx.event.EventHandler;
导入javafx.scene.control.Button;
导入javafx.scene.image.image;
导入javafx.scene.image.ImageView;
导入javafx.scene.input.MouseEvent;
公共类ImageButton扩展按钮{
公共无效更新图像(已选择最终图像,未选择最终图像){
最终图像视图iv=新图像视图(选定);
this.getChildren().add(iv);
iv.setOnMousePressed(新的EventHandler(){
公共无效句柄(MouseEvent evt){
iv.设置图像(未选择);
}
});
iv.setOnMouseReleased(新的EventHandler(){
公共无效句柄(MouseEvent evt){
iv.设置图像(选定);
}
});
超级图形(四);
}
}
Wow!我能说什么?这是一个非常好的答案,非常感谢。我想我会选择第一种解决方案,我会在代码中将大小应用到我的按钮上,这在JavaFX应用程序中似乎很常见,不像Swing;在css中,只让我的按钮填充我的图像。这是一个很好的答案,但显示了JavaFX的一个弱点。这种要求在21世纪是杂乱无章和毫无根据的。你更喜欢哪一个更强大的解决方案?