我试图弄清楚如何将挥杆组件设置为从a点到b点。这是一个代码的宝贝示例,它使红色JPanel从左向右移动:
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
public class MovingSquareExample {
private static final JPanel square = new JPanel();
private static int x = 20;
public static void createAndShowGUI(){
JFrame frame = new JFrame();
frame.getContentPane().setLayout(null);
frame.setSize(500,500);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(square);
square.setBounds(20,200,100,100);
square.setBackground(Color.RED);
Timer timer = new Timer(1000/60,new MyActionListener());
timer.start();
frame.setVisible(true);
}
public static class MyActionListener implements ActionListener{
@Override
public void actionPerformed(ActionEvent arg0) {
square.setLocation(x++, 200);
}
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable(){
@Override
public void run(){
createAndShowGUI();
}
});
}
}
它工作正常,只是我看起来有点波涛汹涌。具有可拖动方块的类似示例的动作(参见Draggable Components in Java Swing)显得更加平滑,因此我认为应该有一种方法可以让它看起来更好。任何建议将不胜感激。
答案 0 :(得分:4)
您正在为Swing库输入一个棘手的区域。但是,没有什么不可能的。你可以使用Timer创建这样的动画,但我真的建议你不要这样做。因此,您可以尽可能地移动组件,我建议您使用Timing Framework库。
但要注意:移动组件不是没有学习就应该做的事情。开发了Swing布局,以便按特定顺序放置组件。如果您操纵组件的尺寸和位置值,您将破坏布局的功能,并且您的程序可能会以奇怪的方式运行。我有过在不使用布局的情况下在Swing中开发应用程序的情况。在一个操作系统中,我的程序似乎工作正常,但将其移植到其他系统,一切都变得混乱。因此,在具有此类自定义项的Swing中启动应用程序之前,您需要保持关注并执行许多测试。
这是JavaFX技术落到我们手中的一个原因。有了这样的技术,我们可以用更少的东西(在不同的程序中部署应用程序)来关注自己,并做更多的事情(包括那些你遇到麻烦的事情)。考虑迁移到这项技术。因此,您可以看到JavaFX可以执行的操作,下载演示程序Ensemble(搜索“JavaFX演示和示例下载”)。作为研究来源,请开始here。
如果这个替代方案对你来说太费力了,请查看我给你的关于Timing Framework库的链接。在那里,您将找到Java代码的示例,这些代码可以在各种具有高性能的Swing事物上制作流畅的动画。要了解如何使用此库,我建议您阅读由Chet Haase和Romain Guy撰写的书Filthy Rich Clients。虽然这本书已经过时,但库代码中的内容已经更改,但您可以在library website上获得最新信息。正如我之前所说,下载库,并下载代码示例。随着时间的推移,你最终会以最好的方式做你想做的事。
我希望你能完成你想要的。祝好运。 :)
答案 1 :(得分:1)
这是我使用计时器为JComponent设置动画的一种方法。
private void animate(JComponent component, Point newPoint, int frames, int interval) {
Rectangle compBounds = component.getBounds();
Point oldPoint = new Point(compBounds.x, compBounds.y),
animFrame = new Point((newPoint.x - oldPoint.x) / frames,
(newPoint.y - oldPoint.y) / frames);
new Timer(interval, new ActionListener() {
int currentFrame = 0;
public void actionPerformed(ActionEvent e) {
component.setBounds(oldPoint.x + (animFrame.x * currentFrame),
oldPoint.y + (animFrame.y * currentFrame),
compBounds.width,
compBounds.height);
if (currentFrame != frames)
currentFrame++;
else
((Timer)e.getSource()).stop();
}
}).start();
}