【问题标题】:Button not displaying in applet小程序中不显示按钮
【发布时间】:2012-10-01 14:35:15
【问题描述】:

以下是我的小程序游戏的浓缩代码:

import java.applet.Applet;
import java.awt.event.*;
import java.awt.*;

public class Game extends Applet implements KeyListener, Runnable {
    Button options = new Button("Options");
    Thread thread = new Thread(this);

    public void init() {
        addKeyListener(this);
        thread.start();
    }

    public void paint(Graphics graphics) {
        // draw stuff
    }

    public void run() {
        try {
            while (true) {
                thread.sleep(40);
                repaint();
            }
        } catch (InterruptedException exception) {}
    }

    public void keyPressed(KeyEvent keyEvent) {
        switch (keyEvent.getKeyCode()) {
        case KeyEvent.VK_ESCAPE:
            // pause game
            add(options);
        }
    }

    public void keyReleased(KeyEvent keyEvent) {}
    public void keyTyped(KeyEvent keyEvent) {}
}

我的游戏按预期运行。但是,当用户按下Esc 时,我想暂停游戏并显示一个选项按钮。

问题是当我按下Esc 时,它会按预期暂停游戏。但是它不会在屏幕上显示按钮。我试图寻找解决方案无济于事。到底发生了什么?

【问题讨论】:

  • 您使用的是什么布局管理器?你的绘画方法是做什么的?你打电话给super.paint?另外,我个人会认真考虑使用基于 Swing 的 AWT 组件...
  • 我正在使用BorderLayout。但是,即使我使用任何其他布局,它仍然不会显示按钮。
  • 你的画法是什么?它是否调用super.paint
  • 没有。它不调用super.paint。应该这样吗?
  • 另见Initial Threads,applet 中也需要。

标签: java applet awt keylistener runnable


【解决方案1】:

对我来说非常好用......

public class TestApplet02 extends Applet implements KeyListener, Runnable {

    Button options = new Button("Options");
    Thread thread = new Thread(this);
    int y = 0;

    public void init() {
        thread.start();
    }

    @Override
    public void start() {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                setLayout(new BorderLayout());
                addKeyListener(TestApplet02.this);
            }
        });
    }

    public void paint(Graphics graphics) {
        super.paint(graphics);
        Graphics2D g2d = (Graphics2D) graphics;
        y++;
        if (y > getHeight()) {
            y = 0;
        }
        g2d.drawLine(0, y, getWidth(), y);
    }

    public void run() {
        try {
            while (true) {
                thread.sleep(40);
                SwingUtilities.invokeLater(new Runnable() {
                    @Override
                    public void run() {
                        repaint();
                    }
                });
            }
        } catch (InterruptedException exception) {
        }
    }

    public void keyPressed(KeyEvent keyEvent) {
        switch (keyEvent.getKeyCode()) {
            case KeyEvent.VK_ESCAPE:
                // pause game
                add(options);
                invalidate();
                revalidate();
        }
    }

    public void keyReleased(KeyEvent keyEvent) {
    }

    public void keyTyped(KeyEvent keyEvent) {
    }
}

来自 TrashGod 提供的链接...

在小程序中,必须从 init 启动 GUI 创建任务 使用invokeAndWait的方法;否则,init 可能会在 GUI 之前返回 已创建,这可能会导致 Web 浏览器启动 小程序。在任何其他类型的程序中,调度 GUI 创建任务 通常是初始线程做的最后一件事,所以它不会 不管是使用 invokeLater 还是 invokeAndWait。

更新

我遇到的主要问题是:

在您的转义键处理程序中,如果方向为 0,则暂停选项将永远不会激活...

case KeyEvent.VK_ESCAPE:
    direction = -direction;

    if (direction < 0) {
        add(options);
    } else {
        remove(options);
    }

我不得不打电话给revalidate...

invalidate();
revalidate();
repaint();

【讨论】:

  • 使用SwingUtilities,有什么帮助?
  • 所有 UI 更新必须在事件调度线程的上下文中执行。我运行的第一个测试在没有它们的情况下运行良好,但因为我是一名 Swing 开发人员,所以我从不修改来自另一个线程的 UI 组件。
  • 好的。另一个问题 - 为什么要设置布局并在 start 而不是 init 中添加关键侦听器? start 方法可能会被多次调用。
  • 没有任何原因,只是想看看它是否有所作为。
  • 事实上,你应该交换initstart 方法的内容。 init 应该用于“准备”您的小程序,start 用于告诉您浏览器已请求小程序“启动”它的工作...
猜你喜欢
  • 2017-05-10
  • 2013-12-09
  • 2022-01-11
  • 2015-08-17
  • 1970-01-01
  • 2021-10-15
相关资源
最近更新 更多