web-dev-qa-db-ja.com

JFrameでKeyListenerを使用する方法

したがって、KeyEventKeyListener)を使用して四角形を移動させようとしていましたが、キーを押すと四角形が移動しません。

長方形が描かれますが、leftキーとrightキーを押すたびに何も起こりません。私は2つのクラスを持っています。1つはkeyEventsとフレームを含むメインクラスで、もう1つは長方形を描画し、長方形を移動する関数を保持しています。

これが私のコードです:

import Java.awt.event.KeyEvent;
import Java.awt.event.KeyListener;

import javax.swing.JFrame;


public class mainFrame extends JFrame implements KeyListener{

mainDraw Draw = new mainDraw();

public void keyPressed(KeyEvent e) {

    int key = e.getKeyCode();

    if(key == KeyEvent.VK_D){

        Draw.moveRight();
    }
}

public void keyReleased(KeyEvent e) {


}
public void keyTyped(KeyEvent e) {}

public mainFrame()
{
    addKeyListener(this);
    setFocusable(true);
    setFocusTraversalKeysEnabled(false);
}

public static void main(String[] args) {

    mainFrame M1 = new mainFrame();

    mainDraw Draw = new mainDraw();

    JFrame frame = new JFrame("Square Move Practice");


    //frame
    frame.setVisible(true);
    frame.setResizable(false);
    frame.setSize(600, 600);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.getContentPane().add(Draw);

}
}

そして今、2番目のクラス:

import Java.awt.Color;
import Java.awt.Graphics;

import javax.swing.JComponent;

public class mainDraw extends JComponent{

public int x = 50;
public int y = 50;

public void Paint(Graphics g){

    g.drawRect(x, y, 50, 50);
    g.fillRect(x, y, 50, 50);
    g.setColor(Color.BLACK);
}

public void moveRight()
{
    x = x + 5;
    y = y + 0;
    repaint();
}

}

長方形を移動する方法を教えてください。前もって感謝します!

12
user3183679

JFrameを正しく使用していないため、長方形は移動していません。インスタンス化されたframeオブジェクトを無視する代わりに、mainFramenew mainFrame()に割り当てる必要があります。

@MadProgrammerが指摘するように、他にもいくつかの問題があります。

以下は、いくつかの問題を修正するコードです。

mainFrame.Java

import Java.awt.*;
import Java.awt.event.KeyEvent;
import Java.awt.event.KeyListener;
import javax.swing.JFrame;


public class mainFrame extends JFrame implements KeyListener{
    private mainDraw draw;

    public void keyPressed(KeyEvent e) {
        System.out.println("keyPressed");
    }

    public void keyReleased(KeyEvent e) {
        if(e.getKeyCode()== KeyEvent.VK_RIGHT)
            draw.moveRight();
        else if(e.getKeyCode()== KeyEvent.VK_LEFT)
            draw.moveLeft();
        else if(e.getKeyCode()== KeyEvent.VK_DOWN)
            draw.moveDown();
        else if(e.getKeyCode()== KeyEvent.VK_UP)
            draw.moveUp();

    }
    public void keyTyped(KeyEvent e) {
        System.out.println("keyTyped");
    }

    public mainFrame(){
        this.draw=new mainDraw();
        addKeyListener(this);
        setFocusable(true);
        setFocusTraversalKeysEnabled(false);
    }

    public static void main(String[] args) {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                mainFrame frame = new mainFrame();
                frame.setTitle("Square Move Practice");
                frame.setResizable(false);
                frame.setSize(600, 600);
                frame.setMinimumSize(new Dimension(600, 600));
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.getContentPane().add(frame.draw);
                frame.pack();
                frame.setVisible(true);
            }
        });
    }
}

mainDraw.Java

import Java.awt.Color;
import Java.awt.Graphics;
import javax.swing.JComponent;

public class mainDraw extends JComponent {

    public int x = 50;
    public int y = 50;

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.drawRect(x, y, 50, 50);
        g.fillRect(x, y, 50, 50);
        g.setColor(Color.BLACK);
    }

    public void moveRight() {
        x = x + 5;
        repaint();
    }

    public void moveLeft() {
        x = x - 5;
        repaint();
    }

    public void moveDown() {
        y = y + 5;
        repaint();
    }

    public void moveUp() {
        y = y - 5;
        repaint();
    }
}

ところで、swingオブジェクトはスレッドセーフではないため、SwingUtilitiesを使用してGUI更新コードを配置します。

7
user508434

少なくとも3つの問題があります...

まず...

mainFrameからのextendsクラスJFrameですが、mainメソッドでは、独自のJFrame

KeyListenermainFrameのインスタンスに登録されているため、無視されます。

extends JFrameは問題を混乱させるだけなので、取り除く必要があります。

第二に...

KeyListenerは、登録されているコンポーネントがフォーカス可能で直接フォーカスがある場合にのみ、キーイベントに応答します。これにより、信頼性が低くなります。

代わりに、Drawパネルで key bindings API を使用する必要があります。これにより、フォーカスの問題を克服できます。

第三に...

ペイントチェーンを壊しました。つまり、長方形が移動しても、以前にペイントされたものが残ります。

Paintを上書きせずに、代わりにpaintComponentを使用してください。これには多くの理由がありますが、通常はバックグラウンドでペイントされ、子コンポーネントの更新と呼ばれます。

最後に、他のことをする前にsuper.paintComponentを呼び出していることを確認し、Graphicsコンテキストがペイント用に準備されていることを確認します

詳細については、 カスタムペイントの実行 を参照してください。

6
MadProgrammer