Live Ticker "Endlosschleife"

sMau90

Aktives Mitglied
Hi,
Ich versuche grade einen Live Ticker in Java zu schreiben. Ich habe aber einfach keine gute Idee, wie ich es schaffe, dass der Text wenn er links "aus dem Bild rausläuft" auf der rechten Seite direkt wieder "einläuft". Also am besten so, dass keine Lücken entstehen. Mein Code bist jetzt (der Text läuft einfach einmal von rechts nach links durch):

Java:
public class PanelTicker extends JPanel {
	
	public PanelTicker() {
		setFont(new Font("Arial", Font.BOLD, 32));
		setBorder(null);
		setDoubleBuffered(true);
		
	}
	
	String tickerString = "";
	int x = 10;
	
	private Timer timer = new Timer(100, new ActionListener() {
		public void actionPerformed(ActionEvent arg0) {
			move();
		}
	});
	
	
	public void paintComponent(Graphics g) {
		
		/*
		 * Antialising einschalten
		 */
		((Graphics2D)g).setRenderingHint
		  (RenderingHints.KEY_ANTIALIASING,
		   RenderingHints.VALUE_ANTIALIAS_ON);

		Image image = new ImageIcon("/home/samu/Desktop/1.jpg").getImage();
		g.drawImage(image, 0, 0, Color.BLACK, this);
		g.setColor(Color.WHITE);
		g.drawString(tickerString, x, 32);
		
	}
	
	public void move() {
		
			x--;
			repaint();
			Display.getDisplayFrame().repaint();
	}
	
	public void setTimerDelay(int delay) {
		timer.setDelay(delay);
	}
	
	public void setTickerString() {
		
		tickerString = PanelDisplayControls.getTextFieldTickerString().getText();
		
	}
	

	public void setTimer(Timer timer) {
		this.timer = timer;
	}

	public Timer getTimer() {
		return timer;
	}
		
}

Wenn ich ja irgendwie die Position des gezeichneten Strings bestimmen könnte, würde ich schon klar kommen, aber hab einfach keine Idee und hab auch noch nicht viel mit Graphics gemacht.

Danke schonmal für die Hilfe

Grüße,
sMau
 
Zuletzt bearbeitet:

Michael...

Top Contributor
Grundsätzlich ist es eine schlechte Idee das Bild in der paintComponent zu laden.
Wenn das Bild aus der Komponente "herausgelaufen" ist, musst Du die x Koordinate natürlich auf einen vernünftigen Wert zurück setzen.
Wenn Du keine Lücken haben willst, musst Du das Bild zwei bis x-mal zeichnen.
 

sMau90

Aktives Mitglied
Ok, das Bild dient ja nur als Hintergrund. Und ja stimmt ist nicht sonderlich effektiv das immer mit neu zuzeichnen. Aber das was sich bewegt ist der String, nicht das Bild.
Also grundsätzlich hab ich aber die gleiche Idee die du grade geschildert hast, dass wenn ich die Position vom Ende des Strings, also so zu sagen den äußersten rechten Pixel, bestimme, kann ich das Programm dann entsprechend reagieren lassen. Aber ich weiß nicht wie ich die Position bestimme, oder welche andere Bedingung sonst in Frage käme.
Bin für jeden Vorschlag offen (=

Grüße,
sMau


EDIT

Ich glaube ich habe gefunden was ich gesucht habe, damit kann ich die breite des Strings in Pixeln berechnen und so auch den äußeren rechten Punkt.
Java:
g.getFontMetrics().stringWidth(string);

Falls dennoch jemand nen Ansatz für ne elegantere Lösung hat, immer her damit.
 
Zuletzt bearbeitet:

Michael...

Top Contributor
Ich glaube ich habe gefunden was ich gesucht habe, damit kann ich die breite des Strings in Pixeln berechnen und so auch den äußeren rechten Punkt.
Java:
g.getFontMetrics().stringWidth(string);

Falls dennoch jemand nen Ansatz für ne elegantere Lösung hat, immer her damit.
Sorry, hatte das mit dem String gar nicht gesehen. Wenn man davon ausgehen kann, dass der Font gleichbleibt oder sogar explizit für die Komponente gesetzt wird, sollte man die FontMetrics nicht vom Graphics Objekt sondern auch hier wieder ausserhalb der paintComponent von der Komponente direkt bezogen werden.
Ein anderere - vielleicht auch nicht ganz so schöner - Ansatz wäre, den String zu manipulieren, also vorne immer Buchstaben abschneiden. Damit könnte man einfach nur ein Label plus Thread/Timer nehmen ohne die paintComponent zu überschreiben.
 

sMau90

Aktives Mitglied
Der Font ist gleichbleibend und wird einmal explizit gesetzt.
Allerdings kann ich dir nicht ganz folgen, hab noch nich so viel mit Graphics gemacht.
Wenn du mir ein kleines Beispiel gibst, was du damit meinst reicht das aber bestimmt schon.

Jedenfalls nochmal vielen Dank für die ganzen Antworten.

Grüße,
sMau
 

Michael...

Top Contributor
Ganz am Anfang setzt Du ja den Font
Code:
new Font("Arial", Font.BOLD, 32));
, wenn Du nun eine Referenz auf das Font Objekt in einer Instanzvariablen halten würdest, könntest Du unmittelbar in der setTickerString() (die eigentlich keine echte set-Methode ist ;-)) über dessen FontMetrics die Breite des Strings bestimmen.
Java:
int width = font.getFontMetrics().stringWidth(tickerString);
In der von Dir geposten Zeile sieht es so aus, als würdest Du die Breite immer wieder in der paintComponent(...) neu berechnen, was - wenn der Font immer der gleiche bleibt - unnötig ist.
 

jgh

Top Contributor
ich hatte sowas mal vor langer Zeit auch implementiert...hier mal ein kleines KSKB:
Er beginnt jetzt von neuem, wenn der alte String "rausgelaufen" ist...aber das ist ja auch ruckzuck änderbar, wenn man einfach die Länge des Tickerstrings mitberechnet.

Java:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class LiveTickerPanel extends JPanel implements Runnable {
	private static final long serialVersionUID = 1L;
	private JLabel tickerLabel;
	private String tickerString;
	private int x = 0;
	private int step = 2;
	private int delay = 80;

	public LiveTickerPanel() {
		initComponents();
	}

	private void initComponents() {
		setLayout(new FlowLayout());
		this.setBackground(Color.RED);
		setOpaque(true);
		tickerString = "Das ist nur der Teststring";
		tickerLabel = new JLabel(tickerString);
		add(tickerLabel);
		tickerLabel.setLocation(x, 0);
		start();
	}

	private void start() {
		Thread t = new Thread(this);
		t.setDaemon(true);
		t.start();
	}

	public static void main(String[] args) {
		JFrame f = new JFrame();
		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		f.setSize(new Dimension(300, 300));
		f.setLocationRelativeTo(null);
		LiveTickerPanel ltp = new LiveTickerPanel();
		f.add(BorderLayout.SOUTH, ltp);
		f.setVisible(true);
	}

	@Override
	public void run() {
		while (!Thread.interrupted()) {
			if (isVisible()) {
				int widthX = getWidth();
				int laenge = tickerLabel.getWidth();
				if (x > -laenge) {
					x = x - step;
					SwingUtilities.invokeLater(new Runnable() {
						@Override
						public void run() {
							tickerLabel.setLocation(x, 0);
						}
					});
				} else {
					x = widthX;
				}
			}
			try {
				Thread.sleep(delay);
			} catch (InterruptedException e) {
				return;
			}
		}
	}
}
 

sMau90

Aktives Mitglied
Bin jetzt endlich mal dazu gekommen das auszuprobieren und es klappt auch alles wunderbar, allerdings wenn ich versuche das hier zu machen:

Java:
int width = font.getFontMetrics().stringWidth(tickerString);

Bekomme ich die Meldung "getFontMetrics is undefined for Type font".

Jemand ne Idee wie ich da trotzdem dran komme? Oder gibt es ne Möglichkeit wie ich einfach außerhalb der paint Methode an das "Grphics Objekt" ran komme? Damit ich nicht bei jedem repaint die String Länge neu berechne.

Grüße,
sMau
 
Zuletzt bearbeitet:

Michael...

Top Contributor
Sorry, mein Fehler so kurz vorm Wochenende lässt die Konzentration bei mir nach ;-)
Die Methode getFontMetrics(...) musst Du an Deiner Komponente aufrufen.
Innerhalb Deines Panels sollte sowas funktionieren:
Java:
int width = getFontMetrics(font).stringWidth(tickerString);
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
Farbtopf Live update JFreeChart AWT, Swing, JavaFX & SWT 3
M Swing JTextField live validieren und Rahmenfarbe ändern AWT, Swing, JavaFX & SWT 3
L JTable aus MySQL DB updaten - Live AWT, Swing, JavaFX & SWT 7
E Swing JFormattedTextField Live Validierung AWT, Swing, JavaFX & SWT 4
C Live Suche mit TextFeld AWT, Swing, JavaFX & SWT 2
P [SWT] - ProgressBar, Prozentzahlen live anzeigen geht nicht AWT, Swing, JavaFX & SWT 13
A Ticker als Thread AWT, Swing, JavaFX & SWT 3
L JavaFX TreeView aufstellen läuft irgendwie auf Endlosschleife AWT, Swing, JavaFX & SWT 3
N Swing Endlosschleife blockt Frame AWT, Swing, JavaFX & SWT 11
C Endlosschleife AWT, Swing, JavaFX & SWT 4
R Endlosschleife auf JButton druck beenden AWT, Swing, JavaFX & SWT 9
E Endlosschleife bei anklickbarer Fläche AWT, Swing, JavaFX & SWT 2
S Objekt wird während Endlosschleife nur einmal bewegt AWT, Swing, JavaFX & SWT 2
R [gelöst]Fenster schließen - trotz Endlosschleife in der Paint-Methode? AWT, Swing, JavaFX & SWT 3
G Checkbox, die eine Endlosschleife ausführt AWT, Swing, JavaFX & SWT 3
G Endlosschleife bei paint() + setBackground() AWT, Swing, JavaFX & SWT 2
F Endlosschleife bei drawImage() AWT, Swing, JavaFX & SWT 4
K JComboBox: Endlosschleife durch Events AWT, Swing, JavaFX & SWT 4

Ähnliche Java Themen

Neue Themen


Oben