因此,我遵循this blog(特别是part 2)创建自定义控件并将其导入Scene Builder。将setOnAction方法添加到自定义场景构建器控件
这是什么样子:
这里是FXML文件:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<fx:root maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="30.0" prefWidth="150.0" type="AnchorPane" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
<children>
<HBox alignment="CENTER" layoutX="-65.0" layoutY="-56.0" spacing="5.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<children>
<Button fx:id="previousButton" minWidth="25.0" mnemonicParsing="false" prefWidth="25.0" text="<" />
<Label fx:id="label" alignment="CENTER" contentDisplay="CENTER" prefWidth="500.0" text="Label" />
<Button fx:id="nextButton" minWidth="25.0" mnemonicParsing="false" prefWidth="25.0" text=">" />
</children>
</HBox>
</children>
</fx:root>
下面是类文件:
package swipeselector;
import java.io.IOException;
import java.util.ArrayList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.AnchorPane;
/**
*
* @author patrickb
*/
public class SwipeSelector extends AnchorPane {
@FXML
private Button previousButton;
@FXML
private Label label;
@FXML
private Button nextButton;
ArrayList<String> items;
int selectedIndex;
private boolean repetitive;
public SwipeSelector() {
FXMLLoader fxmlLoader = new FXMLLoader(
getClass().getResource("swipeSelectorFXML.fxml"));
fxmlLoader.setRoot(this);
fxmlLoader.setController(this);
try {
fxmlLoader.load();
} catch (IOException exception) {
throw new RuntimeException(exception);
}
items = new ArrayList<>();
selectedIndex = 0;
previousButton.setOnAction((ActionEvent event) -> {
setPrevious();
});
nextButton.setOnAction((ActionEvent event) -> {
setNext();
});
}
public void setItems(ArrayList<String> items) {
this.items = items;
selectFirst();
}
public void setPrevious() {
updateItem(selectedIndex - 1);
}
public void setNext() {
updateItem(selectedIndex + 1);
}
public void selectFirst() {
updateItem(0);
}
private void selectLast() {
updateItem(items.size() - 1);
}
private void updateItem() {
if (items.isEmpty()) {
label.setText("");
} else {
if (selectedIndex < 0) {
if (repetitive) {
selectedIndex = items.size() - 1;
} else {
selectedIndex = 0;
}
}
if (selectedIndex >= items.size()) {
if (repetitive) {
selectedIndex = 0;
} else {
selectedIndex = items.size() - 1;
}
}
label.setText(items.get(selectedIndex));
}
}
private void updateItem(int selectedIndex) {
this.selectedIndex = selectedIndex;
updateItem();
}
public void setRepetitive(boolean cyclesThrough) {
this.repetitive = cyclesThrough;
}
}
一切工作正常,但是:当我点击下一个或上一个按钮时,我想要一些好玩的东西在我原来的项目中。我通常会通过将setOnAction(new EventHandler ...
方法添加到对象来实现此目的。虽然这个方法不存在,所以我不知何故需要将它添加到我的自定义控件中。 如何在每次点击两个按钮之一时使自定义控件调用一个ActionEvent,以及如何为我的对象创建一个setOnAction方法,该方法将工作?
感谢您的回答,我确实查看了ButtonBase,但不明白事件是如何触发的。原来这是来自Node的fireEvent。我会发布自己的答案,因为我找到了一种方法使其工作,感谢您的帮助,非常感谢! – Maverick283
@ Maverick283是的,你需要从节点调用一个方法。SimpleEventHandlerProperty使这更容易,因为您不需要实现自定义属性子类。 – Puce
你在那里做了什么看起来相当不错!我认为尽管现在我的解决方案可以达到我的目的,但是感谢分享。 – Maverick283