Déj*_* vu 0 java combobox javafx
我的问题如下,
为了这个问题,我在一个新项目中重现了这个问题.
假设我有一个带有组合框的应用程序,那里可能有一个或多个项目.我希望当用户点击组合框中的某个项目时会发生"某事".
我制作了以下代码:
obsvList.add("item1");
cbTest.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
System.out.println("Item clicked");
}
});
Run Code Online (Sandbox Code Playgroud)
这在应用程序启动并且第一次选择项目时有效.当组合框中有2个或更多项目时(当用户单击项目1,然后单击项目2,然后单击项目1时),这也适用
但是我的问题是,当组合框中只有1个项目时,让我们说"item1".然后用户重新打开组合框并再次单击"item1",然后它将不会重做动作.
只有在单击"新建"项目时,它才会打印"项目单击"行.
我希望它能说清楚我遇到的问题是什么,如果没有请求澄清,我会在需要的地方给出.
提前致谢!
组合框的功能是向用户显示可供选择的选项列表.当您使用意味着选择的控件时,您应该确保UI始终与所选的选项一致.如果这样做,那么当用户"重新选择"相同选项时(因为UI已经处于所需状态),"重复动作"是没有意义的.一种方法是在组合框的值上使用绑定或侦听器:
import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.scene.Scene;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class ComboBoxExample extends Application {
@Override
public void start(Stage primaryStage) {
ComboBox<Item> choices = new ComboBox<>();
for (int i = 1 ; i <=3 ; i++) {
choices.getItems().add(new Item("Choice "+i, "These are the details for choice "+i));
}
Label label = new Label();
choices.valueProperty().addListener((obs, oldItem, newItem) -> {
label.textProperty().unbind();
if (newItem == null) {
label.setText("");
} else {
label.textProperty().bind(newItem.detailsProperty());
}
});
BorderPane root = new BorderPane();
root.setCenter(label);
root.setTop(choices);
Scene scene = new Scene(root, 400, 400);
primaryStage.setScene(scene);
primaryStage.show();
}
public class Item {
private final String name ;
private final StringProperty details = new SimpleStringProperty() ;
public Item(String name, String details) {
this.name = name ;
setDetails(details) ;
}
public String getName() {
return name ;
}
@Override
public String toString() {
return getName();
}
public final StringProperty detailsProperty() {
return this.details;
}
public final String getDetails() {
return this.detailsProperty().get();
}
public final void setDetails(final String details) {
this.detailsProperty().set(details);
}
}
public static void main(String[] args) {
launch(args);
}
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,当用户"重新选择"相同的选项时,从不需要重复动作,因为代码始终确保UI与所选择的内容一致(如果用户选择了该选项,则无需执行任何操作已选择的选项).通过在显示详细信息的UI部分中使用绑定(在这种情况下只是一个简单的标签),我们可以确保,如果数据在外部发生变化,UI将保持最新状态.(显然在实际应用中,这可能要复杂得多,但基本策略仍然完全相同.)
另一方面,如果用户选择相同的功能,则需要重复动作的功能被更好地视为向用户呈现一组"动作".对此的适当控制是菜单,带按钮的工具栏和MenuButtons.
一组可重复动作的示例是:
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.MenuButton;
import javafx.scene.control.MenuItem;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class MenuButtonExample extends Application {
@Override
public void start(Stage primaryStage) {
MenuButton menuButton = new MenuButton("Items");
Label label = new Label();
Item[] items = new Item[3];
for (int i = 1 ; i <=3 ; i++) {
items[i-1] = new Item("Item "+i);
}
for (Item item : items) {
MenuItem menuItem = new MenuItem(item.getName());
menuItem.setOnAction(e -> item.setTimesChosen(item.getTimesChosen() + 1));
menuButton.getItems().add(menuItem);
}
label.textProperty().bind(Bindings.createStringBinding(() ->
Stream.of(items)
.map(item -> String.format("%s chosen %d times", item.getName(), item.getTimesChosen()))
.collect(Collectors.joining("\n")),
Stream.of(items)
.map(Item::timesChosenProperty)
.collect(Collectors.toList()).toArray(new IntegerProperty[0])));
BorderPane root = new BorderPane();
root.setCenter(label);
root.setTop(menuButton);
Scene scene = new Scene(root, 400, 400);
primaryStage.setScene(scene);
primaryStage.show();
}
public static class Item {
private final String name ;
private final IntegerProperty timesChosen = new SimpleIntegerProperty();
public Item(String name) {
this.name = name ;
}
public String getName() {
return name ;
}
@Override
public String toString() {
return getName();
}
public final IntegerProperty timesChosenProperty() {
return this.timesChosen;
}
public final int getTimesChosen() {
return this.timesChosenProperty().get();
}
public final void setTimesChosen(final int timesChosen) {
this.timesChosenProperty().set(timesChosen);
}
}
public static void main(String[] args) {
launch(args);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6844 次 |
| 最近记录: |