How to make JScrollPane (In BorderLayout, containing JPanel) smoothly autoscroll

故事扮演 提交于 2019-11-29 17:41:33

You can set the value of the horizontal scrollbar to control what is currently visible:

JScrollBar horizontal = scroll.getHorizontalScrollBar();
horizontal.setValue( horizontal.getValue() + ??? );

You would need to use a Swing Timer to schedule the scrolling at an appropriate interval.

Simple example of using a Timer to scroll text:

import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;

public class TimerTest extends JPanel implements ActionListener
{
    JLabel timeLabel;
    JLabel scrollLabel;

    public TimerTest()
    {
        setLayout( new BorderLayout() );

        timeLabel = new JLabel( new Date().toString() );
        add(timeLabel, BorderLayout.NORTH);

        scrollLabel = new JLabel( "Some continuously scrolling text!!      " );
        add(scrollLabel, BorderLayout.SOUTH);

        int time = 1000;
        javax.swing.Timer timer = new javax.swing.Timer(time, this);
        timer.setInitialDelay(1);
        timer.start();
    }

    public void actionPerformed(ActionEvent e)
    {
        timeLabel.setText( new Date().toString() );
        String oldText = scrollLabel.getText();

        // Scroll right to left
        String newText = oldText.substring(1) + oldText.substring(0, 1);

        // Scroll left to right
//      int length = oldText.length();
//      String newText = oldText.substring(length-1, length)
//          + oldText.substring(0, length-1);

        scrollLabel.setText( newText );
    }

    private static void createAndShowGUI()
    {
        JFrame frame = new JFrame("SSCCE");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add( new TimerTest() );
        frame.setLocationByPlatform( true );
        frame.pack();
        frame.setVisible( true );
    }

    public static void main(String[] args)
    {
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                createAndShowGUI();
            }
        });
    }
}

One possible solution might be to take advantage of JComponent#scrollRectToVisible and a Swing Timer

For example...

import java.awt.Container;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JViewport;
import javax.swing.Scrollable;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class ScrollTest {

    public static void main(String[] args) {
        new ScrollTest();
    }

    public ScrollTest() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new JScrollPane(new TestPane()));
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel implements Scrollable {

        public TestPane() {
            Timer timer = new Timer(40, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    JViewport viewport = (JViewport) getParent();
                    Rectangle viewRect = viewport.getViewRect();

                    if (viewRect.x + viewRect.width < getWidth()) {
                        viewRect.x += 2;
                        scrollRectToVisible(viewRect);
                    } else {
                        ((Timer)e.getSource()).stop();
                    }
                }
            });
            timer.start();
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(1000, 200);
        }

        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            g2d.drawLine(0, 0, getWidth(), getHeight());
            g2d.dispose();
        }

        @Override
        public Dimension getPreferredScrollableViewportSize() {
            return new Dimension(200, 200);
        }

        @Override
        public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {
            return 64;
        }

        @Override
        public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) {
            return 64;
        }

        @Override
        public boolean getScrollableTracksViewportWidth() {
            return getPreferredSize().width <= getParent().getSize().width;
        }

        @Override
        public boolean getScrollableTracksViewportHeight() {
            return getPreferredSize().height <= getParent().getSize().height;
        }

    }

}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!