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.
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.
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);
}
}
Hi, 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);
}
}
Hello,
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 :-)
Hi
i have tested this program , it is working for Longer String length that exceed out of Frame if i give only ' Welcome to My Home ' String is not moving , really it's good please send me if you have any program for this on [email protected]
thanks, Ranveer Singh kushwah