Ticker als Thread

Status
Nicht offen für weitere Antworten.

A3D

Neues Mitglied
Hallo,

nach vielen gescheiterten Versuchen bitte ich euch, mir bei der Implementierung eines kleinen Tickers behilflich zu sein. Folgenden Beispielcode habe ich im Internet als Grundlage gefunden.

Code:
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;

/**
 * This class is not Thread safe; make calls on the UI Thread
 * using SwingUtilities.invokeXXX() calls.
 */
public class MyMarquee extends JPanel implements ActionListener {
    private Timer tick;
    private int offset;
    private String text = null;
    private int decrement;
    private int textWidth = 0;
    private int textHeight = 0;
    private Font font;

    /**
     * @param delay 	time between ticks
     * @param decrement	how much the offset changes at each tick
     */
    public MyMarquee(int delay, int decrement) {
        if ((delay < 0) || (decrement < 0)) {
            throw new IllegalArgumentException();
        }
        this.decrement = decrement;
        tick = new Timer(delay, this);
        tick.start();
        font = new Font("Dialog", Font.BOLD, 20);
    }

    public void actionPerformed(ActionEvent event) {
        if (offset < (-1 * textWidth)) {
            offset = getWidth();
        } else {
            offset -= decrement;
        }
        repaint();
    }

    public void paint(Graphics g) {
        super.paint(g);
        if (text != null) {
            g.setFont(font);
            textWidth =
                g.getFontMetrics().charsWidth(
                    text.toCharArray(),
                    0,
                    text.length());
            textHeight = g.getFontMetrics().getHeight();
            g.drawString(text, offset, textHeight);
        } else {
            textWidth = 0;
            textHeight = 0;
        }
    }

    public String getText() { return text; }

    public void setText(final String string) { text = string; }

    public static void main(String[] args) {
        MyMarquee marquee = new MyMarquee(100, 5);
        marquee.setText("Hello, World!");
        JFrame frame = new JFrame();
        frame.setSize(300, 300);
        frame.setContentPane(marquee);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.show();
    }

}


Dieser Code muss nun so modifiziert werden, dass es als Thread laufen kann. Deshalb dachte ich mir, zunächst die Erweiterung der Klasse MyMarquee als JPanel aufzuheben und als Zeichenbereich später in meiner Main-Methode über setPanel() zuzuweisen. Aber daran scheitert es auch schon. Meine TestTicker Klasse sieht nun so aus:


Code:
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JPanel;
import javax.swing.Timer;

/**
 * This class is not Thread safe; make calls on the UI Thread
 * using SwingUtilities.invokeXXX() calls.
 */
public class Ticker /*extends JPanel*/ implements ActionListener {

    private static final long serialVersionUID = -5470650929609724739L;
    private Timer tick;
    private int offset;
    private String text = null;
    private int textWidth = 0;
    private int textHeight = 0;
    private Font font= new Font("Dialog", Font.BOLD, 20);
    private int delay = 100;
    private int decrement = 5;
    private JPanel pane;

    /**
     * @param delay 	time between ticks
     * @param decrement	how much the offset changes at each tick
     */
    
    public Ticker() {
        tick = new Timer(delay, this);
        tick.start();
    }

    public Ticker(JPanel p) {
    	setPanel(p);
        tick = new Timer(delay, this);
        tick.start();
    }

    public void actionPerformed(ActionEvent event) {
        if (offset < (-1 * textWidth)) {
            offset = pane.getWidth();
        } else {
            offset -= decrement;
        }
        pane.repaint();
    }

    public void paint(Graphics g) {
        pane.paint(g);
        if (text != null) {
            g.setFont(font);
            textWidth =
                g.getFontMetrics().charsWidth(
                    text.toCharArray(),
                    0,
                    text.length());
            textHeight = g.getFontMetrics().getHeight();
            g.drawString(text, offset, textHeight);
        } else {
            textWidth = 0;
            textHeight = 0;
        }
    }

    public String getText() { return text; }

    public void setText(final String string) { text = string; }
    
    public void setPanel(JPanel p) { pane= p; }


}

Code:
public class TickerTest {

    public static void main(String[] args) {
        JFrame frame = new JFrame();
        JPanel pane = new JPanel();  
        Ticker ticker = new Ticker();
        ticker.setText("Hello, World!");
        ticker.setPanel(pane);
        
        frame.setContentPane(pane);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(250, 250);
        frame.pack();
        frame.setVisible(true);
    }

Könnt ihr mir sagen, was ich übersehen oder hier falsch gemacht habe?
 

André Uhres

Top Contributor
A3D hat gesagt.:
Dieser Code muss nun so modifiziert werden, dass es als Thread laufen kann.
Der läuft schon als Thread :wink: . Hier wird er gestartet:
Code:
tick.start();

Die GUI sollte aber auf dem EventDispatchThread (= UI Thread) gestartet werden:
Code:
public static void main(final String[] args) {
    Runnable gui = new Runnable() {
        public void run() {
            MyMarquee marquee = new MyMarquee(100, 5);
            marquee.setText("Hello, World!");
            JFrame frame = new JFrame();
            frame.setSize(300, 300);
            frame.setContentPane(marquee);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setVisible(true);
        }
    };
    //GUI must start on EventDispatchThread:
    SwingUtilities.invokeLater(gui);
}
Das steht übrigens auch in der Klasse drin:
Code:
/**
 * This class is not Thread safe; make calls on the UI Thread
 * using SwingUtilities.invokeXXX() calls.
 */

Und in Swing überschreiben wir gewöhnlich nicht paint, sondern paintComponent:
Code:
@Override
public void paintComponent(Graphics g) {
    super.paintComponent(g);
    if (text != null) {
        g.setFont(font);
        textWidth =
                g.getFontMetrics().charsWidth(
                text.toCharArray(),
                0,
                text.length());
        textHeight = g.getFontMetrics().getHeight();
        g.drawString(text, offset, textHeight);
    } else {
        textWidth = 0;
        textHeight = 0;
    }
}
Deine modifizierte Version kann nicht funktionieren, weil die paint Methode nie aufgerufen wird,
da sie keine Überschreibung mehr ist von einer Superklasse :wink:
Wenn wir bei Überschreibungen immer die Annotation "@Override" benutzen,
dann prüft schon der Compiler, ob es überhaupt so eine Methode in einer Superklass gibt.
 

A3D

Neues Mitglied
Hallo André,

danke für deine Hilfe. Du hast natürlich recht, es läuft bereits als Thread. Eigentlich meinte ich, dass die Klasse Ticker um die Klasse Thread erweitert werden sollte. Das hat den Hintergrund, dass sich dieser Thread in bestimmten Zeitabständen mit einem anderen synchronisieren soll. Dafür sollte man, so habe ich gelesen, "extends Thread" im Gegensatz zu "implements runnable" bevorzugen.

Zurück zum eigentlichen Problem. Deine Snippets habe ich versucht umzusetzen, aber das Programm läuft leider noch nicht. D.h der Compiler gibt eine Fehlermeldung für die Zeile

Code:
super.paintComponent(g);

aus, die besagt: "The method paintComponent(Graphics) is undefined for the type Object". Das ist auch ziemlich einleuchtend, da die Oberklasse für Ticker dieses ja auch nicht implementiert. Zeigst du mir bitte, wie ich dieses Problem beheben kann.

Der angepasste Code sieht bislang so aus:

Ticker.java

Code:
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JPanel;
import javax.swing.Timer;

/**
* This class is not Thread safe; make calls on the UI Thread
* using SwingUtilities.invokeXXX() calls.
*/

public class Ticker implements ActionListener {

    private static final long serialVersionUID = -5470650929609724739L;
    
    private Timer tick;
    private int offset;
    private String text = null;
    private int textWidth = 0;
    private int textHeight = 0;
    private Font font= new Font("Dialog", Font.BOLD, 20);
    private int delay = 100;
    private int decrement = 5;
    private JPanel pane;
    
    public String getText()                  { return text;   }
    public void setText(final String string) { text = string; }
    public void setPanel(JPanel p)           { pane= p;       }

    public Ticker() {
        tick = new Timer(delay, this);
        tick.start();
    }

    public Ticker(JPanel p) {
       setPanel(p);
        tick = new Timer(delay, this);
        tick.start();
    }

    public void actionPerformed(ActionEvent event) {
        if (offset < (-1 * textWidth)) {
            offset = pane.getWidth();
        } else {
            offset -= decrement;
        }
        pane.repaint();
    }


    public void paintComponent(Graphics g) {
        super.paintComponent(g);   // <--- Fehlermeldung!
        if (text != null) {
            g.setFont(font);
            textWidth  = g.getFontMetrics().charsWidth( text.toCharArray(), 0, text.length());
            textHeight = g.getFontMetrics().getHeight();
            g.drawString(text, offset, textHeight);
        }
        else {
            textWidth = 0;
            textHeight = 0;
        }
    }



}



TickerTest.java
Code:
public class TickerTest {

	public static void main(final String[] args) {
	    Runnable gui = new Runnable() {
	        public void run() {
	            Ticker ticker = new Ticker();
	            ticker.setText("Hello, World!");

	            JFrame frame = new JFrame();
	            JPanel pane = new JPanel();

	            ticker.setPanel(pane);
	            frame.setSize(300, 300);
	            frame.setContentPane(pane);
	            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	            frame.setVisible(true);
	        }
	    };
	    //GUI must start on EventDispatchThread:
	    SwingUtilities.invokeLater(gui);
	}
	
	
	public void paintComponent() {
	}

}

Grüsse
 

André Uhres

Top Contributor
Deine modifizierte Version kann nicht funktionieren, weil die "paintComponent"-Methode nie aufgerufen wird,
da sie keine Überschreibung mehr ist von einer Superklasse.
Wenn wir bei Überschreibungen immer die Annotation "@Override" benutzen,
dann prüft schon der Compiler, ob es überhaupt so eine Methode in einer Superklasse gibt.
Code:
@Override
public void paintComponent(Graphics g) {
Die "paintComponent"-Methode muss also auf jedenfall in eine Unterklasse von "JComponent" kommen.
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
S Live Ticker "Endlosschleife" AWT, Swing, JavaFX & SWT 10
P thread nimmt veränderte boolean nicht AWT, Swing, JavaFX & SWT 7
N JFrame loescht alles, sobald der Thread zuende ist AWT, Swing, JavaFX & SWT 22
M Server/Client thread von GUI Trennen AWT, Swing, JavaFX & SWT 2
K JavaFx, Sound Aufnahme und Thread AWT, Swing, JavaFX & SWT 0
T Exception in thread "main" java.lang.NoClassDefFoundError AWT, Swing, JavaFX & SWT 4
G Exception javafx Thread -> caused by removing children while in EventHandler AWT, Swing, JavaFX & SWT 28
H Event Handling Thread - Abruf der get-Methode AWT, Swing, JavaFX & SWT 5
J "Exception in thread "AWT-EventQueue-0"" Fehler AWT, Swing, JavaFX & SWT 3
G Thread starten Swing AWT, Swing, JavaFX & SWT 5
C Thread verwalten AWT, Swing, JavaFX & SWT 2
A Swing Exception in thread "AWT-EventQueue-0" AWT, Swing, JavaFX & SWT 1
S JavaFX Exception in thread "JavaFX Application Thread" AWT, Swing, JavaFX & SWT 3
L Label im JavaFX Thread Updaten AWT, Swing, JavaFX & SWT 3
ralfb1105 JavaFX Alert Confirmation Dialog aus einem Service Thread AWT, Swing, JavaFX & SWT 8
ralfb1105 JavaFX MVC: Thread in Model Class mit Ausgabe in TextArea AWT, Swing, JavaFX & SWT 10
D Swing SwingUtils / Thread Problem AWT, Swing, JavaFX & SWT 3
J Thread per Button starten AWT, Swing, JavaFX & SWT 10
J Thread kennt JButton nicht. AWT, Swing, JavaFX & SWT 11
T JavaFX Task / Thread / FXThread Komplikationen AWT, Swing, JavaFX & SWT 5
O Swing Event Dispatch Thread AWT, Swing, JavaFX & SWT 1
L JavaFX UI Thread block AWT, Swing, JavaFX & SWT 13
X Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: -1 AWT, Swing, JavaFX & SWT 6
sandaime Swing Thread für CMD auslesen AWT, Swing, JavaFX & SWT 16
E JavaFX JavaFX Application in Thread ausführen AWT, Swing, JavaFX & SWT 1
D JavaFX UI-Thread und DB-Thread trennen um z.B. Ladebalken anzuzeigen AWT, Swing, JavaFX & SWT 15
T JavaFX Controller im extra Thread AWT, Swing, JavaFX & SWT 0
T Swing 2 Thread.sleep parallel laufen lassen AWT, Swing, JavaFX & SWT 4
L Zweites Fenster mit Thread AWT, Swing, JavaFX & SWT 0
E JavaFX Stage.show() in ursprünglichem Thread starten AWT, Swing, JavaFX & SWT 7
L Swing Frame in Thread wird nicht gezeichnet AWT, Swing, JavaFX & SWT 2
N Programm mit Swing und Thread, Figur bewegen sich nicht AWT, Swing, JavaFX & SWT 6
C Im ActionListener Buttons disablen, einen Thread starten, dann Buttons enablen AWT, Swing, JavaFX & SWT 2
C Thread-/ Simulations- Problem AWT, Swing, JavaFX & SWT 18
T Swing Button bleibt grau [=> UI hat sich aufgehängt, Aufgabe in Thread auslagern] AWT, Swing, JavaFX & SWT 3
M Thread-Frage in SWT AWT, Swing, JavaFX & SWT 1
Q GUI außerhalb GUI-Thread updaten - GUI friert ein AWT, Swing, JavaFX & SWT 18
C Thread in Klassen starten AWT, Swing, JavaFX & SWT 4
L exception in thread awt-eventqueue-0 java.lang.nullpointerexception AWT, Swing, JavaFX & SWT 2
S Swing Exception in thread "AWT-EventQueue-0" bei Jlabel AWT, Swing, JavaFX & SWT 4
D SWT SWT Elemente aus anderen Klassen aufrufen - Invalid thread access AWT, Swing, JavaFX & SWT 6
K JavaFX Tableview mit fxml ohne Aktualiserung trotz Thread AWT, Swing, JavaFX & SWT 13
K Event Handling 2 Buttons und Thread stop AWT, Swing, JavaFX & SWT 3
C Swing Update von swing-TableModels per Thread. Eins geht, das andere nicht, warum? AWT, Swing, JavaFX & SWT 12
V JLabel bzw. GUI aus externen Thread ansteuern AWT, Swing, JavaFX & SWT 3
J Applet Paralleles Thread Handling AWT, Swing, JavaFX & SWT 3
H Swing JfreeChart aktualisieren - mit daten aus thread AWT, Swing, JavaFX & SWT 3
T Java Swing Main GUI Thread AWT, Swing, JavaFX & SWT 3
C Event Handling Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException AWT, Swing, JavaFX & SWT 43
T Table-Zeilen mit Thread einfärben AWT, Swing, JavaFX & SWT 15
F Swing GUI-Thread für automatisches Update nutzen AWT, Swing, JavaFX & SWT 10
Y KeyListener, GUI Thread, repaint AWT, Swing, JavaFX & SWT 7
V Nullpointerexception (etwas mit thread und jframe) AWT, Swing, JavaFX & SWT 3
P Problem Thread.sleep() und JProgressBar AWT, Swing, JavaFX & SWT 7
S SWT GUI-Thread AWT, Swing, JavaFX & SWT 11
A Thread und sleep(1000); AWT, Swing, JavaFX & SWT 7
B Swing Thread+Animation AWT, Swing, JavaFX & SWT 7
S Timer oder Thread.sleep AWT, Swing, JavaFX & SWT 3
M Exception in thread "Thread-3" java.lang.NullPointerException AWT, Swing, JavaFX & SWT 18
B Über SWT Button Thread beenden AWT, Swing, JavaFX & SWT 2
C SWT Gui Thread hängt sich auf AWT, Swing, JavaFX & SWT 3
lumo SWT Exception in thread "main" org.eclipse.swt.SWTError: No more handles AWT, Swing, JavaFX & SWT 3
Luk10 Swing Problem mit Zeichen-Thread AWT, Swing, JavaFX & SWT 8
G 2D-Grafik Von Thread aus Zeichnen AWT, Swing, JavaFX & SWT 5
U Swing JLabel bewegen mittels Thread AWT, Swing, JavaFX & SWT 3
M JProgressBar für einen Thread AWT, Swing, JavaFX & SWT 14
R JTable und Thread AWT, Swing, JavaFX & SWT 4
K Thread.sleep in GUI AWT, Swing, JavaFX & SWT 4
J Thread funktioniert nicht AWT, Swing, JavaFX & SWT 10
D JPanel mit Thread in JPanel AWT, Swing, JavaFX & SWT 4
F Exception in thread "AWT-EventQueue-0" java.lang.NumberFormatException: null AWT, Swing, JavaFX & SWT 5
P Teil einer Swing GUI in eigenem Thread AWT, Swing, JavaFX & SWT 4
S Thread.sleep() in einer methode fürs zeichen AWT, Swing, JavaFX & SWT 3
O JTree/TreeModel/DefaultMutableTreeNodes thread safe machen AWT, Swing, JavaFX & SWT 3
P repaint während Thread läuft AWT, Swing, JavaFX & SWT 9
F SWT table refresh per Thread AWT, Swing, JavaFX & SWT 2
V Swing remove(Component) blockiert Thread sehr lange. AWT, Swing, JavaFX & SWT 6
J AWT Artefakte bei AWT-Rendering durch parallelen Thread AWT, Swing, JavaFX & SWT 4
H Thread-Problem mit der Darstellung beim Sperren des Fensters AWT, Swing, JavaFX & SWT 2
T Event Dispatch Thread und noch ein Thread AWT, Swing, JavaFX & SWT 7
Burny91 Swing Thread mit wait() und notify() steuern AWT, Swing, JavaFX & SWT 22
N SWT - über Thread Composite erstellen und Anhängen AWT, Swing, JavaFX & SWT 6
K Vom Gui aus auf einen Thread warten AWT, Swing, JavaFX & SWT 4
X Problem bei JTextArea und Thread.sleep() AWT, Swing, JavaFX & SWT 8
F Merkwürdiges Verhalten zeichnen sperater Thread AWT, Swing, JavaFX & SWT 13
B Swing Swing und Thread.sleep() AWT, Swing, JavaFX & SWT 6
N Exception Behandlung mit setDefaultUncaughtExceptionHandler, insbesondere im EventDispatcher Thread AWT, Swing, JavaFX & SWT 4
Q Neuer Thread zum Öffnen AWT, Swing, JavaFX & SWT 2
P Swing GUI im Thread? AWT, Swing, JavaFX & SWT 5
T GUI JFrame - neuer Thread AWT, Swing, JavaFX & SWT 2
data89 Was mache ich mit "Dispatched Event Thread"/Substance falsch? AWT, Swing, JavaFX & SWT 4
0x7F800000 Allg. Frage zum ev. dispatch thread, wie korrekt auf reaktion der Listener warten? AWT, Swing, JavaFX & SWT 4
S Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException AWT, Swing, JavaFX & SWT 7
T thread.sleep Sprung Problem AWT, Swing, JavaFX & SWT 24
N Server mit Thread und Statusbox AWT, Swing, JavaFX & SWT 3
S Objektverhalten in einen Thread legen AWT, Swing, JavaFX & SWT 4
G JProgressBar actionPerformedMethode und SwingUI thread AWT, Swing, JavaFX & SWT 36
E Komponenten in Event Dispatch Thread erzeugen? AWT, Swing, JavaFX & SWT 4
J Thread in GUI einbauen AWT, Swing, JavaFX & SWT 2
Lony AbstractTableModel Exception in thread "AWT-EventQueue- AWT, Swing, JavaFX & SWT 3

Ähnliche Java Themen

Neue Themen


Oben