Java Tips Weblog

  • Blog Stats

    • 2,569,319 hits
  • Categories

  • Archives

Marquee Panel

Posted by Rob Camick on April 24, 2011

A marquee is used to scroll a text message across the screen. The marquee components I’ve seen generally take a text string as a parameter for the marquee class. Then the plain text is scrolled across the screen. Wouldn’t it be nice to jazz up your marquee by using stylized text or by adding images to the marquee?

The MarqueePanel may be what you are looking for. It takes a different approach from other marquee components in that it doesn’t use a string to control the marquee. Instead it uses components. Thats right, just like you would add components to any other panel you add components to the MarqueePanel. Then the MarqueePanel will scroll the components to make it look like a marquee.

By using components you have much more flexibility to create a jazzy marquee. Of course, you can just add JLabel with some text for a simple marquee. But now you can also use a JLabel that uses HTML for its text. This means you can have different sized and colored fonts. If you don’t like using HTML you can try using a JTextPane and use the styled attributes available in the editor kit to give you a special look.

Also, you are not limited to a single component. The MarqueePanel uses a BoxLayout so you can add as many components as you want and they will be scrolled in a single line. The basic code I used to create the MarqueePanel used in the Webstart demo below is something like:

MarqueePanel marquee = new MarqueePanel();
marquee.add( new JLabel( "add some text here" ) );
marquee.add( new JLabel( new ImageIcon(...) ) );

I played with the label font to make it a little bigger, but I’m sure you get the idea. Then you add the marquee to your window and away you go. The scrolling will start as soon as the window is visible.

Of course it would also be nice to control some of the scrolling properties of the marquee. Here is a list of the methods that allow you to do so:

  • setScrollFrequency – controls how many times in a second the components are scrolled. Defaults to 5.
  • setScrollAmount – controls the scroll amount in pixels each time the components are scrolled.
  • setPreferredWidth – controls the preferred width of the marquee. A value of -1 will cause the default preferred width calculation to be used which will use half of the preferred width of the component.
  • setWrap – this allows components that have already scrolled off the left edge of the panel to be displayed again on the right edge of the panel. So rather than waiting for all components to completely scroll off the left edge you can have a more continous scroll.
  • setWrapAmount – specifies the space in pixels between the traling edge of the components on the panel and the starting edge of the components that have wrapped.
  • setScrollWhenFocused – scrolling of the components will only occur when the window has focus. When a window is deactivated scrolling will pause and then resume from the same place once the window is reactived

The above properties are dynamic. That is, they will take effect the next time the components are scrolled. I guess I should also mention the start(), stop(), pause() and resume() methods which are used to control the scrolling of the components. Hopefully the method names are self explanatory.

The magic for this implementation is achieved by using the Graphics2D.translate method
and by taking advantage of the Swing painting mechanism. I hope I haven’t broken any painting rules with this implementation. Check out the provided links below for more information.

Get The Code

MarqueePanel.java
MarqueePanelDemo.java
RelativeLayout.java (needed for demo)

Related Reading

Java Tutorials: A Closer Look at the Paint Mechanism
Java Tutorials: How to Write a Window Listener
Java API: java.awt.Graphics2D#translate(int, int)

24 Responses to “Marquee Panel”

  1. Eitan said

    Thanks.
    Very nice indeed.
    And welcome back.

  2. Rob Camick said

    Thanks, although I won’t be back on a regular basis as I’ve run out of ideas.

  3. Eitan said

    Don’t worry too much.
    I think your brain have the right foundation…
    I am 60 and I talk from experience.

  4. Gabriel said

    Thks

  5. mjquake said

    You are very awesome. I just somehow landed here on your page searching for a while now and continuosly trying to implement auto resize column width in a jtable.

    I think your tutorials are awesome and the starter classes are amazing. Thanks a million.

  6. eraveline said

    Great ! I’m going to use this right now and I won’t lose time trying to reimplent it. Cheers !

  7. andreuhres said

    This is an adaptation of Rob Camick’s code, to scroll components from the bottom edge of the panel to the top edge (instead of right to left):

    http://wiki.byte-welt.net/wiki/MarqueePanelV

    It would be nice, of course, if we could choose the direction (right-left or bottom-top) in a single class).

  8. iie said

    very nice, but memory leak..?

  9. Anonymous said

    thanks,it’s fantastic! :)

  10. Jon said

    Very nice! Could you include the code of the demo?
    Thanks!

  11. Dorotej said

    Can you set MarqueePanel background to alpha transparency? Kind regards.

  12. Dorotej said

    I added alpha transparency. Really, your code iz amazing! The best code I have seen related to the scrolling text! Thank you very much.

  13. navdeep said

    how to marquee images instead text….plz send me the source code plz….

  14. Klaus Versl said

    Great piece of code! I improved it in a way: To allow smooth rendering, i added a revalidate(); line in the actionPerformed(ActionEvent ae) method. This forces swing to actually repaint the marquee panel after each movement, up to 60 fps or more. But it raises CPU load also.

    	public void actionPerformed(ActionEvent ae) {
    		...
    
    			// hack: force to repaint the complete line of text 
    		revalidate(); 
    		repaint();
    	}
    
    • Rob Camick said

      revalidate() is used to invoke the layout manager, not force a repaint. The size/location of the components never change so this is unnecessary.

      The components are painted at a different location by using the translate(…) method. The repaint() will request the component to repaint itself. I verified this using JDK1.7 on Windows 7 by adding a System.out.println() statement before the repaint() method is invoked and at the start of the paintChildren() method. In my testing there is always a one-to-one relationship indicating the component is repainting itself as scheduled.

      Maybe this works differently on different platforms?

      • Anonymous said

        possibly. It can have other reasons as well, as I use an other scheduler to invoke the “actionPerformed()” method.
        I develop and use my code on Linux. Actually, in my situation, an explicit “revalidate()” statement is necessary to get a smooth movement. Else, the marquee would not paint more often than ~ 1 times per second. It depends on other things, like thread idle state, as well.

      • Rob Camick said

        > I use an other scheduler to invoke the “actionPerformed()” method.

        You aren’t using the class the way it was designed, so of course you may get non standard behaviour.

  15. Burkhard said

    If I use your marquee panel in eclipse, it works in the preview. But after I integrate the classes it into our MES visualization system, it shows nothing. That’s why I believe that the paint event of your marquee panel and the paint event of our MES visualization system are not harmonizing together.

  16. Anonymous said

    Where is “public static void main(String[]args)”

Leave a reply to andreuhres Cancel reply