在Java中创建动画JScrollPane的简单方法?

我目前有一个JScrollPane,它包含基本上是一个项目列表。 此JScrollPane将显示在信息屏幕上。

我正在寻找的是使它以给定的间隔自动滚动到列表底部的某种方式,然后回到顶部。 我认识到使用JScrollPane可能无法实现这一点,因此任何替代方案的建议都会很棒!

通常我会使用TimingFramework,或者你可以使用像Trident或Unviversal Tween Engine这样的东西作为任何动画的基础。 主要原因是,除了为您完成大部分工作外,它们还提供可变速度,这将使动画看起来更自然。

但是您可以使用javax.swing.Timer实现基本概念。

此示例将允许您滚动到图像的底部然后再返回。

动画将花费5秒(由runningTiming变量提供),允许它变化(图像越大,移动越快,图像越小,速度越慢)。

 import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.EventQueue; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Point; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import javax.imageio.ImageIO; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.Timer; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; public class AutoScroller { public static void main(String[] args) { new AutoScroller(); } private long startTime = -1; private int range = 0; private int runningTime = 5000; private int direction = 1; public AutoScroller() { EventQueue.invokeLater(new Runnable() { @Override public void run() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { } final JScrollPane scrollPane = new JScrollPane(new TestPane()); JFrame frame = new JFrame("Testing"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setLayout(new BorderLayout()); frame.add(scrollPane); // frame.pack(); frame.setSize(scrollPane.getPreferredSize().width, 200); frame.setLocationRelativeTo(null); frame.setVisible(true); Timer timer = new Timer(40, new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (startTime < 0) { startTime = System.currentTimeMillis(); range = scrollPane.getViewport().getView().getPreferredSize().height - scrollPane.getHeight(); } long duration = System.currentTimeMillis() - startTime; float progress = 1f; if (duration >= runningTime) { startTime = -1; direction *= -1; // Make the progress equal the maximum range for the new direction // This will prevent it from "bouncing" if (direction < 0) { progress = 1f; } else { progress = 0f; } } else { progress = (float) duration / (float) runningTime; if (direction < 0) { progress = 1f - progress; } } int yPos = (int) (range * progress); scrollPane.getViewport().setViewPosition(new Point(0, yPos)); } }); timer.setRepeats(true); timer.setCoalesce(true); timer.start(); } }); } public class TestPane extends JPanel { private BufferedImage image; public TestPane() { try { image = ImageIO.read(new File("Path/to/your/image")); } catch (IOException ex) { ex.printStackTrace(); } } @Override public Dimension getPreferredSize() { return image == null ? new Dimension(200, 200) : new Dimension(image.getWidth(), image.getHeight()); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); if (image != null) { Graphics2D g2d = (Graphics2D) g.create(); int x = (getWidth() - image.getWidth()) / 2; int y = (getHeight() - image.getHeight()) / 2; g2d.drawImage(image, x, y, this); g2d.dispose(); } } } } 

您是否考虑过使用计时器每隔一段时间向JScrollPane发送滚动指令? 只是想到的第一件事……