2016-04-14 16 views
1

Ich habe eine Swing-Anwendung, die basierend auf einer vom Benutzer eingegebenen Liste von Namen eine Reihe von Panels erstellt, mit einem Panel für jeden Namen, den der Benutzer eingibt. Am unteren Rand der Anwendung habe ich eine JPanel, mit einer Schaltfläche zum Schließen der aktuellen Panel und eine JLabel, die die aktuelle Anzahl der geöffneten Panels anzeigt.Aktualisieren von JLabel von JButton actionListener

ich initialisieren das Etikett wie so

String[] usernames = input("Usernames"); 
int totalTabs = usernames.length; 

JLabel lblRemaining = new JLabel("Remaining: " + totalTabs); 

Ich habe dann eine Aktion Hörer auf die Schließen-Schaltfläche hinzugefügt und hat versucht, einen Swingworker zu verwenden, um das Etikett zu aktualisieren, aber es scheint einfach nicht zu aktualisieren.

close.addActionListener(new ActionListener() { 
    public void actionPerformed(ActionEvent e) { 

     unlookup(username);  
     SwingWorker<String, String> updateLabel = new SwingWorker<String, String>(){ 

       @Override 
       protected String doInBackground() throws Exception { 
         String tabTotal = Integer.toString(desktop.getTabCount()); 
         return tabTotal; 
       } 

       @Override 
       protected void done(){ 
        try { 
          lblRemaining.setText(get()); 
          System.out.println(get()); 
        } catch (Exception ignore) { 
        } 
       } 

     }; 

     updateLabel.execute(); 
    } 

}); 

Die println wird in der Konsole die richtige Figur zeigt, damit ich es wissen muss etwas mit der GUI nicht aktualisiert zu tun, aber ich kann scheinen, um es einfach nicht, um herauszufinden!

Ich bin relativ neu zu Java und Swing, also hoffentlich ist es ziemlich offensichtlich, dass ich falsch mache!

Thanks :)

+0

Was ist der Sinn eines SwingWorker? Es ist illegal, auf irgendeine Swing-Klasse zuzugreifen, einschließlich "desktop", die ein JTabbedPane ist, in einem anderen Thread als dem Event Dispatch Thread, sodass die Verwendung in doInBackground zu undefinierten Ergebnissen führt. Ihr ActionListener wird bereits auf dem EDT ausgeführt. "lblRemaining.setText (Integer.toString (desktop.getTabCount()));" Alles was Sie in Action benötigen sollten (Abgesehen von "unlookup (username)", was kryptisch ist und wahrscheinlich nichts mit der Frage zu tun hat.) – laszlok

+0

@laszlok, die Methode doInBackground() greift nicht auf die GUI zu. Es gibt einen String-Wert zurück, auf den dann in der done() -Methode zugegriffen wird, die auf dem EDT ausgeführt wird. Der SwingWorker-Code sieht also korrekt aus. Einverstanden, der SwingWorder ist möglicherweise nicht notwendig, da es nicht so aussah, als würde es eine lange laufende Aufgabe ausführen, die die GUI einfrieren würde, so dass der gesamte Code im ActionListener selbst sein könnte. – camickr

+0

@camickr, lesen Sie bitte https://docs.oracle.com/javase/tutorial/uiswing/concurrency/dispatch.html - Die desktop.getTabCount() -Methode ist eine Swing-Komponentenmethode, die nicht als threadsicher markiert ist und sie daher aufruft In einem anderen Thread als dem EDT, wie im Tutorial erklärt, besteht die Gefahr von Thread-Interferenz- oder Speicherkonsistenzfehlern. Dass es sich nicht um Malen handelt (wenn Sie das mit "nicht auf die GUI zugreifen" meinen) ist unerheblich. – laszlok

Antwort

1

Die println in der Konsole

Dann bedeutet dies, Sie haben einen falschen Verweis auf die JLabel die richtige Figur zeigt.

Also haben Sie wahrscheinlich 1) eine Instanzvariable mit diesem Namen erstellt und dann 2) eine lokale Variable mit dem gleichen Namen erstellt und diese Bezeichnung dem Rahmen hinzugefügt. Der Swing-Mitarbeiter hat nur Zugriff auf die Instanzvariable.

Die lokale Variable loswerden.

Wenn Sie mehr Hilfe benötigen, dann posten Sie eine ordnungsgemäße SSCCE, die das Problem demonstriert. A SSCCE sollte mit ALLEN Fragen enthalten sein. Wir können nicht sagen, was das Problem wirklich auf ein paar Zeilen Code basiert.

+0

Leider ist dies Teil einer viel größeren Anwendung, die von jemand anderem erstellt wurde (von denen ich viele nicht teilen kann), aber ich habe meinen Beitrag aktualisiert, um so viel Code wie möglich zu zeigen. –

+0

Nicht interessiert an "so viel Code wie möglich". Wir brauchen eine 'SSCCE'. So erstellen Sie eine einfache App, die zeigt, was Sie tun. Erstellen Sie einen Rahmen mit der Beschriftung und einer Schaltfläche. Wenn Sie auf den Button klicken, starten Sie den SwingWorker. Also wird der ganze "SSCCE" ungefähr 20-30 Zeilen Code sein. Lassen Sie das einfache Stück Code arbeiten und vergleichen Sie den Arbeitscode mit Ihrer realen Anwendung. Wir haben keinen Zugriff auf Ihre echte Anwendung, sodass wir nicht erraten können, was Sie möglicherweise falsch machen. Es gibt keine Magie zum Aktualisieren eines Etiketts. Wenn Sie die richtige Referenz haben und der Code ausgeführt wird, aktualisiert sich das Etikett. – camickr