简体   繁体   English

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

[英]Java AWT - repaint() method thread scheduling

What I am looking to do is have the user to be able to change perspectives from a KeyListener . 我想要做的是让用户能够从KeyListener更改视角。 If the user hits the specified key, than the perspective should change. 如果用户按下指定的键,则透视图应该改变。 Any ideas? 有任何想法吗?

Even if I override the methods they still do not work. 即使我重写了这些方法,它们仍然无法正常工作。 I have also tried KeyAdapter 我也尝试过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) {}

}

The program runs, but doesn't switch perspectives. 该程序将运行,但不会切换透视图。 I cannot seem to get the KeyListener to work at all. 我似乎根本无法使KeyListener正常工作。 I really have no idea what to do. 我真的不知道该怎么办。

I don't think the issue is with your KeyListener , but is with your paint process 我认为问题不在于您的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);
    }
}

This will block the Event Dispatching Thread, preventing it from ever been able to process new events coming into the system 这将阻止事件调度线程,从而使其无法处理进入系统的新事件

Take a look at Painting in AWT and Swing for details about how painting works in AWT. 看看AWT和Swing中的绘画,了解有关AWT中绘画工作原理的详细信息。

The (simple) solution, in this case, would be to provide a other Thread which handles the timing between updates and simple call repaint when you want the UI updated. 在这种情况下,(简单)解决方案将是提供另一个Thread ,该Thread在您要更新UI时处理更新和简单调用repaint之间的时间安排。

A better solution would be take take advantage of the a BufferStrategy instead. 更好的解决方案是利用BufferStrategy代替。 It still require a Thread , but stops you from breaking the painting chain. 它仍然需要一个Thread ,但是会阻止您中断绘画链。

As a side note. 作为旁注。 AWT Applet s are woefully out-of-date and were replaced by JApplet before 2000. Having said that, I would recommend against using applets at all, as they have enough problems which only increases the difficulty of starting development and focus on something like a JPanel added to an instance of a JFrame instead. AWT Applet已经过时了,并在2000年之前被JApplet取代。话虽如此,我建议不要使用Applet,因为它们有足够的问题,只会增加开始开发的难度并专注于诸如JPanel添加到JFrame的实例中。

Take a look at Performing Custom Painting and Creating a GUI With JFC/Swing 看一下使用JFC / Swing 执行自定义绘制创建GUI

I'd also drop the use of KeyListener as soon as you can in favour of Swing's Key bindings API. 我还将尽快放弃使用KeyListener ,而支持Swing的键绑定API。 See How to Use Key Bindings for more details 有关更多详细信息,请参见如何使用键绑定

I'd also avoid calling your applet Component , there already is a class called Component and this is just going to confuse matters... 我还避免调用您的applet Component ,已经有一个名为Component的类,这只会使事情变得混乱...

And applets, definitely, should not have a main method. 而且,小程序绝对不应该有main方法。 They are expected to be loaded by the browser directly and have a different, defined, life cycle. 它们应由浏览器直接加载,并具有不同的定义生命周期。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM