我有带有页码(1、2、3等)的组合框。当用户选择特定页面时(通过鼠标或键盘(组合框可编辑))。我要显示和总计页面。这就是为什么我在组合框操作中也会这样做的原因:
combobox.setValue(currentPage+"/"+totalPages)
所以最终的代码看起来像
@FXML
private void onPageComboBoxAction(ActionEvent event){
....
combobox.setValue(currentPage+"/"+totalPages)
}
但是,此代码又触发了一个ActionEvent和代码周期。因此,我看到了两种可能的方法:
处理一些特定事件(但是哪些以及如何处理)
寻找在不触发另一个事件的情况下更改组合框值的方法(再次如何?)
谁能帮我解决这个问题?
最佳答案
setValue(...)
更改组合框保存的值(即,它更改数据或基础模型的状态)。在我看来,您真正想要的只是改变数据的显示方式。您可以通过设置按钮单元格来更改所选值的显示。
这是一个示例,其中按钮单元格同时跟踪所选项目和页面数:
import java.util.Random;
import java.util.stream.IntStream;
import javafx.application.Application;
import javafx.collections.ListChangeListener.Change;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.control.ListCell;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
public class PageNumberCombo extends Application {
private static final Random RNG = new Random();
@Override
public void start(Stage primaryStage) {
ComboBox<Integer> combo = new ComboBox<>();
combo.setButtonCell(new ListCell<Integer>() {
{
itemProperty().addListener((obs, oldValue, newValue) -> update());
emptyProperty().addListener((obs, oldValue, newValue) -> update());
combo.getItems().addListener((Change<? extends Integer> c) -> update());
}
private void update() {
if (isEmpty() || getItem() == null) {
setText(null);
} else {
setText(String.format("%d / %d", getItem().intValue(), combo.getItems().size()));
}
}
});
Button reloadButton = new Button("Reload");
reloadButton.setOnAction(e -> reload(combo));
reload(combo);
HBox root = new HBox(10, combo, reloadButton);
root.setAlignment(Pos.CENTER);
root.setPadding(new Insets(24));
primaryStage.setScene(new Scene(root, 240, 60));
primaryStage.show();
}
private void reload(ComboBox<Integer> combo) {
int numPages = RNG.nextInt(10) + 11 ;
combo.getItems().clear();
IntStream.rangeClosed(1, numPages).forEach(combo.getItems()::add);
}
public static void main(String[] args) {
launch(args);
}
}
如果您的
ComboBox
是可编辑的,则默认情况下按钮单元格是TextField
,组合框的converter
用于将文本字段中的字符串值转换为模型值,反之亦然。因此,在这种情况下,您只需要安装一个在整数x
和字符串"x / total"
之间转换的转换器。请注意,默认情况下,此转换器还用于在下拉列表的单元格中显示文本,因此,如果希望这些文本显示为整数值,则需要安装
cellFactory
来显式创建这些单元格。import java.util.Random;
import java.util.stream.IntStream;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.control.ListCell;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
import javafx.util.StringConverter;
public class PageNumberCombo extends Application {
private static final Random RNG = new Random();
@Override
public void start(Stage primaryStage) {
ComboBox<Integer> combo = new ComboBox<>();
combo.setEditable(true);
combo.setConverter(new StringConverter<Integer>() {
@Override
public String toString(Integer object) {
return object + " / " + combo.getItems().size();
}
@Override
public Integer fromString(String string) {
int index = string.indexOf('/');
if (index < 0) {
index = string.length();
}
String text = string.substring(0, index).trim();
try {
return Integer.parseInt(text);
} catch (Exception exc) {
return 0 ;
}
}
});
combo.setCellFactory(lv -> new ListCell<Integer>() {
@Override
public void updateItem(Integer item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setText(null) ;
} else {
setText(item.toString());
}
}
});
Button reloadButton = new Button("Reload");
reloadButton.setOnAction(e -> reload(combo));
reload(combo);
HBox root = new HBox(10, combo, reloadButton);
root.setAlignment(Pos.CENTER);
root.setPadding(new Insets(24));
primaryStage.setScene(new Scene(root, 240, 60));
primaryStage.show();
}
private void reload(ComboBox<Integer> combo) {
int numPages = RNG.nextInt(10) + 11 ;
combo.getItems().clear();
IntStream.rangeClosed(1, numPages).forEach(combo.getItems()::add);
}
public static void main(String[] args) {
launch(args);
}
}