2017-05-25 186 views
0

嗨,我有一个组合框的问题。我有一个四个组合框的界面,他们使用作为项目相同的列表。我向这些组合框中的一个添加了监听器,并且我希望在我选择某个项目时完成监听器,而不是在列表发生更改时完成监听器,但使用此监听器时,automaticalli会再次运行,当我从列表中删除项目时设置监听器Combobox JavaFX

  class1.getSelectionModel().selectedItemProperty().addListener((options, oldValue, newValue) ->{ 

      System.out.println(oldValue); 
      System.out.println(newValue); 

      class1.getItems().add(oldValue); 
      class1.getItems().remove(newValue); 

      }); 

所以在最后,他每次我做了删除时间运行此监听器,并将其与错误最终

+0

如果删除所选的项目,那么显然选择将不得不改变。你究竟想在这里发生什么? (为什么你改变选择的变化列表?) –

+0

我想显示在组合框值我选择的项目,但我希望该项目从列表中删除,所以当我再次点击该组合框它会显示为所有选项,除了已经选择的选项 –

回答

0

的问题主要出现是因为你最终改变可观察名单(选择模型的selectedItems),而结束正在处理该列表中的更改。这在API中是一个缺陷,imo。一种解决方法(黑客)是一个Platform.runLater(...)使用过滤列表,并更新谓词的名单上,这样才能让第一个变化再次改变之前完成:

import javafx.application.Application; 
import javafx.application.Platform; 
import javafx.collections.FXCollections; 
import javafx.collections.ObservableList; 
import javafx.collections.transformation.FilteredList; 
import javafx.scene.Scene; 
import javafx.scene.control.ComboBox; 
import javafx.scene.layout.BorderPane; 
import javafx.stage.Stage; 

public class ComboBoxNoSelectedItem extends Application { 

    @Override 
    public void start(Stage primaryStage) { 
     ObservableList<String> allItems = FXCollections.observableArrayList("One", "Two", "Three", "Four", "Five"); 
     ComboBox<String> combo = new ComboBox<>(); 
     combo.setValue(allItems.get(0)); 
     FilteredList<String> items = allItems.filtered(item -> item != combo.getValue()); 
     combo.setItems(items); 

     combo.valueProperty().addListener((obs, oldValue, newValue) -> Platform.runLater(() -> items.setPredicate(item -> item != newValue))); 


     BorderPane root = new BorderPane(); 
     root.setTop(combo); 
     primaryStage.setScene(new Scene(root, 400, 400)); 
     primaryStage.show(); 
    } 

    public static void main(String[] args) { 
     launch(args); 
    } 
} 

也许一个更简洁的方法就是到禁用显示当前选中的项目,这是接近的细胞,但不完全一样,UX:

import javafx.application.Application; 
import javafx.collections.FXCollections; 
import javafx.collections.ObservableList; 
import javafx.scene.Scene; 
import javafx.scene.control.ComboBox; 
import javafx.scene.control.ListCell; 
import javafx.scene.layout.BorderPane; 
import javafx.stage.Stage; 

public class ComboBoxNoSelectedItem extends Application { 

    @Override 
    public void start(Stage primaryStage) { 
     ObservableList<String> allItems = FXCollections.observableArrayList("One", "Two", "Three", "Four", "Five"); 
     ComboBox<String> combo = new ComboBox<>(allItems); 

     combo.setCellFactory(lv -> new ListCell<String>() { 

      { 
       disableProperty().bind(combo.valueProperty().isEqualTo(itemProperty())); 
      } 

      @Override 
      protected void updateItem(String item, boolean empty) { 
       super.updateItem(item, empty); 
       setText(item); 
      } 
     }); 

     BorderPane root = new BorderPane(); 
     root.setTop(combo); 
     primaryStage.setScene(new Scene(root, 400, 400)); 
     primaryStage.show(); 
    } 

    public static void main(String[] args) { 
     launch(args); 
    } 
} 
+0

确定这个工作正常,但由于某些原因,前两三次更改甚至会删除其他元素..过了一段时间,它完美的工作,但我最终失去了两个或三个项目列表 –

+0

FilteredList items = classi.filtered(item - > item!= class1.getValue()); class1.setItems(items); () - > items.setPredicate(item - > item!= newValue)));}}。 –