Java KeyListener,GLEventListener不工作?
我在做这个项目,我可能和听众有问题。我认为我正确地实现了它们,但我不确定。当应用程序第一次启动时,图像被加载并显示在画布上,但若我使用“L”键加载另一个图像,它将什么也不做。有人知道是什么导致了这个问题吗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;
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()
。它第一次工作是因为initialloadImage()代码>从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();