How to add marquee behaviour to text of JLabel
?
I have tried this
JLabel search = new JLabel("<html><marquee>Search</marquee><html>");
but its not working.
How to add marquee behaviour to text of JLabel
?
I have tried this
JLabel search = new JLabel("<html><marquee>Search</marquee><html>");
but its not working.
Please see http://forums.sun.com/thread.jspa?forumID=57&threadID=605616 for details about how to do this :)
(Edit: I would probably use System.currentTimeMillis() directly inside the paint() method instead of using a timer, and then divide / modulo (%) it to get it into the required range for 'x offset' on the examples). By increasing the size of the division number, you can change the speed ((System.currentTimeMillis() / 200) % 50).
(Edit 2: I just updated the code below to fix a problem with repainting. Now we schedule a repaint within the paint method; maybe there's a better way but this works :))
(Edit 3: Errr, I tried with a longer string and it messed up. That was easy to fix (increase range by width again to compensate for negative values, subtract by width)
package mt;
import java.awt.Graphics;
import javax.swing.Icon;
import javax.swing.JLabel;
public class MyJLabel extends JLabel {
public static final int MARQUEE_SPEED_DIV = 5;
public static final int REPAINT_WITHIN_MS = 5;
/**
*
*/
private static final long serialVersionUID = -7737312573505856484L;
/**
*
*/
public MyJLabel() {
super();
// TODO Auto-generated constructor stub
}
/**
* @param image
* @param horizontalAlignment
*/
public MyJLabel(Icon image, int horizontalAlignment) {
super(image, horizontalAlignment);
// TODO Auto-generated constructor stub
}
/**
* @param image
*/
public MyJLabel(Icon image) {
super(image);
// TODO Auto-generated constructor stub
}
/**
* @param text
* @param icon
* @param horizontalAlignment
*/
public MyJLabel(String text, Icon icon, int horizontalAlignment) {
super(text, icon, horizontalAlignment);
// TODO Auto-generated constructor stub
}
/**
* @param text
* @param horizontalAlignment
*/
public MyJLabel(String text, int horizontalAlignment) {
super(text, horizontalAlignment);
// TODO Auto-generated constructor stub
}
/**
* @param text
*/
public MyJLabel(String text) {
super(text);
}
/* (non-Javadoc)
* @see javax.swing.JComponent#paintComponent(java.awt.Graphics)
*/
@Override
protected void paintComponent(Graphics g) {
g.translate((int)((System.currentTimeMillis() / MARQUEE_SPEED_DIV) % (getWidth() * 2)) - getWidth(), 0);
super.paintComponent(g);
repaint(REPAINT_WITHIN_MS);
}
}
This works great (I wrote this by myself, so there might be some mistakes):
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class JMarqueeLabel extends JPanel implements Runnable
{
/**
*
*/
private static final long serialVersionUID = -2973353417536204185L;
private int x;
private FontMetrics fontMetrics;
public static final int MAX_SPEED = 30;
public static final int MIN_SPEED = 1;
private int speed;
public static final int SCROLL_TO_LEFT = 0;
public static final int SCROLL_TO_RIGHT = 1;
private int scrollDirection = 0;
private boolean started = false;
private JLabel label;
public JMarqueeLabel(String text)
{
super();
label = new JLabel(text)
{
/**
*
*/
private static final long serialVersionUID = -870580607070467359L;
@Override
protected void paintComponent(Graphics g)
{
g.translate(x, 0);
super.paintComponent(g);
}
};
setLayout(null);
add(label);
setSpeed(10);
setScrollDirection(SCROLL_TO_RIGHT);
}
@Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
label.paintComponents(g);
}
public void setScrollDirection(int scrollDirection)
{
this.scrollDirection = scrollDirection;
}
public int getScrollDirection()
{
return scrollDirection;
}
public void setSpeed(int speed)
{
if (speed < MIN_SPEED || speed > MAX_SPEED)
{
throw new IllegalArgumentException("speed out of range");
}
this.speed = speed;
}
public int getSpeed()
{
return speed;
}
@Override
public void validateTree()
{
System.out.println("Validate...");
super.validateTree();
label.setBounds(0, 0, 2000, getHeight());
if (!started)
{
x = getWidth() + 10;
Thread t = new Thread(this);
t.setDaemon(true);
t.start();
started = true;
}
}
public String getText()
{
return label.getText();
}
public void setText(String text)
{
label.setText(text);
}
public void setTextFont(Font font)
{
label.setFont(font);
fontMetrics = label.getFontMetrics(label.getFont());
}
@Override
public void run()
{
fontMetrics = label.getFontMetrics(label.getFont());
try
{
Thread.sleep(100);
} catch (Exception e)
{
}
while (true)
{
if (scrollDirection == SCROLL_TO_LEFT)
{
x--;
if (x < -fontMetrics.stringWidth(label.getText()) - 10)
{
x = getWidth() + 10;
}
}
if (scrollDirection == SCROLL_TO_RIGHT)
{
x++;
if (x > getWidth() + 10)
{
x = -fontMetrics.stringWidth(label.getText()) - 10;
}
}
repaint();
try
{
Thread.sleep(35 - speed);
} catch (Exception e)
{
}
}
}
}
This works for very long strings. If you need longer strings, than you have to change 2000
to a higher number.
Hope this is what you want :-)
Marquee Label in Java with Controlling direction of flow, speed and text Chech this post How to create marquee JLabel using java
As you found, the HTML on JLabel is limited to formatting and doesn't support the <marquee>
tag. You would have to use something like a SwingWorker
or a ExecutorService
to change the text every few milliseconds.
hier is a quick an dirty solution. If you need, I can precise the code in some points.
package gui;
import java.awt.Color;
import java.awt.GridLayout;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.ScrollPaneConstants;
public class ScrollLabel extends JPanel {
private static final long serialVersionUID = 3986350733160423373L;
private final JLabel label;
private final JScrollPane sPane;
private final ScrollMe scrollMe;
public ScrollLabel(String text) {
setLayout(new GridLayout(1, 1));
label = new JLabel(text);
sPane = new JScrollPane(label);
sPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);
JScrollBar horizontalScrollBar = new JScrollBar(JScrollBar.HORIZONTAL);
sPane.setHorizontalScrollBar(horizontalScrollBar);
setBorder(BorderFactory.createLineBorder(Color.RED));
add(sPane.getViewport());
scrollMe = new ScrollMe(this, label, sPane);
scrollMe.start();
}
class ScrollMe extends Thread {
JScrollPane sPane;
ScrollLabel parent;
JLabel label;
ScrollMe(ScrollLabel parent, JLabel label, JScrollPane sPane) {
this.sPane = sPane;
this.parent = parent;
this.label = label;
}
boolean isRunning = true;
@Override
public void run() {
int pos = 0;
try {
while (isRunning) {
if (sPane.isVisible()) {
int sWidth = parent.getSize().width;
int lWidth = label.getWidth();
if (sWidth < lWidth) {
if (pos + sWidth > lWidth)
pos = 0;
sPane.getHorizontalScrollBar().setValue(pos);
}
}
synchronized (this) {
wait(50);
pos += 1;
}
}
}
catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally {
isRunning = false;
}
}
}
public static void main(String[] args) {
JFrame jFrame = new JFrame("ScrollLabel");
jFrame.getContentPane().add(new ScrollLabel("how to add marquee behaviour to Jlabel !Java"));
jFrame.setVisible(true);
}
}