MarqueePanelV
Aus Byte-Welt Wiki
http://tips4java.wordpress.com/2011/04/24/marquee-panel/
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).
import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.event.*; /** * The MarqueePanelV is used to scroll components from the bottom edge of the * panel to the top edge. Scrolling is continuous. To simulate the scrolling * of text you can simply add a JLabel to the panel. * * Various properties control the scrolling of the components on the panel. * Changes to the properties are dynamic and will take effect the next time * the components are scrolled. * @author Rob Camick, André Uhres */ public final class MarqueePanelV extends JPanel implements ActionListener, AncestorListener, WindowListener { private boolean paintChildren; private boolean scrollingPaused; private int scrollOffset; private int wrapOffset; private int preferredHeight = -1; private int scrollAmount; private int scrollFrequency; private boolean wrap = false; private int wrapAmount = 50; private boolean scrollWhenFocused = true; private Timer timer = new Timer(1000, this); /** * Convenience constructor that sets both the scroll frequency and * scroll amount to a value of 5. */ public MarqueePanelV() { this(5, 5); } /** * * @param scrollFrequency * @param scrollAmount */ @SuppressWarnings("LeakingThisInConstructor") public MarqueePanelV(int scrollFrequency, int scrollAmount) { setScrollFrequency(scrollFrequency); setScrollAmount(scrollAmount); setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); addAncestorListener(this); } /* * Translate the location of the children before they are painted so it * appears they are scrolling bottom to top */ @Override public void paintChildren(Graphics g) { // Need this so we don't see a flicker of the text before scrolling if (!paintChildren) { return; } // Normal painting as the components scroll bottom to top Graphics2D g2d = (Graphics2D) g; g2d.translate(0, -scrollOffset); super.paintChildren(g); g2d.translate(0, scrollOffset); // Repaint the start of the components on the bottom edge of the panel once // all the components are completely visible on the panel. // (Its like the components are in two places at the same time) if (isWrap()) { wrapOffset = scrollOffset - super.getPreferredSize().height - wrapAmount; g2d.translate(0, -wrapOffset); super.paintChildren(g); g2d.translate(0, wrapOffset); } } /* * The default preferred size will be half the size of the components added to * the panel. This will allow room for components to be scrolled on and off * the panel. * * The default height can be overriden by using the setPreferredHeight() method. */ @Override public Dimension getPreferredSize() { Dimension d = super.getPreferredSize(); d.height = (preferredHeight == -1) ? d.height / 2 : preferredHeight; return d; } @Override public Dimension getMinimumSize() { return getPreferredSize(); } public int getPreferredHeight() { return preferredHeight; } /** * Specify the preferred height on the panel. A value of -1 will cause the * default preferred with size calculation to be used. * * @param preferredHeight preferred height of the panel in pixels */ public void setPreferredHeight(int preferredHeight) { this.preferredHeight = preferredHeight; revalidate(); } /** * Get the scroll amount. * * @return the scroll amount in pixels */ public int getScrollAmount() { return scrollAmount; } /** * Specify the scroll amount. The number of pixels to scroll every time * scrolling is done. * * @param scrollAmount scroll amount in pixels */ public void setScrollAmount(int scrollAmount) { this.scrollAmount = scrollAmount; } /** * Get the scroll frequency. * * @return the scroll frequency */ public int getScrollFrequency() { return scrollFrequency; } /** * Specify the scroll frequency. That is the number of times scrolling * should be performed every second. * * @param scrollFrequency scroll frequency */ public void setScrollFrequency(int scrollFrequency) { this.scrollFrequency = scrollFrequency; int delay = 1000 / scrollFrequency; timer.setInitialDelay(delay); timer.setDelay(delay); } /** * Get the scroll only when visible property. * * @return the scroll only when visible value */ public boolean isScrollWhenFocused() { return scrollWhenFocused; } /** * Specify the scrolling property for unfocused windows. * * @param scrollWhenVisible when true scrolling pauses when the window * loses focus. Scrolling will continue when * the window regains focus. When false * scrolling is continuous unless the window * is iconified. */ public void setScrollWhenFocused(boolean scrollWhenFocused) { this.scrollWhenFocused = scrollWhenFocused; } /** * Get the wrap property. * * @return the wrap value */ public boolean isWrap() { return wrap; } /** * Specify the wrapping property. Normal scrolling is such that all the text * will scroll from bottom to top. When the last part of the text scrolls off * the bottom edge scrolling will start again from the bottom edge. Therefore * there is a time when the component is blank as nothing is displayed. * Wrapping implies that as the end of the text scrolls off the top edge * the beginning of the text will scroll in from the bottom edge. So the end * and the start of the text is displayed at the same time. * * @param wrap when true the start of the text will scroll in from the bottom * edge while the end of the text is still scrolling off the top * edge. Otherwise the panel must be clear of text before it * will begin again from the bottom edge. */ public void setWrap(boolean wrap) { this.wrap = wrap; } /** * Get the wrap amount. * * @return the wrap amount value */ public int getWrapAmount() { return wrapAmount; } /** * Specify the wrapping amount. This specifies the space between the end of the * text on the top edge and the start of the text from the bottom edge when * wrapping is turned on. * * @param wrapAmount the amount in pixels */ public void setWrapAmount(int wrapAmount) { this.wrapAmount = wrapAmount; } /** * Start scrolling the components on the panel. Components will start * scrolling from the bottom edge towards the top edge. */ public void startScrolling() { paintChildren = true; scrollOffset = -getSize().height; timer.start(); } /** * Stop scrolling the components on the panel. The conponents will be * cleared from the view of the panel */ public void stopScrolling() { timer.stop(); paintChildren = false; repaint(); } /** * The components will stop scrolling but will remain visible */ public void pauseScrolling() { if (timer.isRunning()) { timer.stop(); scrollingPaused = true; } } /** * The components will resume scrolling from where scrolling was stopped. */ public void resumeScrolling() { if (scrollingPaused) { timer.restart(); scrollingPaused = false; } } // Implement ActionListener /** * Adjust the offset of the components on the panel so it appears that * they are scrolling from bottom to top. */ @Override public void actionPerformed(ActionEvent ae) { scrollOffset += scrollAmount; int height = super.getPreferredSize().height; if (scrollOffset > height) { scrollOffset = isWrap() ? wrapOffset + scrollAmount : -getSize().height; } repaint(); } // Implement AncestorListener /** * Get notified when the panel is added to a Window so we can use a * WindowListener to automatically start the scrolling of the components. */ @Override public void ancestorAdded(AncestorEvent e) { SwingUtilities.windowForComponent(this).addWindowListener(this); } @Override public void ancestorMoved(AncestorEvent e) { } @Override public void ancestorRemoved(AncestorEvent e) { } // Implement WindowListener @Override public void windowActivated(WindowEvent e) { if (isScrollWhenFocused()) { resumeScrolling(); } } @Override public void windowClosed(WindowEvent e) { stopScrolling(); } @Override public void windowClosing(WindowEvent e) { stopScrolling(); } @Override public void windowDeactivated(WindowEvent e) { if (isScrollWhenFocused()) { pauseScrolling(); } } @Override public void windowDeiconified(WindowEvent e) { resumeScrolling(); } @Override public void windowIconified(WindowEvent e) { pauseScrolling(); } @Override public void windowOpened(WindowEvent e) { startScrolling(); } }