Java AWT - repaint()方法线程调度

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java AWT - repaint()方法线程调度相关的知识,希望对你有一定的参考价值。

我要做的是让用户能够从KeyListener更改透视图。如果用户点击指定的键,则视角应该更改。有任何想法吗?

即使我覆盖了这些方法,它们仍然无效。我也试过KeyAdapter

package com.development.gameOne.environment.component;

import java.applet.Applet;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;

import com.development.gameOne.environment.applet.drawing.Perspective;
import com.development.gameOne.environment.applet.perspectives.p1.FirstPerspective;
import com.development.gameOne.environment.applet.perspectives.p2.SecondPerspective;

public class Component extends Applet implements KeyListener {

    private static final long serialVersionUID = 1L;
    private Dimension size = new Dimension(1280, 720);

    private ArrayList<Perspective> perspectives = new ArrayList<Perspective>();
    private boolean running = true;
    private boolean switchPerspective = false;

    public Component() {
        setPreferredSize(size);
        loadPerspectives();
        addKeyListener(this);
        setFocusable(true);
        setVisible(true);
        start();
    }

    private void loadPerspectives() {
        perspectives.add(new FirstPerspective());
        perspectives.add(new SecondPerspective());
    }

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

    @Override
    public void paint(Graphics g) {
        while (running) {
            for (Perspective p : perspectives) {
                System.out.println(p.getPerspective());
                while (!switchPerspective) {
                    System.out.println("Rendering");
                    p.start(g);
                    sleep(100);
                }
                switchPerspective = false;
            }
            sleep(10);
        }
    }

    public static void sleep(int renderSpeed) {
        try {
            Thread.sleep(renderSpeed);
        }
        catch (Exception e) {}
    }

    public void keyPressed(KeyEvent e) {
        switch(e.getKeyCode()){
        case KeyEvent.VK_SHIFT:
            System.out.println("KeyPressed");
            switchPerspective = true;
            break;
        }
    }



    public void keyTyped(KeyEvent e) { }

    public void keyReleased(KeyEvent e) {}

}

程序运行,但不切换透视图。我似乎无法让KeyListener工作。我真的不知道该怎么做。

答案

我认为问题不在于你的KeyListener,而在于你的油漆工艺

@Override
public void paint(Graphics g) {
    while (running) {
        for (Perspective p : perspectives) {
            System.out.println(p.getPerspective());
            while (!switchPerspective) {
                System.out.println("Rendering");
                p.start(g);
                sleep(100);
            }
            switchPerspective = false;
        }
        sleep(10);
    }
}

这将阻止事件调度线程,阻止它能够处理进入系统的新事件

看看Painting in AWT and Swing有关绘画如何在AWT中运作的详细信息。

在这种情况下,(简单)解决方案是提供另一个Thread,当您想要更新UI时,它处理更新和简单调用repaint之间的时间。

更好的解决方案是利用a BufferStrategy代替。它仍然需要一个Thread,但阻止你打破绘画链。

作为旁注。 AWT Applets可悲地过时了,并在2000年之前被JApplet取代。话虽如此,我建议不要使用applet,因为他们有足够的问题只会增加开始开发的难度并专注于像JPanel这样的东西添加到JFrame的实例。

看看Performing Custom PaintingCreating a GUI With JFC/Swing

我也会尽快放弃使用KeyListener来支持Swing的Key bindings API。有关详细信息,请参阅How to Use Key Bindings

我也避免打电话给你的applet Component,已经有一个名为Component的课程,这只会让事情变得混乱......

而applet肯定不应该有main方法。它们应该由浏览器直接加载并具有不同的,定义的生命周期。

以上是关于Java AWT - repaint()方法线程调度的主要内容,如果未能解决你的问题,请参考以下文章

使用线程 repaint() 组件

repaint 导致 mouseListener 注册没有发生的点击

Java JPanel中,repaint(),paint(),方法的区别?

Java - 方法 repaint() 不调用 paintComponent() 方法

Java多线程02

Java 中的 repaint() 方法在翻译后不会重新绘制我的 Rectangle