【问题标题】:Java Moving an Image with separate classJava使用单独的类移动图像
【发布时间】:2011-12-19 11:53:00
【问题描述】:

我正在制作一个小型的爱好游戏,到目前为止我有几节课。有两个课程我遇到了一些问题,下面列出了有问题的课程。

屏幕.Java

package geisst.flat;

import javax.imageio.ImageIO;
import javax.swing.JFrame;

import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

public class Screen extends JFrame {

public int x = 100;
public int y = 100;

public Screen() {
    this.setSize(400, 400);
    this.setTitle("Flat Game");
    this.setResizable(false);
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.setVisible(true);

    addKeyListener(new KeyListen());
}

public void paint(Graphics g) {
    BufferedImage mainImage = null;

    try {
        mainImage = ImageIO.read(new File("res/test.gif"));
    } catch(IOException e) {

    }

    g.drawImage(mainImage, x, y, null);
    repaint();
}
}

还有 KeyListen.Java

package geisst.flat;

import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

public class KeyListen extends KeyAdapter {

Screen screen;

@Override
public void keyPressed(KeyEvent e) {
    int keyCode = e.getKeyCode();

    if(keyCode == KeyEvent.VK_LEFT) {
        screen.x += 3;
    }
}

}

KeyListen 应该将 mainImage 的 x 位置向上移动 3 个像素,但我收到以下错误。

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at geisst.flat.KeyListen.keyPressed(KeyListen.java:15)
at java.awt.Component.processKeyEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Window.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.KeyboardFocusManager.redispatchEvent(Unknown Source)
at java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(Unknown Source)
at java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(Unknown Source)
at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(Unknown Source)
at java.awt.DefaultKeyboardFocusManager.dispatchEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$000(Unknown Source)
at java.awt.EventQueue$1.run(Unknown Source)
at java.awt.EventQueue$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue$2.run(Unknown Source)
at java.awt.EventQueue$2.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)

你们知道为什么会这样吗?这可能是非常明显的事情:P

提前致谢,

盖斯特

【问题讨论】:

    标签: java image swing load keylistener


    【解决方案1】:

    您永远不会初始化screen 的值。

    你可以这样做:

    KeyListener 类中

    public KeyListen (Screen screen) {
     this.screen = screen;
    }
    

    Screen 类中:

    addKeyListener(new KeyListen(this));
    

    【讨论】:

    • 非常感谢,这非常有效,对不起,如果这太明显以至于我看起来像个白痴,我还在学习这个话题。
    【解决方案2】:

    你从不初始化屏幕,所以它是空的,但你使用它的属性:

    screen.x += 3;
    

    您应该将Screen 对象的引用传递给侦听器,或者通过调用getSource

    @Override
    public void keyPressed(KeyEvent e) {
        int keyCode = e.getKeyCode();
    
        if(keyCode == KeyEvent.VK_LEFT) {
            if (e.getSource() instanceof Screen)
                ((Screen)e.getSource()).x += 3;
        }
    }
    

    【讨论】:

    • 如果我初始化屏幕会在我的屏幕上创建一个新的窗口实例吗?对不起,如果我的问题有点愚蠢。
    • 也谢谢你,这很好,我选择了 npinti 的解决方案,因为它看起来更简单,但你的也是一个很好的解决方案。
    【解决方案3】:

    1) 不好直接画到JFrame上,放JPanel、JComponent或者JLabel

    2) 对于 Swing JComponents,是否有paintComponent 而不是paint,paint 是绘制到RootPane 或GlassPane(从JFrame 派生的组件)的正确方法

    3) 使用 KeyBindings 而不是 KeyListener,因为 KeyListener 在窗口中没有焦点时不起作用,将焦点设置为 ContentPane 不是一个好主意

    4) 将 JComponent 用于 Custom PaintingJLabelIcon

    5) KeyBindings 示例here

    【讨论】:

    • 感谢您的意见,我会考虑到这一点。
    猜你喜欢
    • 2017-07-18
    • 2012-02-01
    • 2014-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-05
    • 1970-01-01
    相关资源
    最近更新 更多