Как использовать KeyListener с JFrame?

Итак, я пытался сделать прямоугольник с KeyEvent (KeyListener) и всякий раз, когда я пытаюсь нажать клавишу, прямоугольник не двигается.

прямоугольник рисуется, но всякий раз, когда я ударил left и right ключи, ничего не происходит. У меня есть два класса, один-мой основной класс с keyEvents и frame, а другой рисует прямоугольник и держит функцию для перемещения прямоугольника.

вот мой код:

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);

}
}

а теперь второй класс:

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();
}

}

Пожалуйста, скажите мне, как я могу переместить прямоугольник. Заранее спасибо!

4 ответов


прямоугольник не движется, потому что вы не используете JFrame правильно. Вы должны назначить frame to new mainFrame() вместо того, чтобы игнорировать инстанцированный


есть по крайней мере три вопроса...

во-первых...

код mainFrame класс extends С JFrame, но в main метод, вы создаете его экземпляр и игнорируете его, создавая свой собственный JFrame.

на KeyListener зарегистрирован на экземпляр mainFrame, Что означает, что его проигнорировали.

вы должны избавиться от extends JFrame как это просто запутать вопрос

во-вторых...

KeyListener только реагируйте на ключевые события, когда компонент, на который он зарегистрирован, фокусируется и имеет прямую фокусировку, это делает его ненадежным.

вместо этого вы должны использовать API Привязок ключей С Draw панель, это позволит вам перейти к вопросам фокуса.

в-третьих...

вы сломали цепь краски, это означает, что когда прямоугольник движется, то, что было окрашено ранее, все равно останется.

вы должны воздержаться от переопределение paint и вместо того, чтобы использовать paintComponent. Для этого есть много причин, но, как правило, он рисует в фоновом режиме, называется обновлениями дочерних компонентов.

наконец, убедитесь, что вы звоните super.paintComponent прежде чем делать что-либо еще, чтобы обеспечить Graphics контекст подготовлен для рисования

посмотри Выполнение Изготовленная На Заказ Картина для более подробной информации


вы должны добавить своего слушателя в класс mainDraw, а не свой мэйнфрейм.

Это хорошая практика, чтобы не обрабатывать события клавиш и мыши в кадрах и окнах.

o/


Я пытался реализовать прослушиватели ярлыков для всего кадра и не преуспел, наконец, нашел способ. Если вы хотите установить прослушиватель даже при фокусировке на другой компонент, необходимо добавить прослушиватели ко всем компонентам.

вот мой код

вызовите это в своем конструкторе:

setShortcutListener(this); // this = JFrame when you call in in constructor

метод setShortcutListener(JFrame frame) :

private void setShortcutListener(JFrame frame) {
    List<Component> comp_list = Common.getAllComponents(frame);
    for (Component component : comp_list) {
        component.addKeyListener(getShortcutKeyListener());
    }
}

метод getAllComponents( frame); класс Common-это просто класс,

public static List<Component> getAllComponents(final Container c) {
    Component[] comps = c.getComponents();
    List<Component> compList = new ArrayList<Component>();
    for (Component comp : comps) {
        compList.add(comp);
        if (comp instanceof Container) {
            compList.addAll(getAllComponents((Container) comp));
        }
    }
    return compList;
}

способ getShortcutKeyListener ():

public static KeyListener getShortcutKeyListener() {
    KeyListener listener = new KeyListener() {

        @Override
        public void keyReleased(KeyEvent evt) {
            if (evt.getKeyCode() == KeyEvent.VK_F3) {
                // What you do when F3 key pressed
            } else if (evt.getKeyCode() == KeyEvent.VK_F2) {
                // What you do when F2 key pressed
            } 
        }

        @Override
        public void keyTyped(KeyEvent e) {
            // Do nothing
        }

        @Override
        public void keyPressed(KeyEvent e) {
            // Do nothing
        }
    };
    return listener;
}

Я думаю, что у нас есть простые способы, чем этот, но этот код работает так, как ожидалось. Ключевые слушатели работают в любой форме.

надеюсь, этот ответ поможет кому-то. Спасибо.