Problem mit einer JComboBox, Event temporär deaktivieren

Diskutiere Problem mit einer JComboBox, Event temporär deaktivieren im Allgemeine Java-Themen Forum; Hallo zusammen, ich habe da ein kleines Problem und zwar habe ich folgende Konstellation: 1. eine JComboBox wird "von aussen" befüllt, diese hat...

  1. FrittenFritze
    FrittenFritze Neues Mitglied
    Hallo zusammen,

    ich habe da ein kleines Problem und zwar habe ich folgende Konstellation:

    1. eine JComboBox wird "von aussen" befüllt, diese hat einen ActionListener registriert.
    2. dieser ActionListener feuert, wenn ein Eintrag ausgewählt wird und befüllt die zweite JComboBox
    3. die wiederrum auch einen ActionListener registriert hat
    4. der dann feuert wenn in der zweiten JComboBox ein Eintrag ausgewählt wird.

    Das ganze funktioniert auch einwandfrei, beim ersten Mal. Wenn man die erste JComboBox dann verändert, fliegt das Ganze mit einer NPE raus. Es ist so, dass die erste JComboBox die Einträge aus der zweiten rauswirft und beim ChangeEvent der ActionListener der zweiten JComboBox feurt.

    Gibt es eine Möglichkeit zu sagen "jetzt deaktiviere ich kurzzeitig die Events" und sie dann wieder einschalten?

    Hier der Code:

    Code (Text):

        JComboBox<Object> cbxLang = new JComboBox<Object>();
         Iterator<String> iterator = languageList.iterator();
         
         JComboBox<Object> cbxModel = new JComboBox<Object>();
         
         while (iterator.hasNext()) {
           String next = iterator.next();
           cbxLang.addItem(makeObj(next));
         }
         
         cbxLang.addActionListener(new ActionListener() {
           
           @Override
           public void actionPerformed(ActionEvent e) {
             _wds_dvd.setDVDLanguage(((JComboBox<Object>)e.getSource()).getSelectedItem().toString());
             _logger.info("Selected language: " +((JComboBox<Object>)e.getSource()).getSelectedItem().toString());
             
             List<String> modelList = _wds_dvd.getModelList();
             Iterator<String> iterator = modelList.iterator();
             
             cbxModel.removeAllItems();
             
             
             while (iterator.hasNext()) {
               String next = iterator.next();
               cbxModel.addItem(makeObj(next));
             }
             
             cbxModel.addActionListener(new ActionListener() {
               
               @Override
               public void actionPerformed(ActionEvent e) {
                 _logger.info("Selected modelline: " + ((JComboBox<Object>)e.getSource()).getSelectedItem().toString());
                 _wds_dvd.setModel(((JComboBox<Object>)e.getSource()).getSelectedItem().toString());
                 try {
                   String navigationXML = _wds_dvd.getNavigationXML();
                   _navTree.setIconLocation(_wds_dvd.getIconLocation());
                   _navTree.setCellRenderer(new WDSCellRenderer());
                   _navTree.buildNavigationTree(navigationXML);
                   open_wds ();
                 } catch (IOException e1) {
                   e1.printStackTrace();
                 }
               }
             });
           }
         });
     
    Danke Euch schon mal. :)
     
  2. Vielleicht hilft dir das kostenlose Training weiter --> (hier klicken)
  3. Thallius
    Thallius Bekanntes Mitglied
    Du könntest auch einfach mal ein paar sicherheitsabfragen in deinen actionlistener machen. Wenn du natürlich einfach auf getsource.getselecteditem zugreifst obwohl vielleicht gar keine items drin sind, dann kann das nicht klappen
     
  4. FrittenFritze
    FrittenFritze Neues Mitglied
    Naja, das beseitigt ja nicht das eigentliche Problem, dass der ActionListener feuert, obwohl es gar nicht notwendig ist. Das Sauberste wäre den ActionListener rauszuhängen...
     
  5. FrittenFritze
    FrittenFritze Neues Mitglied
    Lösung gefunden:

    Code (Text):

         JComboBox<Object> cbxLang = new JComboBox<Object>();
         Iterator<String> iterator = languageList.iterator();
         
         JComboBox<Object> cbxModel = new JComboBox<Object>();
         
         while (iterator.hasNext()) {
           String next = iterator.next();
           cbxLang.addItem(makeObj(next));
         }
         
         cbxLang.addActionListener(new ActionListener() {
           
           @Override
           public void actionPerformed(ActionEvent e) {
             _wds_dvd.setDVDLanguage(((JComboBox<Object>)e.getSource()).getSelectedItem().toString());
             _logger.info("Selected language: " +((JComboBox<Object>)e.getSource()).getSelectedItem().toString());
             
             List<String> modelList = _wds_dvd.getModelList();
             Iterator<String> iterator = modelList.iterator();
             
             final ActionListener[] actionListeners = cbxModel.getActionListeners();
             
             for (final ActionListener listener : actionListeners) {
               cbxModel.removeActionListener(listener);
             }
             
             try {
               cbxModel.removeAllItems();
               while (iterator.hasNext()) {
                 String next = iterator.next();
                 cbxModel.addItem(makeObj(next));
               }
             } finally {
               for (final ActionListener listener : actionListeners) {
                 cbxModel.addActionListener(listener);
               }
             }
             
             cbxModel.addActionListener(new ActionListener() {
               
               @Override
               public void actionPerformed(ActionEvent e) {
                 _logger.info("Selected modelline: " + ((JComboBox<Object>)e.getSource()).getSelectedItem().toString());
                 _wds_dvd.setModel(((JComboBox<Object>)e.getSource()).getSelectedItem().toString());
                 try {
                   String navigationXML = _wds_dvd.getNavigationXML();
                   _navTree.setIconLocation(_wds_dvd.getIconLocation());
                   _navTree.setCellRenderer(new WDSCellRenderer());
                   _navTree.buildNavigationTree(navigationXML);
                   open_wds ();
                 } catch (IOException e1) {
                   e1.printStackTrace();
                 }
               }
             });
           }
         });
     
    Mit getActionListeners holt man sich alle registrierten Listener raus, läuft die Liste durch und löscht sie (.remove(listener)), macht was auch immer man machen will und hängt sie wieder rein (.addActionListener(listener)).

    Fertig...
     
  6. Thallius
    Thallius Bekanntes Mitglied
    Oh Mann....

    Klar viel besser so....
     
  7. FrittenFritze
    FrittenFritze Neues Mitglied
    Ist irgendwas "falsch" oder warum so viele ....?
     
  8. Joose
    Joose Super-Moderator Mitarbeiter
    Falsch ist es nicht, aber unnötig die Listener zu entfernen um sie dann wieder hinzuzufügen.
    Eine einfache Abfrage in der actionPerformed wie Thallius schon gesagt hat würde reichen.
     
  9. FrittenFritze
    FrittenFritze Neues Mitglied
    Mehrere Lösungen führen zum Ziel.

    Ich vermeide lieber, dass der Listener feuert statt per Abfrage rauszuhüpfen.
     
  10. Thallius
    Thallius Bekanntes Mitglied
    Was meinst du wohl was mehr Performance kostet? Eine If-Abfrage oder das Hinzufügen und Entfernen der Listener?

    Das ist einfach typisch für die heutige Zeit. Speicher und CPU Power haben wir ja genug und wenn nicht soll sich der User gefälligst einen besseren Rechner kaufen.

    In diesem Fall ist es sogar weniger Code die Performance zu steigern als Deine merkwürdige Lösung. Aber hey es funktioniert ja warum sollte ich also weiter drüber nachdenken....
     
  11. FrittenFritze
    FrittenFritze Neues Mitglied
    Hast Du schlecht gegessen??? Typisch für heutige Zeit, so ein Schwachsinn.

    Diese Abfrage läuft genau ein mal beim Start... jetzt bleib mal auf dem Teppich. Und der einzige User bin ich selbst....
     
    Zuletzt bearbeitet: 6. Dez. 2016
  12. X5-599
    X5-599 Aktives Mitglied
    Ich würde das nicht gerade als "merkwürdige" Lösung bezeichnen. Bei uns handhaben wir das genau so. Warum? Weil mit organischem wachsen der Software handelt man sich so immer mehr und mehr solcher if/elses ein. Diese haben dann mit der eigentlichen Aufgabe der Listener nichts mehr zu tun und dienen nur noch der Steuerung: "Darf ich nun oder darf ich nicht". Der Code wird dadurch mitunter schwerer lesbar. Darum wurde bei uns diese Guideline des Entfernens/wieder hinzufügens eingeführt.

    Meiner Meinung nach kann man heutzutage gut und gerne auf Performance Optimierung verzichten, wenn dadurch besser wartbarer/lesbarer Code entsteht. Das kann natürlich jeder so machen wie er will. Letztenendes ist es wohl eine Design Entscheidung.
     
  13. FrittenFritze
    FrittenFritze Neues Mitglied
    Genau diese Guideline gab es bei uns auch. Gab weil ich nicht mehr bei dem Arbeitgeber bin. Ich bin nicht dafür etwas unnötig feuern zu lassen um dann abzufragen "brauche ich oder nicht". Das ist ein schlechtes Design, so meine Meinung, auch wenn "Herr Softwareentwickler" es anders sehen mag. Vor allem, wenn Tausende von diesen Event fliegen... was da wohl mehr Performance kostet????

    Egal, Problem gelöst, Diskussion zu Ende.
     
  14. Schau dir jetzt hier den Kurs an und lerne Java zu programmieren: --> Hier klicken, um mehr zu erfahren (Klick)
Die Seite wird geladen...

Problem mit einer JComboBox, Event temporär deaktivieren - Ähnliche Themen

Probleme bei einer Installation die Apache ant+ivy verwendet
Probleme bei einer Installation die Apache ant+ivy verwendet im Forum Allgemeine Java-Themen
Problem mit einer bool-Variable in einem Bot-Programm
Problem mit einer bool-Variable in einem Bot-Programm im Forum Java Basics - Anfänger-Themen
Probleme beim Verbinden mit einer HTTPS Seite
Probleme beim Verbinden mit einer HTTPS Seite im Forum Mobile Geräte
A-Stern Algorithmus Problem und Implementierung einer Map
A-Stern Algorithmus Problem und Implementierung einer Map im Forum Spiele- und Multimedia-Programmierung
MySQL - Probleme mit einer Aufgabe !
MySQL - Probleme mit einer Aufgabe ! im Forum Hausaufgaben
Thema: Problem mit einer JComboBox, Event temporär deaktivieren