【问题标题】:Swing Repeated repaints JComboBox flickerSwing Repeated 重绘 JComboBox 闪烁
【发布时间】:2014-04-05 13:57:33
【问题描述】:

我的动画和 JComboBox 出现问题。在我的应用程序中,我可以使用鼠标和键盘或设置动画来移动和变换我的形状。

我的组件层次结构如下:放置在我的 JFrame 中的 JPanel 包含一个名为 EditorCanvas 的面板,用于修改和绘制形状,以及一个名为 DrawMenu 的面板,其中包含一些 JButton 和我的 JComboBox。

JFrame -> JPanel -> EditorCanvas
JFrame -> JPanel -> DrawMenu -> JComboBox

JComboBox 用于在单击时选择要添加到画布的形状。 在另一个线程中,我在计算新位置等后每 10 毫秒在画布上调用一次 repaint()...

问题是我不能再使用我的 JComboBox,因为弹出窗口在我打开后立即消失。这在某些时候是由我的重绘引起的。真正奇怪的是我的 JComboBox 被放置在另一个面板中,所以不应该重新绘制它。

我尝试在 SwingUtilities.invokeLater 调用的 Runnable 中替换我的重绘调用,但问题仍然存在。

以下是我的代码的一些相关部分:

public class EditorCanvas extends JPanel implements MouseListener, MouseMotionListener, KeyListener {

    ...

    @Override
    public void paintComponent(Graphics g) {

        super.paintComponent(g);

        // To keep keyboard focus
        this.requestFocusInWindow();

        this.graphics = (Graphics2D) g.create();

        this.graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

        this.mainRenderer.paintAll(this.graphics);
    }


public class AnimationManager implements Runnable {

    ...

    public void run () {

        try {

            while (Thread.currentThread() == this.thread) {

                // Update time values
                double curTime = System.currentTimeMillis();
                double deltaTime = curTime - this.lastTime;
                this.lastTime = curTime;

                for (Animation anim : this.animations) {
                    anim.update(deltaTime);
                }

                SwingUtilities.invokeLater(new Runnable() {
                    public @Override void run() {
                        EditorParameters.getCanvas().repaint();
                    }
                });

                // Pause the animation if it has to
                synchronized (this) {

                    while (this.pause) {
                        System.out.println("\nAnimation paused!\n");
                        this.wait();
                    }
                }

                Thread.sleep(SLEEP_TIME);
            }

【问题讨论】:

  • 尝试用validate/revalidate/invalidate 代替repaint。我不能说它是否有效,因为您没有共享完整的可测试代码。

标签: java swing animation repaint


【解决方案1】:

问题是我不能再使用我的 JComboBox,因为弹出窗口会立即消失

绘画方法仅供绘画。

this.requestFocusInWindow();

你不应该在绘画方法中调用类似的方法。

我什至不知道您为什么需要自定义面板。您不应该调用另一个组件的 paintAll() 方法。 Swing 将负责绘制面板的所有子组件。

【讨论】:

  • 事实上我不想重绘 JComboBox 或其他,它只是在我重绘 EditorCanvas 时被重绘。这绝对不是我想要的,但我无能为力:它不仅重新绘制了我的 EditorCanvas,而且还重新绘制了其他面板,我想。
  • 对于其他评论:我调用 requestFocusInWindow() 因为我经常在不理解的情况下失去键盘焦点。 paintAll 是另一个类中的方法,在面板上绘制形状,我刚刚发现这个方法名称已经存在于一些 Swing 预定义的类中。
  • @user3501153, because I often lose the keyboard focus - 当您单击组合框时,您当然会失去键盘焦点。在paintComponent() 方法中调用requestFocusInWindow() 方法不是解决方案。解决方案是不使用 KeyListener,而是使用Key Bindings。如果您需要进一步的帮助,那么您需要发布一个正确的 SSCCE 来证明问题。
  • 在尝试创建 SSSCE 并将代码减少到严格的最低限度时,我发现是我对 requestFocusInWindow() 的调用从 JComboBox 中窃取了焦点......正如你所说。但我仍然有一个焦点问题:画布根本没有它。我需要它来让我的鼠标和键盘监听器工作。
  • 谢谢camickr。我花了大约一周的时间,因为我的应用程序相当大......所以它本身不是重绘。您确定键绑定是执行此操作的唯一方法吗?不管怎样,我再谢谢你一次。 =)
猜你喜欢
  • 2011-11-25
  • 2011-08-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-07
  • 2012-06-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多