Moin,
ich muss in Java taktartig Strings erzeugen und hänge irgendwie…
Zielsetzung ist, über die GUI auf "start" zu klicken und automatisch in einem definierten Takt über einen definierten Algorithmus eine String-Ausgabe in eine JTextArea zu erlangen.
Mein erster Gedanke, einen Boolean an den Start-Button zu knüpfen und dann mit einer while-Schleife zu arbeiten klappt irgendwie nicht. Ich komme in der Problem einer Endlosschleife…
Jemand eine Idee?
Jupp, Threads…
http://java.sun.com/javase/6/docs/api/javax/swing/SwingWorker.htmlDas zweite Beispiel unter "Sample Usage" wär was für dich.
Mit einem eigenen Thread arbeiten, der in einer Endlosschleife die GUI updated und danach schläft. Dabei beachten, dass Swing nicht threadsafe ist.
import java.awt.event.*;
import javax.swing.*;
public class Taktvoll
{
public static void main(String[] args)
{
JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
final JTextArea text = new JTextArea(25, 40);
panel.add(text);
JButton button = new JButton("klick mich");
button.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
new Thread(new Runnable()
{
public void run()
{
while (true)
{
try
{
SwingUtilities.invokeAndWait(new Runnable()
{
public void run()
{
text.setText(text.getText() + "hi!\n");
}
});
Thread.sleep(1000);
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
}
}).start();
}
});
panel.add(button);
JFrame frame = new JFrame("Taktartige Erzeugung");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(panel);
frame.pack();
frame.setVisible(true);
}
}
Geht aber bestimmt auch einfacher.
Geht aber bestimmt auch einfacher.
Mit dem empfohlenen Swing Timer ist es schon fast ein Kinderspiel:
import java.awt.event.*;
import javax.swing.*;
public class Taktvoll
{
public static void main(String[] args)
{
JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
final JTextArea text = new JTextArea(25, 40);
panel.add(text);
JButton button = new JButton("klick mich");
button.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
Timer timer = new Timer(1000, new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
text.setText(text.getText() + "hi!\n");
}
});
timer.setInitialDelay(0);
timer.start();
}
});
panel.add(button);
JFrame frame = new JFrame("Taktartige Erzeugung");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(panel);
frame.pack();
frame.setVisible(true);
}
}
Das sollte statt mit dem Timer auch mit dem "neuen" (since 1.5)
java.util.concurrent.ScheduledExecutorService gehen. Ich hatte sofort an das Package gedacht, da ich dort in letzter Zeit etwas mit herumgespielt hatte:
An ExecutorService that can schedule commands to run after a given delay, or to execute periodically.
[offtopic]@Fred: Ich sehe in deinem Beispiel nur noch innere Klassen und beim "addieren" von Strings quasi Bytecode. Danke nochmal für deinen Beitrag beim OO-Seminar [10][/offtopic]
Bytecode. Danke nochmal für deinen Beitrag beim OO-Seminar [10]
Gern. Der Vortrag wird am 20. Mai im KunterBuntenSeminar wiederholt, für alle Interessierten [23]
[offtopic]
Java-Programme werden in eine Zwischensprache namens "Bytecode" übersetzt, welche auf einer virtuellen Maschine ausgeführt wird. Was das genau bedeutet, wird im Studium normalerweise nicht weiter thematisiert.
Die Grundkonzepte dieser virtuellen Maschine werden in meinem Vortrag eingeführt. Dazu untersuchen wir eine handvoll einfacher Programme, deren übersetzte Form uns Aufschluss über die Funktionsweise der virtuellen Maschine gibt. Ganz nebenbei lernen wir, dass ein Großteil der neueren Java-Features im Kern nichts weiter als syntaktischer Zucker ist – und wer tut nicht gerne Zucker in seinen Kaffee? ;)
Im Anschluss an den etwa einstündigen Vortrag können wir interaktiv weitere einfache Java-Programme schreiben und den Bytecode zusammen analysieren.
[/offtopic]
Super, Euch allen herzlichen Dank!
Ich hatte es mal mit Tasks probiert und das ging nicht so richtig gut. Der SwingTimer stellte sich als für die geplante Umsetzung passendste Lösung heraus und macht genau das, was ich brauche.
Mal eine dumme Frage: Warum machst du:
[...]
new Thread(new Runnable()
{
public void run()
{
[...]
}
}).start();
[...]
anstatt einfach nur
new Thread()
{
public void run()
{
[...]
}
}.start();
? Hat das einen bestimmten Grund oder war das nur wegen des Ad-Hoc-Charakters?
Weil ich nicht von Thread erben will, ich finde Komposition schicker. So trenne ich ganz klar zwischen einem Thread und einer Aufgabe, die zu erledigen ist. Hab mal irgendwo gelesen, dass man das so machen soll, ist aber schon ewig her.