I'm sure there are better ways, but here's a rudimentary late-night attempt:
package yawmark.jdc.marquee;
import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Rectangle2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
public class MarqueeDemo {
public static void main(String[] args) {
String message = "All work and no play makes Jack a dull boy. ";
MarqueePanel panel = new MarqueePanel(message, 5);
JFrame f = new JFrame("MarqueeDemo");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setLocationRelativeTo(null);
f.add(panel, BorderLayout.CENTER);
f.setSize(300, 300);
f.setVisible(true);
panel.start();
}
}
class MarqueePanel extends JPanel {
private String message;
private Timer timer;
private int delay;
private int x;
private int y;
public MarqueePanel(String message, int delay) {
this.message = message;
this.delay = delay;
}
public void start() {
this.x = getWidth();
if (this.timer == null) {
this.timer = new Timer(this.delay, new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
MarqueePanel.this.update();
MarqueePanel.this.repaint();
}
});
this.timer.start();
}
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawString(this.message, this.x, this.y);
}
void update() {
updateXposition();
updateYposition();
}
private void updateYposition() {
final int panelHeight = getHeight();
this.y = panelHeight / 2;
}
private void updateXposition() {
this.x--;
if ((offRightSideOfPanel()) || (offLeftSideOfPanel())) {
this.x = getWidth();
}
}
private boolean offLeftSideOfPanel() {
final Font font = getFont();
final FontMetrics metrics = getFontMetrics(font);
final Graphics graphics = getGraphics();
final Rectangle2D stringBounds = metrics.getStringBounds(this.message, graphics);
final double messageWidth = stringBounds.getWidth();
return (this.x + messageWidth) < 0;
}
private boolean offRightSideOfPanel() {
return this.x > getWidth();
}
}
~