【问题标题】:Java AWT - repaint() method thread schedulingJava AWT - repaint() 方法线程调度
【发布时间】:2018-07-25 12:49:14
【问题描述】:

我想做的是让用户能够从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 工作。我真的不知道该怎么办。

【问题讨论】:

  • 我不想让你失望,但这个问题与 Swing 无关,是纯粹的 AWT
  • 1) 为什么要编写小程序?如果是由于您的讲师的规范,请参考Why CS teachers should stop teaching Java applets。 2) 为什么使用 AWT 组件而不是 Swing?请参阅 this answer 了解放弃 AWT 的许多充分理由。
  • 谢谢,如果我这样做了,我并不是要标记swing,但是java 8怎么样,它比swing好吗?我应该只学那个吗? @MadProgrammer
  • @JoeD 目前还没有真正利用 Java 8,但是泛型上的菱形运算符和资源尝试是值得欢迎的。

标签: java applet awt


【解决方案1】:

我认为问题不在于您的 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

更好的解决方案是利用BufferStrategy。它仍然需要Thread,但会阻止您破坏绘画链。

作为旁注。 AWT Applets 已经过时了,在 2000 年之前被 JApplet 取代。话虽如此,我还是建议不要使用小程序,因为它们有很多问题,只会增加开始开发和专注的难度将 JPanel 之类的东西添加到 JFrame 的实例中。

看看Performing Custom PaintingCreating a GUI With JFC/Swing

我也会尽快放弃使用 KeyListener,转而使用 Swing 的键绑定 API。详情请见How to Use Key Bindings

我也避免调用你的小程序Component,已经有一个名为Component 的类,这只会让事情变得混乱......

小程序当然不应该有main 方法。它们应由浏览器直接加载,并具有不同的、已定义的生命周期。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-12-13
    • 1970-01-01
    • 1970-01-01
    • 2014-08-10
    • 1970-01-01
    • 2021-07-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多