java - 为什么我的 Canvas 添加到我的 JFrame 后无法绘制?

标签 java swing lwjgl

我正在编写一个使用 Canvas 实例进行绘制的小游戏(以防它很熟悉;我使用游戏库 LWJGL)。 现在我已经为我的游戏创建了一个主菜单,其中包含一个 JPanel,然后我在游戏开始时将其添加到我的主游戏 JFrame 中;

Canvas canvas = new Canvas();
JFrame frame = new JFrame("Puzzler");
this.canvas = canvas;
this.jframe = frame;
canvas.setIgnoreRepaint(true);
frame.setSize(640, 480);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);

接下来,我创建主菜单:

this.mainMenuPanel = new MainMenuPanel(this.main);
this.jframe.setSize(500, 170);
this.jframe.getContentPane().add(mainMenuPanel);
this.jframe.validate();

最后,当主菜单要启动游戏时,我尝试用Canvas实例替换主菜单的JPanel:

this.jframe.setVisible(false);
this.jframe.invalidate();
this.jframe.removeAll();
this.jframe.getContentPane().add(canvas);
this.jframe.setVisible(true);
this.jframe.pack();
this.jframe.setSize(640, 480);
this.jframe.validate();

当这最后一段代码运行时,对 LWJGL 的 Display.create() 的调用返回一个错误,指出 Canvas 不可绘制。 我已经尝试了一大堆组合(比如添加一个 JPanel 作为 Canvas 的容器,没有运气),并且一直在扰乱 validate() 和 repaint() 调用的顺序,因为这有时有助于 Swing 。有谁知道这里可能是什么问题?

编辑 我已经解决了这个问题。问题原来是 java 的事件处理线程在运行主循环时卡住了,因为我在主线程上调用了 run() 而不是 start()。傻我。 :P

最佳答案

除了不混合规则,我猜你会在纯 awt 上下文中得到类似的异常 - 来自 LWJGL tutorial Basic applet :

Now that we have the basic template we need to stick the LWJGL native Display on it. To do this we simply use the Display.setParent(Canvas) method. However before we can create the Display we need to make sure that the canvas is ready to be drawn on. To ensure this we will use the addNotify() method of the awt canvas to tell us when the canvas is ready and that we can create the Display. Similarly we will use the removeNotify() to inform us that the canvas is about to be destroyed and we should clean up and close the native Display.

编辑

(手边仍然没有 IDE,只是从我的头顶开始;-)

实际上,我不太明白你用 removeXX 做了什么,不希望有任何需要。起初,我会保持简单,并完全按照教程中所示:

 display_parent = new Canvas() {
    public final void addNotify() {
       super.addNotify();
       startLWJGL();
    }
    public final void removeNotify() {
      stopLWJGL();
      super.removeNotify();
    }
 };
 frame.add(display.parent);

另外确保所有更改都发生在 EDT - 这可能是真正的问题,不知道 Display 在这些方法中实际做了什么:

 public void gameLoop() {
     while(running) {
         SwingUtilities.invokeLater(new Runnable() {
             public void run() {
                 Display.sync(60);
                 Display.update();
             }
         });
    }

    Display.destroy();
 }      

编辑2

只需在 JFrame 中运行示例(在上面引用的教程中),无需更改现有代码,只需添加一个 main:

    public static void main(String[] args) {
        final JFrame frame = new JFrame("Gears AWT");

        final JPanel intro = new JPanel();
        Action action = new AbstractAction("Start Gears") {

            @Override
            public void actionPerformed(ActionEvent e) {
                GearsApplet gears = new GearsApplet();
                gears.init();
                frame.remove(intro);
                frame.add(gears);
                frame.getRootPane().revalidate();
            }
        };
        JButton button = new JButton(action);
        intro.add(button);
        frame.add(intro); //.display_parent);
        frame.setSize(200, 200);
        frame.setVisible(true);
    }

感觉还好(初步估计,怀疑有一些魔鬼隐藏在线程的黑暗壁龛中 - 因为我们在美国东部时间(很可能)),齿轮正在运行并且组可旋转

关于java - 为什么我的 Canvas 添加到我的 JFrame 后无法绘制?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8193000/

相关文章:

java - 制作《我的世界》模组。编译错误

java - 找不到 key 时,java.util.Collections.binarySearch 返回值背后的原因是什么?

java - 如何使用 JPA 更新带有 Google App Engine Java 的实体?

java - 在内存中存储等距网格的最佳方法是什么?

java - ComponentAdapter 中 componentResized 方法的任何替代方法

java - glsl 中的操作 '*' 类型错误?

opengl - 菜鸟问题: Draw a quad parallel to the view

Java:如何检查输入的第一个字符是否== x

java - 获得不同系列具有相同的颜色

Java JTable 不显示 MySQL 中的所有行