Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/379.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java KeyListener,GLEventListener不工作?_Java_Image_Opengl_Loading - Fatal编程技术网

Java KeyListener,GLEventListener不工作?

Java KeyListener,GLEventListener不工作?,java,image,opengl,loading,Java,Image,Opengl,Loading,我在做这个项目,我可能和听众有问题。我认为我正确地实现了它们,但我不确定。当应用程序第一次启动时,图像被加载并显示在画布上,但若我使用“L”键加载另一个图像,它将什么也不做。有人知道是什么导致了这个问题吗 public class Listener extends JFrame implements GLEventListener, KeyListener { private static final long serialVersionUID = 1L; int w, h;

我在做这个项目,我可能和听众有问题。我认为我正确地实现了它们,但我不确定。当应用程序第一次启动时,图像被加载并显示在画布上,但若我使用“L”键加载另一个图像,它将什么也不做。有人知道是什么导致了这个问题吗

public class Listener extends JFrame implements GLEventListener, KeyListener {
    private static final long serialVersionUID = 1L;
    int w, h;
    String path;
    BufferedImage bufferedImage;
    ByteBuffer byteBuffer;
    GL2 gl;    
    static JFrame frame = new JFrame();
    static JFileChooser fc = new JFileChooser();

    public static void main(String[] args) {
        GLProfile glp = GLProfile.getDefault();
        GLCapabilities caps = new GLCapabilities(glp);
        GLCanvas canvas = new GLCanvas(caps);  
        frame.setSize(300, 300);
        frame.getContentPane().add(canvas);
        frame.setVisible(true);

        frame.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });      
        canvas.addGLEventListener(new Listener());     
        canvas.addKeyListener(new Listener());

        FPSAnimator animator = new FPSAnimator(canvas, 60);
        animator.start();
    }

    public void loadImage(){
        try {
            FileNameExtensionFilter filter = new FileNameExtensionFilter("Obrázky",
                    "jpg", "jpeg", "png", "bmp", "JPG", "JPEG", "PNG", "BMP");
            fc.addChoosableFileFilter(filter);
            fc.showOpenDialog(null);
            path = fc.getSelectedFile().getAbsolutePath();  
            bufferedImage = ImageIO.read(new FileInputStream(path));    

            w = bufferedImage.getWidth();
            h = bufferedImage.getHeight();
        } 
        catch (IOException e) {
            System.err.println("Error: " + e);
        }       
    }

    @Override
    public void init(GLAutoDrawable drawable) {
        loadImage();
    }

    @Override
    public void display(GLAutoDrawable drawable) {
        WritableRaster raster = Raster.createInterleavedRaster(
                DataBuffer.TYPE_BYTE, w, h, 4, null);
        ComponentColorModel colorModel = new ComponentColorModel(
                ColorSpace.getInstance(ColorSpace.CS_sRGB), new int[] { 8, 8,
                        8, 8 }, true, false, ComponentColorModel.TRANSLUCENT,
                DataBuffer.TYPE_BYTE);
        BufferedImage image = new BufferedImage(colorModel, raster, false, null);

        Graphics2D g = image.createGraphics();
        g.drawImage(bufferedImage, null, null);
        DataBufferByte dataBuf = (DataBufferByte) raster.getDataBuffer();
        byte[] imageRGBA = dataBuf.getData();
        byteBuffer = ByteBuffer.wrap(imageRGBA);
        byteBuffer.position(0);
        byteBuffer.mark();

        gl = drawable.getGL().getGL2();  
        gl.glClear(GL.GL_COLOR_BUFFER_BIT);
        gl.glEnable(GL.GL_BLEND);

        gl.glMatrixMode(GL2.GL_PROJECTION);
        gl.glLoadIdentity();
        gl.glOrtho(0, w, h, 0, 0, 1);
        gl.glMatrixMode(GL2.GL_MODELVIEW);
        gl.glLoadIdentity();
        gl.glDisable(GL.GL_DEPTH_TEST);
        gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
        gl.glClear(GL.GL_COLOR_BUFFER_BIT);
        gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA);
        gl.glEnable(GL.GL_BLEND);

        gl.glBindTexture(GL.GL_TEXTURE_2D, 1);
        gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, 1);
        gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, GL2.GL_CLAMP);
        gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, GL2.GL_CLAMP);
        gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER,
                GL.GL_LINEAR);
        gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER,
                GL.GL_LINEAR);
        gl.glTexEnvf(GL2.GL_TEXTURE_ENV, GL2.GL_TEXTURE_ENV_MODE, GL.GL_REPLACE);
        gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGBA, w, h, 0, GL.GL_RGBA,
                GL.GL_UNSIGNED_BYTE, byteBuffer);
        gl.glEnable(GL.GL_TEXTURE_2D);
        gl.glBindTexture(GL.GL_TEXTURE_2D, 1);
        gl.glBegin(GL2.GL_POLYGON);

        gl.glTexCoord2d(0, 0); 
        gl.glVertex2d(0, 0);
        gl.glTexCoord2d(1, 0); 
        gl.glVertex2d(w, 0);
        gl.glTexCoord2d(1, 1); 
        gl.glVertex2d(w, h);
        gl.glTexCoord2d(0, 1); 
        gl.glVertex2d(0, h);
        gl.glEnd();

        gl.glFlush();
    }

    public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_L)  
            loadImage();
    }

    public void reshape(GLAutoDrawable drawable, int x, int y, int width,
            int height) {

    }

    public void dispose(GLAutoDrawable drawable) {

    }

    public void keyTyped(KeyEvent e) {

    }

    public void keyReleased(KeyEvent e) {

    }
}

您可能打算将现有的
Listener
实例添加为侦听器,但现在使用的是新实例。尝试更改:

canvas.addKeyListener(new Listener());
致:

编辑

我认为关键侦听器不起作用。但是,
GLEventListener
listener有一个问题。未显示图像的问题是,
GLEventListener
在另一个
Listener
实例上注册。图像已加载,但在不同(不可见)帧上调用了
display()
。它第一次工作是因为initial
loadImage()
init()
执行

实际上,为不同的任务分配并注册了三个帧。尝试摆脱静态框架来简化事情。例如,添加构造函数:

public Listener() {
    GLProfile glp = GLProfile.getDefault();
    GLCapabilities caps = new GLCapabilities(glp);
    GLCanvas canvas = new GLCanvas(caps);  
    setSize(300, 300);
    add(canvas);
    setVisible(true);

    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    canvas.addGLEventListener(this);     
    canvas.addKeyListener(this);

    FPSAnimator animator = new FPSAnimator(canvas, 60);
    animator.start();
}
main
重构为:

public static void main(String[] args) {
    new Listener();
}
并摆脱静态帧:

//static JFrame frame = new JFrame();

断章取义地看这段代码,我看到的主要错误是它是一个JFrame,所有人都认为它在大多数情况下是好的,出于某种原因,在某些个人经验的情况下,我注意到它可能会导致侦听器出于某种原因而无法正常工作。由于您不使用任何JComponents,所以应该可以很好地转换为普通框架,这只是您问题的一个简单解决方案


如果loadIamge()中没有try-catch的输出,这是非常有可能的,因为这意味着我可能从未调用过,测试这一点的一个好方法可能就是out.println(“我被调用了吗?”);在方法内部。这通常是一个很好的调试实践。

遗憾的是,这是不可能的,因为在java中,我不能在静态方法(静态上下文)中使用它frame.addKeyListener(此)”正在工作,但我一点击窗口,frame就会失去焦点(焦点现在有画布)并且不再侦听。@Hefatel如果需要,您可以删除
静态
,查看上次编辑是否有帮助。谢谢,这帮助很大。顺便说一句,此代码不符合GL3。您从未在任何时候调用
glGenTextures(…)
,您只需假设您可以绑定一个名为1的纹理并让GL为您创建它。在GL3之前,这是可以接受的,但是兼容的实现不应该以这种方式工作。谢谢,你是对的,从JFrame到Frame的更改是解决方案。
//static JFrame frame = new JFrame();