Event Dispatch Thread und noch ein Thread

TX

Mitglied
Hallo,
ich habe mal ein Beispiel zusammengestellt und wollte nochmal nachfragen wie man das jetzt genau macht mit den EDT.

Ist das so Ok, wie dass in der nicht auskommentierten Methode setTextinTextfield() programmiert wurde?
Sieht etwas seltsam aus.

Java:
package edtKram;

import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.concurrent.TimeUnit;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;


public class EdtTest extends JFrame{
	
	private static final long serialVersionUID = 1L;
	
	private JTextField textField;
	private JButton button;
	
	public EdtTest() {
		super("EDT Test");
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		
		textField = new JTextField(20);
		
		button = new JButton("Thread");
		button.addActionListener(new ButtonListener());
		
		getContentPane().setLayout(new FlowLayout());
		getContentPane().add(textField);
		getContentPane().add(button);
		
		pack();
	}
	
	
	//private void setTextinTextField(String string){
	//	textField.setText(string);
	//}
	
	private void setTextinTextField(final String string){
		try {
            SwingUtilities.invokeAndWait(new Runnable() {
                public void run() {
                    textField.setText(string);
                }
            });
        } catch (Exception e) { 
           e.printStackTrace();
        }
	}
	
	
	
	private class ButtonListener implements ActionListener{
		@Override
		public void actionPerformed(ActionEvent e) {
			Thread thread = new Thread(){
				public void run() {
					button.setEnabled(false);
					
					for(int i = 1; i <= 3; i++){
						setTextinTextField(String.format("Thread %d", i));
						
						try {
							TimeUnit.SECONDS.sleep(2);
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
						
					}
					
					button.setEnabled(true);
				}
				
			};
			
			thread.start();
			
		}
	}
	
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		try {
            SwingUtilities.invokeAndWait(new Runnable() {
                public void run() {
                    new EdtTest().setVisible(true);
                }
            });
        } catch (Exception e) { 
           e.printStackTrace();
        }

	}

}
 
solang du die Methode setTextinTextField nur vom EDT aus aufrufst sollte das so ok sein.
Und da du die Methode in deinem beispiel nur in dem actionlistener aufrufst sollte der auskommentierte code reichen.
 
In deinem Beispiel kannst du eig. nichts verkehrt machen, da du nur setText aufrufst und setText ist thread safe, also wäre hier genau genommen (auch wenn du es aus deinem neu gestarteten Thread aufrufst) kein invokeLater oder ähnliches nötig.
 
Hm. Das mit dem Hinweis auf die Threadsicherheit von setText hab' ich jetzt nicht gefunden ???:L

Zumindest kann es nicht schaden, das auf dem EDT zu machen. Dann (und spätestens, wenn man davon ausgeht, dass das "setTextinTextField" eher als Beispiel für "irgendwelche Veränderungen" am GUI steht) war das ursprüngliche Muster schon richtig. Viel wichtiger ist in diesem Sinne aber, dass auch
button.setEnabled(false);
und
button.setEnabled(true);
auf dem EDT gemacht werden müßten. BTW: Die Klasse SwingWorker bietet einige Mechanismen, die das Einhalten der Thread-Regeln nicht ganz so krampfig aussehen lassen 😉
 
😱 Joa leckst mi am... ???:L Ich WUSSTE, das das dabei steht, aber als ich eben...

*unterbrech und nochmal nachseh*

JA, ich WUSSTE, dass das dabei steht, aber warum zum... steht es bei der 7er Doku nicht mehr dabei?! ???:L (da hatte ich eben geschaut, und es nicht mehr gefunden! :rtfm: )
 
Ok, threadsafe, das ist schon mal gut.

Stimmt, dann müsste man das auch bei den Buttons machen.

Ich meine, wenn man es ohne invokeandwait macht, dann kann es passieren, dass der Text verzögert aktualisiert wird und in diesen Beispiel weniger als 2 Sekunden gewartet wird bis der nächste Text kommt, aber das muss ich nochmal testen und das war auch eher bei TextArea.
 

Zurück
Oben