几乎没有什么信息可以继续,而且您可能遇到问题的原因有很多。
以下是我如何解决您的问题的简单示例。注意-我个人不喜欢null
布局,它们对 Swing 的内部工作方式造成了很大的困扰,并且往往会产生比它们解决的更多的问题。相反,当我想取消布局管理器时,我使用 aJLayeredPane
代替。
public class BouncingLabel {
public static void main(String[] args) {
new BouncingLabel();
}
public BouncingLabel() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JLayeredPane {
private JLabel label;
private Point p;
private int dv = 2;
public TestPane() {
p = new Point();
label = new JLabel("Look Ma, no hands!");
add(label);
Timer timer = new Timer(60, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
p.y = (getHeight() - label.getHeight()) / 2;
p.x = p.x + dv;
if (p.x + label.getWidth() > getWidth()) {
dv *= -1;
p.x = getWidth() - label.getWidth() + dv;
} else if (p.x < 0) {
dv *= -1;
p.x = 0 + dv;
}
label.setLocation(p);
repaint();
}
});
timer.setRepeats(true);
timer.setCoalesce(true);
timer.start();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 100);
}
@Override
public void doLayout() {
super.doLayout();
label.setSize(label.getPreferredSize());
label.getLocation(p);
}
}
}
更新
仔细检查代码后,您似乎违反了事件调度线程 - 无阻塞规则。所有 UI 更新都在单个线程(EDT)中维护,任何阻塞该线程的操作都将阻止 EDT 将事件分派给所有组件,包括重绘请求。
做这样的事情..
for (int i=x1;i<x2;i++)
{
label.setbound(i,y1+(x-i)*m,label.getwidth(),label.gethigh());
}
意味着您已阻止 EDT 将任何所需的更新事件分派到 UI 的其余部分,阻止它更新屏幕,直到您退出该方法。
查看Swing 中的并发以获取更多详细信息。
我还将仔细研究如何使用 Swing Timers和Swing Worker来获得一些解决方案。