Swing Threads sollen Tabtitel zur Laufzeit ändern

Netzgeist

Mitglied
Moin,
ein kleines Problem hält mich auf. Vieleicht könnt ihr mir helfen 🙂

Gegeben ist ein JFrame(den gencode lass ich mal weg):
1.PNG


Darin folgende Methoden:
Java:
public synchronized void incrementVal() {
        val++;
        updateTab();
    }
Java:
private void updateTab() {
        jTabbedPane1.setTitleAt(0, "<html><b>Val:" + val + "</b></html>");
    }
Java:
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
        for (int i = 0; i < 5; i++) {
            new Bot(this).start();
        }
    }

Weiterhin gegeben ist die Klasse Bot:
Java:
public class Bot extends Thread {

    private Tabtitle t;

    public Bot (Tabtitle t) {
        this.t = t;
    }

    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            t.incrementVal();
        }
    }
}

Wie man sieht versuche ich über den jButton 5 Instanzen von Bot zu starten. Jede dieser Instanzen soll "val" je 10mal erhöhen. Das JFrame soll jeweils den aktuellen Wert von val als Tabtitel darstellen. Zur Laufzeit passiert bei drücken des jButton folgendes:
Code:
Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 1 >= 1
        at java.util.Vector.elementAt(Vector.java:427)
        at javax.swing.plaf.basic.BasicTabbedPaneUI.getTextViewForTab(BasicTabbedPaneUI.java:1688)
        at javax.swing.plaf.basic.BasicTabbedPaneUI.calculateTabWidth(BasicTabbedPaneUI.java:1740)
        at javax.swing.plaf.basic.BasicTabbedPaneUI.calculateMaxTabWidth(BasicTabbedPaneUI.java:1758)
        at javax.swing.plaf.basic.BasicTabbedPaneUI$TabbedPaneLayout.calculateSize(BasicTabbedPaneUI.java:2314)
        at javax.swing.plaf.basic.BasicTabbedPaneUI$TabbedPaneLayout.minimumLayoutSize(BasicTabbedPaneUI.java:2265)
        at java.awt.Container.minimumSize(Container.java:1651)
        at java.awt.Container.getMinimumSize(Container.java:1636)
        at javax.swing.JComponent.getMinimumSize(JComponent.java:1716)
        at javax.swing.GroupLayout$ComponentSpring.calculateNonlinkedMinimumSize(GroupLayout.java:2933)
        at javax.swing.GroupLayout$ComponentSpring.calculateMinimumSize(GroupLayout.java:2897)
        at javax.swing.GroupLayout$Spring.getMinimumSize(GroupLayout.java:1315)
        at javax.swing.GroupLayout$ComponentSpring.calculatePreferredSize(GroupLayout.java:2904)
        at javax.swing.GroupLayout$Spring.getPreferredSize(GroupLayout.java:1325)
        at javax.swing.GroupLayout$Group.getSpringSize(GroupLayout.java:1604)
        at javax.swing.GroupLayout$Group.calculateSize(GroupLayout.java:1590)
        at javax.swing.GroupLayout$Group.calculatePreferredSize(GroupLayout.java:1568)
        at javax.swing.GroupLayout$Spring.getPreferredSize(GroupLayout.java:1325)
        at javax.swing.GroupLayout$Group.getSpringSize(GroupLayout.java:1604)
        at javax.swing.GroupLayout$Group.calculateSize(GroupLayout.java:1590)
        at javax.swing.GroupLayout$Group.calculatePreferredSize(GroupLayout.java:1568)
        at javax.swing.GroupLayout$Spring.getPreferredSize(GroupLayout.java:1325)
        at javax.swing.GroupLayout$Group.getSpringSize(GroupLayout.java:1604)

Mir ist bewusst, das die wechselnde Darstellung des Tabtitels mitunter schneller sein kann als die Wahrnehmung des Benutzers. Der code soll so auch nicht verwendet werden, das hier ist ein simplifiziertes Beispiel für mein Problem.
 
Aus der Ausnahme deute ich, dass es die setTitleAt()-Methode verreisst. Wann wird der Thread denn ausgeführt? Sofort bei Programmstart oder erst wenn man klickt und man schon alles sieht? Wichtig ist
natürlich, dass die JTabbedPane auch Tabs hat, sonst wird er nichts finden.

Du könntest mal ein vollständiges Beispiel posten oder für's Debugging ein paar Sleeps in den Thread einbauen.
 
Alles, was den sichtbaren Zustand einer Swing-Component verändert, oder darauf basiert, muss vom Event-Dispatch-Thread gemacht werden.
Java:
SwingUtilities.invokeLater(new Runnable()
{
    public void run()
    {
        tabTextÄndern();
    }
});
 
KrokoDiehl: Der Auslöser ist der jButton.
Marco13: Danke, nach anpassen der Methode in

Java:
private void updateTab() {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                jTabbedPane1.setTitleAt(0, "<html><b>Val:" + val + "</b></html>");
            }
        });   
    }

funktioniert der Methodenaufruf. Ich werd mich nun in SwingUtilities einlesen 🙂
 

Neue Themen


Zurück
Oben