2017-01-26 5 views
0

Ich habe 4 ComboBox in jedem von ihnen gibt es 5 Elemente: "", "1", "2", "3", "4". Ich muss machen, wenn der Artikel "1" in einem ComboBox ausgewählt ist, wird es automatisch von anderen ausgeschlossen. Und wenn das Element "" in der ComboBox insame ausgewählt ist, wird es automatisch zum anderen zurückgegeben. Also das gleiche Bedürfnis für andere Gegenstände außer "".
Ich habe versucht, dies zu tun, ist hier der Code:Entfernen mehrerer identischer Elemente ComboBox


public void vubadditems(ComboBox<String> vub1,ComboBox<String> vub2,ComboBox<String> vub3,ComboBox<String> vub4){ 
    vub1.getItems().addAll(" ","1","2","3","4"); 
    vub2.getItems().addAll(" ","1","2","3","4"); 
    vub3.getItems().addAll(" ","1","2","3","4"); 
    vub4.getItems().addAll(" ","1","2","3","4"); 
} 
public void vubact(ComboBox<String> vub1,ComboBox<String> vub2,ComboBox<String> vub3,ComboBox<String> vub4){ 
    if(vub1.getSelectionModel().getSelectedItem()!=" "){  
    vub2.getItems().remove(vub1.getSelectionModel().getSelectedItem()); 
    vub3.getItems().remove(vub1.getSelectionModel().getSelectedItem()); 
    vub4.getItems().remove(vub1.getSelectionModel().getSelectedItem()); 
    s=vub1.getSelectionModel().getSelectedItem(); 
    }else{ 
    } 
    if(vub2.getSelectionModel().getSelectedItem()!=" "){  
     vub1.getItems().remove(vub2.getSelectionModel().getSelectedItem()); 
     vub3.getItems().remove(vub2.getSelectionModel().getSelectedItem()); 
     vub4.getItems().remove(vub2.getSelectionModel().getSelectedItem()); 
     } 
    if(vub3.getSelectionModel().getSelectedItem()!=" "){  
     vub1.getItems().remove(vub3.getSelectionModel().getSelectedItem()); 
     vub2.getItems().remove(vub3.getSelectionModel().getSelectedItem()); 
     vub4.getItems().remove(vub3.getSelectionModel().getSelectedItem()); 
     } 
    if(vub4.getSelectionModel().getSelectedItem()!=" "){  
     vub1.getItems().remove(vub4.getSelectionModel().getSelectedItem()); 
     vub2.getItems().remove(vub4.getSelectionModel().getSelectedItem()); 
     vub3.getItems().remove(vub4.getSelectionModel().getSelectedItem()); 
     } 
} 
public void vubq1ac(){ 
    vubact(q1vub1,q1vub2,q1vub3,q1vub4); 
} 
public void initialize(){ 
vubadditems(q1vub1,q1vub2,q1vub3,q1vub4); 
    vubadditems(q2vub1,q2vub2,q2vub3,q2vub4); 
    vubadditems(q3vub1,q3vub2,q3vub3,q3vub4); 
    vubadditems(q4vub1,q4vub2,q4vub3,q4vub4); 
    vubadditems(q5vub1,q5vub2,q5vub3,q5vub4); 
} 

q1vub1, q1vub2, q1vub3, q1vub4 von FXML_fileComboBox ‚s
ich auf ComboBox
vubq1ac als Aktion listiner hinzufügen geladen Aber ich habe einige Ausnahmen und Programm funktioniert nicht Ausnahme:

Exception in thread "JavaFX Application Thread" java.lang.IndexOutOfBoundsException 
at com.sun.javafx.scene.control.ReadOnlyUnbackedObservableList.subList(ReadOnlyUnbackedObservableList.java:136) 
at javafx.collections.ListChangeListener$Change.getAddedSubList(ListChangeListener.java:242) 
at com.sun.javafx.scene.control.behavior.ListViewBehavior.lambda$new$177(ListViewBehavior.java:269) 
at javafx.collections.WeakListChangeListener.onChanged(WeakListChangeListener.java:88) 
at com.sun.javafx.collections.ListListenerHelper$Generic.fireValueChangedEvent(ListListenerHelper.java:329) 
at com.sun.javafx.collections.ListListenerHelper.fireValueChangedEvent(ListListenerHelper.java:73) 
at com.sun.javafx.scene.control.ReadOnlyUnbackedObservableList.callObservers(ReadOnlyUnbackedObservableList.java:75) 
at javafx.scene.control.MultipleSelectionModelBase.clearAndSelect(MultipleSelectionModelBase.java:378) 
at javafx.scene.control.ListView$ListViewBitSetSelectionModel.clearAndSelect(ListView.java:1403) 
at com.sun.javafx.scene.control.behavior.CellBehaviorBase.simpleSelect(CellBehaviorBase.java:256) 
at com.sun.javafx.scene.control.behavior.CellBehaviorBase.doSelect(CellBehaviorBase.java:220) 
at com.sun.javafx.scene.control.behavior.CellBehaviorBase.mousePressed(CellBehaviorBase.java:150) 
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:95) 
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:89) 
at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218) 
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80) 
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238) 
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191) 
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59) 
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58) 
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) 
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) 
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) 
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) 
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) 
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) 
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) 
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74) 
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54) 
at javafx.event.Event.fireEvent(Event.java:198) 
at javafx.scene.Scene$MouseHandler.process(Scene.java:3757) 
at javafx.scene.Scene$MouseHandler.access$1500(Scene.java:3485) 
at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1762) 
at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2494) 
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:380) 
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:294) 
at java.security.AccessController.doPrivileged(Native Method) 
at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$354(GlassViewEventHandler.java:416) 
at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:389) 
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:415) 
at com.sun.glass.ui.View.handleMouseEvent(View.java:555) 
at com.sun.glass.ui.View.notifyMouse(View.java:937) 
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method) 
at com.sun.glass.ui.win.WinApplication.lambda$null$148(WinApplication.java:191) 
at java.lang.Thread.run(Unknown Source) 
+0

Vergleichen Sie zunächst 'String' nicht mit' == 'oder'! = ', Verwenden Sie stattdessen equals:' vub1.getSelectionModel(). GetSelectedItem(). Equals ("") ' – MBec

+0

@MBec OK i rewrite :? 'if (vub1.getSelectionModel(). getSelectedItem().equals ("")) {} else {'aber das Programm gibt immer noch die Ausnahme –

+0

Sie haben eine 'IndexOutOfBoundsException', also überprüfen Sie, dass Ihre Schleife nur über die maximale Größe Ihrer Listen iteriert! –

Antwort

0

Wenn Sie Ihrem aktuellen Ansatz folgen, wird Ihr Code ziemlich lang und ziemlich schwer zu debuggen sein. Momentan scheint es so zu sein:

  1. Sie entfernen nur und geben niemals Artikel zurück.
  2. Sie speichern den zuvor ausgewählten Wert nicht. Stellen Sie sich vor, dass in Ihrer ersten ComboBox "1" ausgewählt wurde (und anschließend von anderen Komponenten ausgeschlossen wurde), und Sie entscheiden, es wieder in "" zu ändern. Sie können den vorherigen Wert nicht direkt von ComboBox abrufen, da .getSelectedItem() nur den aktuellen Wert zurückgibt, der "" bereits wäre.

Ich werde Ihnen meinen Ansatz vorstellen und Ihnen kurz sagen, wie es funktioniert.

public class JavaFXApplication extends Application { 

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

    @Override 
    public void start(Stage primaryStage) { 
     FlowPane root = new FlowPane(); 

     ArrayList<String> items = new ArrayList<>(); 
     Collections.addAll(items, " ", "1", "2", "3", "4"); 

     List<ComboBox> comboBoxList = new ArrayList<>(); 
     for (int i = 0; i < 4; i++) { 
      ComboBox c = new ComboBox(FXCollections.observableArrayList(items)); 
      c.setValue(c.getItems().get(0)); 
      c.valueProperty().addListener(removeFromOtherCombo(comboBoxList, c)); 
      comboBoxList.add(c); 
     } 

     root.getChildren().addAll(comboBoxList); 
     Scene scene = new Scene(root, 200, 100); 

     primaryStage.setScene(scene); 
     primaryStage.show(); 
    } 

    public static ChangeListener removeFromOtherCombo(List<ComboBox> boxes, ComboBox current) { 
     return (o, oldVal, newVal) -> { 
      if (newVal.equals(oldVal)) { 
       return; 
      } 

      if (!oldVal.equals(" ")) { 
       boxes.stream() 
         .filter(c -> !c.equals(current)) 
         .forEach((ComboBox) -> { 
          ComboBox.getItems().add(oldVal); 
         }); 
      } 

      if (!newVal.equals(" ")) { 
       boxes.stream() 
         .filter(c -> !c.equals(current)) 
         .forEach((ComboBox) -> { 
          ComboBox.getItems().remove(newVal); 
         }); 
      } 
     }; 
    } 
} 

Für jede ComboBox erstelle ich ein ChangeListener, die von jedem anderen ComboBox bewusst ist und die ComboBox, dem er zugeordnet ist.

c.valueProperty().addListener(removeFromOtherCombo(comboBoxList, c)); 

Die ChangeListener wird jedes Mal, wenn Sie einen neuen Wert auswählen benachrichtigt, und zum Glück für uns erhält er den alten und neuen Wert.

Wenn der alte Wert dem neuen Wert entspricht, gibt es für uns nichts zu tun.

if (newVal.equals(oldVal)) { 
    return; 
} 

Wenn der alte Wert ist eine Zahl (zum Beispiel sind wir von „1“ auf „2“ zu ändern), dann müssen wir die zuvor gewählte Nummer, die jedem ComboBox mit einer Ausnahme zurückgeben, der filtriert.

if (!oldVal.equals(" ")) { 
    boxes.stream() 
      .filter(c -> !c.equals(current)) 
      .forEach((ComboBox) -> { 
       ComboBox.getItems().add(oldVal); 
      }); 
} 

Der gleiche Ansatz genommen wird, wenn wir auf eine Reihe sind zu ändern, aber dieses Mal haben wir von jedem ComboBox mit einer Ausnahme zu entfernen.

+0

Ich benutze eine Scene Builder und FXML Dateien und initialisiere 'ComboBox', also kannst du diesen Teil des Codes umschreiben: ' Liste comboBoxList = new ArrayList <>(); für (int i = 0; i <4; i ++) { ComboBox c = neue ComboBox (FXCollections.observableArrayList (items)); c.setValue (c.getItems(). Get (0)); c.valueProperty(). AddListener (removeFromOtherCombo (comboBoxList, c)); comboBoxList.add (c); ' –

+0

Dann ändern Sie diese Zeile' ComboBox c = neue ComboBox (FXCollections.observableArrayList (Elemente)); 'zu' ComboBox c = ComboBoxList.get (i); 'und fügen Sie Ihre' ComboBox' hinzu Die Liste vor der Schleife beginnt: 'comboBoxList.add (comboBox1);' usw. Sie können in diesem Fall die foreach-Schleife verwenden. – Dth

+0

OK vielen Dank Ich habe ihren eigenen Code umgeschrieben, aber ich war 'Ausnahme', weil mein Programm automatisch eines der Elemente von' ComboBox' auswählen sollte, aber das Kopieren des Codes diese 'exceptions' neu schreibt, erscheint ich nicht –

Verwandte Themen