如何将opengl显示附加到JFrame并正确处理?

时间:2014-10-05 04:07:30

标签: java swing opengl jframe lwjgl

如何将OpenGl显示附加到JFrame,以便在关闭JFrame时会破坏显示?到目前为止,这是我的代码:

package test.core;


import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Component;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;

import static org.lwjgl.opengl.GL11.*;

public class Main {



    private static CreateCanvas canvas;
    private static CreateFrame frame;

    private static int width = 800;
    private static int height = 600;

    public static void main(String[] args) throws InterruptedException {
        startFrames();

        startDisplay();

    }

    public static void cleanUp() {
        Display.destroy();
    }

    private static void startDisplay() {
        try
        {
            Display.setParent(canvas);
            Display.create();
        }catch(LWJGLException ex)
        {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    private static void startFrames()
    {
        Runnable r = new Runnable(){
            @Override
            public void run(){
                frame = new CreateFrame();
                JButton button = new JButton("BUTTON");
                canvas = new CreateCanvas();
                JPanel panel = frame.panel;

                panel.add(canvas);
                panel.add(button);
                frame.add(panel);

                canvas.setSize(300, 300);
                frame.setSize(width, height);

                frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);

                WindowListener listen = new WindowAdapter(){
                    @Override
                    public void windowClosing(WindowEvent we){
                        int result = JOptionPane.showConfirmDialog(frame, "Do you want to quit the Application?");
                        if(result == JOptionPane.OK_OPTION){
                            frame.setVisible(false);
                            cleanUp();
                            frame.dispose();
                        }
                    }
                };

                frame.addWindowListener(listen);


                frame.setVisible(true);
            }

        };
        SwingUtilities.invokeLater(r);
    }

}

在我执行runnable之前,我已将opengl显示附加到JFrame。但是在添加了runnable后,显示屏现在显示的尺寸与我的屏幕尺寸相同。我试过重新排列

canvas.setSize();

frame.setSize();

但没有任何改变,opengl显示仍然是相同的大小,当我尝试先关闭JFrame而不是先关闭显示我得到这个错误:

Exception in thread "AWT-EventQueue-0" java.lang.IllegalStateException: From thread Thread[AWT-EventQueue-0,6,main]: Thread[main,5,main] already has the context current

指向我的

Display.destroy();

我猜是在告诉我,我没有正确处理显示器?任何人都可以帮我将opengl显示附加到JFrame并修复上面的错误吗?

1 个答案:

答案 0 :(得分:1)

看来您在“主”线程中启动了显示(它为主线程提供了当前的OpenGL上下文),但是您试图从不同的线程中销毁显示,在这种情况下是事件调度线程(EDT)。 但是,在给定时间只有一个线程可以拥有当前的OpenGL上下文。

虽然可以改变哪个线程具有当前上下文,但我认为这不是你想要做的。

我们在这里要做的是在我们创建它的同一个线程(具有当前OpenGL上下文的线程)上销毁显示。我见过的approach是使用在EDT上运行的Canvas的{​​{1}})和addNotify(方法来设置已检查的标记OpenGL线程确定何时销毁显示。

此外,该问题还提到了有关设置显示尺寸的问题。由于setSize()和LayoutManager的工作方式,您的JFrame显示大小和显示大小未设置为您所需的大小。有关详细信息,请参阅Java tutorials和文档。在下面的示例中,我使用了一种方法来解决此问题。

所以这里有一个例子,试图接近问题中发布的代码的意图:

removeNotify()

注意:这个示例是使用lwjgl版本2.9.1测试的,因为它似乎是最初发布问题时可用的最新版本。