tutorials.de Buch-Aktion 05/2012
ERLEDIGT
NEIN
ANTWORTEN
8
ZUGRIFFE
826
EMPFEHLEN
  • An Twitter übertragen
  • An Facebook übertragen
AUF DIESES THEMA
ANTWORTEN
  1. #1
    Javazubi Javazubi ist offline Rookie
    Registriert seit
    Oct 2006
    Beiträge
    5
    Hi,

    ich habe viele ähnliche Postings gelesen, aber irgendwie komme ich nicht zur Lösung meines Problems. Ich habe ein JLabel, dem ich zur Laufzeit einen neuen Text zuweisen möchte. Mein Hauptthread (Frame) wird wie folgt gestartet:

    Code :
    1
    2
    3
    4
    5
    6
    7
    
    public static void main(String args[]) {
            java.awt.EventQueue.invokeLater(new Runnable() {
                public void run() {
                    new ATC_Frame().setVisible(true);
                }
            });
        }

    Auf der Form befindet sich eine JTable, deren Click-Event abgefangen wird und folgenden Code aufruft:

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    
    1  private void tueWas() {
        
    2   String[] conn_status = new String[2];
    3   conn_status[0] = "Verbindung wird aufgebaut";
     
    5   System.err.println(conn_status[0]);
    6   //setText des Labels soll ausgeführt werden
    7   SwingUtilities.invokeLater( new AddEvent(lblMeldung, conn_status[0]) );
     
    8   thread1 = new thread1_klasse(x, x, x, x, x);
    9   thread1.start();
     
    10  //Ich übergebe das String-Array, damit ich ein Call-By-Reference habe
    11  //und der Zweite Thread das hier lokale conn_status[0] änder kann
    12  thread1.starteThread2(x, x, x, conn_status);
     
    13  //Hier wird die Änderung von conn_status[0] durch Thread2 abgewartet
    14  while (conn_status[0].equals("Verbindung wird aufgebaut")) {
    15     try
    16     {
    17           Thread.sleep(1000);
    18           System.out.println("Warte");
    19     }
    20     catch(Exception e)
    21     {
    22           e.ToString();
    23     }
    24  }
     
    25  //Nach der Änderung von conn_status[0] durch Thread2 soll der neue Text
    26  //Verbindung "steht" oder "steht nicht" angezeigt werden
    27  System.err.println(conn_status[0]);
    28  SwingUtilities.invokeLater( new AddEvent(lblMeldung, conn_status[0]) );
     
    29  }
     
     
    30  class AddEvent implements Runnable {
     
    31  private JLabel lbl;
    32  private String text;
        
    33  public AddEvent(JLabel lbl, String text) {
    34      this.lbl = lbl;
    35      text = text;
    36  } 
        
    37  public void run() {
    38             System.out.println("IN ADDEVENT");
            lbl.setText( text );
    39  } 
     
    40  }

    Nun erfolgt aber weder in Zeile 7 noch in Zeile 28 die gewünschte Änderung des Labels. Nachdem der 2. Thread den Text geändert hat, sehe ich den Erfolg über das System.err.println in Zeile 27 und erst ganz zum Schluß die beiden Ausgaben von "IN ADDEVENT" in Zeile 38.

    Kann mir jemand helfen?

    Gruß
     

  2. #2
    elmato elmato ist offline Mitglied Brokat
    Registriert seit
    May 2005
    Ort
    NRW
    Beiträge
    408
    Warum implementiert deine Klasse AddEvent denn das Interface Runnable? Erscheint mir irgendwie überflüssig, warum, setzt du den Text des Labels nicht einfach so?
     
    Been there, done that, got the T-Shirt..

  3. #3
    Javazubi Javazubi ist offline Rookie
    Registriert seit
    Oct 2006
    Beiträge
    5
    Hi,

    weil es so einfach nicht funktioniert. Ein label.setText("irgendwas") klappt aus dem Main-Thread nicht. Das habe ich beim Lesen der Foren schon herausgefunden. Darum ja auch das invokeLater.

    Die Klasse addEvent ist eine von 4 bis 5 Varianten, die ich bisher gefunden habe, um die GUI zur Laufzeit zu aktualisieren. Alle Varianten haben in meinem Code den selben Effekt. Die Ausgabe von Zeile 38 wird als allerletztes angezeigt und daher nicht parallel zum Main-Thread abgearbeitet. Selbst wenn der Verbindungsaufbau in Zeile 12 in einen Timeout läuft (hier wäre ja in jedem Fall genügend Zeit das Label zu aktualisieren), wird addEvent->run() danach durchlaufen UND WIE SCHÖN - selbst dann ändert sich der Text des Labels nicht!
     

  4. #4
    elmato elmato ist offline Mitglied Brokat
    Registriert seit
    May 2005
    Ort
    NRW
    Beiträge
    408
    Sorry vielleicht verstehe ich dein Problem nicht so ganz aber folgender Code funktioniert einwandfrei bei mir..
    Code java:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    
    package test;
     
    import javax.swing.SwingUtilities;
    import java.awt.BorderLayout;
    import javax.swing.JPanel;
    import javax.swing.JFrame;
    import javax.swing.JScrollPane;
    import javax.swing.JTable;
    import javax.swing.JLabel;
     
    public class labelTest extends JFrame {
     
        private static final long serialVersionUID = 1L;
     
        private JPanel jContentPane = null;
     
        private JScrollPane jScrollPane = null;
     
        private JTable jTable = null;
     
        private JLabel jLabel = null;
     
        /**
         * This method initializes jScrollPane  
         *  
         * @return javax.swing.JScrollPane  
         */
        private JScrollPane getJScrollPane() {
            if (jScrollPane == null) {
                jScrollPane = new JScrollPane();
                jScrollPane.setViewportView(getJTable());
            }
            return jScrollPane;
        }
     
        /**
         * This method initializes jTable   
         *  
         * @return javax.swing.JTable   
         */
        private JTable getJTable() {
            if (jTable == null) {
                jTable = new JTable(5,5);
                jTable.addMouseListener(new java.awt.event.MouseAdapter() {
                    public void mouseClicked(java.awt.event.MouseEvent e) {
                        try {
                            Thread.sleep(5000);
                        } catch (InterruptedException ie) {
                            System.out.println(ie.getMessage());
                        }
                        jLabel.setText("verbunden");
                    }
                });
            }
            return jTable;
        }
     
        /**
         * @param args
         */
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    labelTest thisClass = new labelTest();
                    thisClass.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    thisClass.setVisible(true);
                }
            });
        }
     
        /**
         * This is the default constructor
         */
        public labelTest() {
            super();
            initialize();
        }
     
        /**
         * This method initializes this
         * 
         * @return void
         */
        private void initialize() {
            this.setSize(300, 200);
            this.setContentPane(getJContentPane());
            this.setTitle("JFrame");
        }
     
        /**
         * This method initializes jContentPane
         * 
         * @return javax.swing.JPanel
         */
        private JPanel getJContentPane() {
            if (jContentPane == null) {
                jLabel = new JLabel();
                jLabel.setText("nicht verbunden");
                jContentPane = new JPanel();
                jContentPane.setLayout(new BorderLayout());
                jContentPane.add(getJScrollPane(), BorderLayout.CENTER);
                jContentPane.add(jLabel, BorderLayout.NORTH);
            }
            return jContentPane;
        }
     
    }
     
    Been there, done that, got the T-Shirt..

  5. #5
    Javazubi Javazubi ist offline Rookie
    Registriert seit
    Oct 2006
    Beiträge
    5
    Hi,

    das Problem mit der NICHT nebenläufigen Ausführung von AddEvent hat sich erledigt. Ich habe im Konstruktor "new Thread( this ).start();" hinzugefügt. Ebenfalls habe ich den Parameter "text" des Konstruktors an this.text übergeben Die Klasse sind nun so aus.

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    
    class AddEvent implements Runnable {
        private JLabel lbl;
        private String text;
        
        public AddEvent(JLabel lbl, String text) {
                    System.out.println("IN Konstruktor conn_status[0] = " + text);
            this.lbl = lbl;
            this.text = text;
                    new Thread( this ).start();
        } 
        
        public void run() {
                    System.out.println("IN ADDEVENT " + this.text);
                    lbl.setText( this.text );
        } 
    }

    Aber ein Problem bleibt! Das NACHTRÄGLICHE ändern des Textes mit lbl.setText(this.text) funktioniert nicht bzw. die Änderung wird nicht angezeigt.

    Du hast schon recht, wenn man das Label mit
    jLabel = new JLabel();
    erstellt und direkt danach ein
    jLabel.setText("nicht verbunden");
    aufruft wird der Text gesetzt. Aber setze bitte mal einen Button auf deine Form und füge einen ActionListener hinzu, der den ButtonClick abfängt und probiere ein erneutes jLabel.setText("...") in diesem Listener. Es wird dir nicht gelingen!

    Hiiiilfeeeeeeeee!
     

  6. #6
    elmato elmato ist offline Mitglied Brokat
    Registriert seit
    May 2005
    Ort
    NRW
    Beiträge
    408
    Also ich glaube langsam das wir irgendwie ziemlich an einander vorbei Reden :/
    meinst du sowas
    Code java:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    
    package test;
     
    import javax.swing.SwingUtilities;
    import java.awt.BorderLayout;
    import javax.swing.JPanel;
    import javax.swing.JFrame;
    import javax.swing.JScrollPane;
    import javax.swing.JTable;
    import javax.swing.JLabel;
    import javax.swing.JButton;
     
    public class labelTest extends JFrame {
     
        private static final long serialVersionUID = 1L;
     
        private JPanel jContentPane = null;
     
        private JScrollPane jScrollPane = null;
     
        private JTable jTable = null;
     
        private JLabel jLabel = null;
     
        private JButton jButton = null;
     
        /**
         * This method initializes jScrollPane  
         *  
         * @return javax.swing.JScrollPane  
         */
        private JScrollPane getJScrollPane() {
            if (jScrollPane == null) {
                jScrollPane = new JScrollPane();
                jScrollPane.setViewportView(getJTable());
            }
            return jScrollPane;
        }
     
        /**
         * This method initializes jTable   
         *  
         * @return javax.swing.JTable   
         */
        private JTable getJTable() {
            if (jTable == null) {
                jTable = new JTable(5,5);
                jTable.addMouseListener(new java.awt.event.MouseAdapter() {
                    public void mouseClicked(java.awt.event.MouseEvent e) {
                        try {
                            Thread.sleep(5000);
                        } catch (InterruptedException ie) {
                            System.out.println(ie.getMessage());
                        }
                        jLabel.setText("verbunden");
                    }
                });
            }
            return jTable;
        }
     
        /**
         * This method initializes jButton  
         *  
         * @return javax.swing.JButton  
         */
        private JButton getJButton() {
            if (jButton == null) {
                jButton = new JButton();
                jButton.setText("Knopf");
                jButton.addActionListener(new java.awt.event.ActionListener() {
                    public void actionPerformed(java.awt.event.ActionEvent e) {
                        jLabel.setText("geht doch");
                    }
                });
            }
            return jButton;
        }
     
        /**
         * @param args
         */
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    labelTest thisClass = new labelTest();
                    thisClass.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    thisClass.setVisible(true);
                }
            });
        }
     
        /**
         * This is the default constructor
         */
        public labelTest() {
            super();
            initialize();
        }
     
        /**
         * This method initializes this
         * 
         * @return void
         */
        private void initialize() {
            this.setSize(300, 200);
            this.setContentPane(getJContentPane());
            this.setTitle("JFrame");
        }
     
        /**
         * This method initializes jContentPane
         * 
         * @return javax.swing.JPanel
         */
        private JPanel getJContentPane() {
            if (jContentPane == null) {
                jLabel = new JLabel();
                jLabel.setText("nicht verbunden");
                jContentPane = new JPanel();
                jContentPane.setLayout(new BorderLayout());
                jContentPane.add(getJScrollPane(), BorderLayout.CENTER);
                jContentPane.add(jLabel, BorderLayout.NORTH);
                jContentPane.add(getJButton(), BorderLayout.SOUTH);
            }
            return jContentPane;
        }
     
    }
    funktioniert bei mir super...
     
    Been there, done that, got the T-Shirt..

  7. #7
    Javazubi Javazubi ist offline Rookie
    Registriert seit
    Oct 2006
    Beiträge
    5
    Sorry, dass ich bei deinem vorletzten posting deinen Listener jTable.mouseClicked() übersehen habe. Genau sowas meinte ich. Und das funktioniert bei dir Bei mir leider nicht... grmbl
     

  8. #8
    elmato elmato ist offline Mitglied Brokat
    Registriert seit
    May 2005
    Ort
    NRW
    Beiträge
    408
    Poste doch mal den Rest deines Codes..
     
    Been there, done that, got the T-Shirt..

  9. #9
    Javazubi Javazubi ist offline Rookie
    Registriert seit
    Oct 2006
    Beiträge
    5
    Die Klasse hat mittlerweile mehr als 1000 Zeilen Code. Ich muss mich daher auf das Wesentliche beschränken.

    Code :
    1
    2
    3
    4
    5
    6
    7
    
    public static void main(String args[]) {
            java.awt.EventQueue.invokeLater(new Runnable() {
                public void run() {
                    new ATC_Frame().setVisible(true);
                }
            });
    }

    Der Konstruktor der Klasse ATC_Frame ruft die Funktion fuelle_tabelle() auf.
    Die Funktion fuelle_tabelle() fügt einem JPanel eine JTable hinzu.

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    
    private void fuelle_tabelle() {
        
        lblFehler = new JLabel();
        table = new JTable(daten, ueberschriften);
    .
    .
    .
     
        //Listener für Tabelle hinzufuegen
        table.addMouseListener(new java.awt.event.MouseAdapter() {
                    public void mouseClicked(java.awt.event.MouseEvent evt) {
                        handler_table_click(evt);
                    }
        });
     
    }

    Bei einem Click auf die Tabelle wird der Code in handler_table_click() definitiv ausgeführt.

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    private void handler_table_click(java.awt.event.MouseEvent evt) {
            
        lblFehler.setText("Test");
     
    .
    .
    .
     
    }

    Aber das Label ändert seinen Text nicht. Danke für deine Geduld...
     

Ähnliche Themen

  1. In SwingWorker.doInBackground Methode GUI verändern, mit oder ohne invokeLater?
    Von DarthShader im Forum Swing, Java2D/3D, SWT, JFace
    Antworten: 6
    Letzter Beitrag: 24.09.08, 19:47
  2. Problem mit invokeLater / invokeAndWait
    Von informatiker85 im Forum Swing, Java2D/3D, SWT, JFace
    Antworten: 2
    Letzter Beitrag: 27.01.08, 19:08
  3. Besserer Programmierstil mit invokeLater?
    Von javaprogger1987 im Forum Swing, Java2D/3D, SWT, JFace
    Antworten: 2
    Letzter Beitrag: 27.12.06, 11:38
  4. invokeLater - Wann?
    Von taouri im Forum Swing, Java2D/3D, SWT, JFace
    Antworten: 2
    Letzter Beitrag: 02.12.06, 18:20
  5. JDialog & invokeLater
    Von feigline im Forum Java
    Antworten: 3
    Letzter Beitrag: 18.05.06, 02:22