KeyHandler не отвечает на ключевые события

1

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

Я создал класс, который реализует KeyListener и переопределяет функции. Затем я создал экземпляр нового класса и добавил обработчик к JPanel и JFrame. Все еще нет кубиков

public class main_program extends JFrame {

    private int mX_cord, mY_cord,prior_selected_vertex, current_selected_vertex;
    private int verticies_to_edge1, verticies_to_edge2;
    private int radius =10;
    private boolean vertex_selected1 = false, vertex_selected2 = false, edge_ready = false,delete_vertex_ready = false;
    private Edge tempEdge = null;
    private ArrayList<Integer> vertex_xcord = new ArrayList<Integer>();
    private ArrayList<Integer> vertex_ycord = new ArrayList<Integer>();
    private ArrayList<Edge> edge = new ArrayList<Edge>();

    HandlerMouse handler = new HandlerMouse();
    HandlerKey keyhand = new HandlerKey();

    private JPanel masterPanel;
    private JTextArea masterTextArea;
    private JScrollPane masterScrollPane;
    private Point point1, point2;
    Graphics g;

    public main_program(){

        setTitle("Graph");
        setSize(600, 400);
        setDefaultCloseOperation(new JFrame().EXIT_ON_CLOSE);
        //this must be set for custom layout of components
        setLayout(null);

        masterPanel = new JPanel();
        masterPanel.setSize(600,300);
        masterPanel.setLocation(0, 0);
        masterPanel.setBackground(Color.WHITE);
        masterPanel.addMouseListener(handler);
        masterPanel.addMouseMotionListener(handler);
        masterPanel.addKeyListener(keyhand);

        masterTextArea = new JTextArea();
        masterTextArea.setBackground(Color.green);

        masterScrollPane = new JScrollPane();
        masterScrollPane.add(masterTextArea);
        masterScrollPane.setSize(600, 100);
        masterScrollPane.setLocation(0, 300);
        masterScrollPane.addMouseListener(handler);
        masterScrollPane.addMouseListener(handler);
        masterScrollPane.addKeyListener(keyhand);

        add(masterPanel);
        add(masterScrollPane);
        setLocationRelativeTo(null);
        setVisible(true);

    }

    public void paint(Graphics g){  
        super.paint(g);
        for(int i = 0 ; i < vertex_xcord.size(); i++){
            g.fillOval(vertex_xcord.get(i), vertex_ycord.get(i), radius, radius);
        }
        for(int i = 0 ; i<edge.size(); i++){
            tempEdge = edge.get(i);
            g.drawLine(vertex_xcord.get(tempEdge.vertex1), vertex_ycord.get(tempEdge.vertex1), vertex_xcord.get(tempEdge.vertex2), vertex_ycord.get(tempEdge.vertex2));
        }
        //g.fillOval(mX_cord, mY_cord, radius, radius);
        //repaint();
    }

    private class HandlerKey implements KeyListener{
        public void keyPressed(KeyEvent evt){
            System.out.println("key pressed");
            if(evt.getKeyCode() == KeyEvent.VK_ENTER && edge_ready){
                edge.add(new Edge(prior_selected_vertex, current_selected_vertex));
                edge_ready = false;
                repaint();
            }
        }
        public void keyReleased(KeyEvent evt){
            System.out.println("key rel");
        }
        public void keyTyped(KeyEvent evt){
            System.out.println("key type");
        }
    }
    private class HandlerMouse implements MouseListener, MouseMotionListener{

        public void mouseClicked(MouseEvent evt){
            mX_cord = evt.getX()-5;
            mY_cord = evt.getY()+15;
            if( evt.getClickCount() == 1){
                //mX_cord = evt.getX();
                //mY_cord = evt.getY();
                vertex_xcord.add(mX_cord);
                vertex_ycord.add(mY_cord);
                repaint();
            }
            else{
                for(int i = 0 ; i < vertex_xcord.size(); i++){
                    if(Math.abs(vertex_xcord.get(i) - mX_cord ) < 15 && Math.abs(vertex_ycord.get(i) - mY_cord ) < 15 ){
                        if(vertex_selected1 == false){
                            prior_selected_vertex = i;
                            vertex_selected1 = true;
                        }
                        else{
                            current_selected_vertex = i;
                            vertex_selected2 = true;
                        }
                        System.out.println("YOU HAVE SELECTED A VERTEX: " + i);
                        break;
                    }
                }
            }
            if(vertex_selected2 == true){
                edge_ready = true;
                verticies_to_edge1 = prior_selected_vertex;
                verticies_to_edge2 = current_selected_vertex ;
                vertex_selected1 = vertex_selected2 = false;
                System.out.println("Ready for edge!");
            }
            else{
                delete_vertex_ready = true;
            }
        }

        public void mouseEntered(MouseEvent arg0) 
        {   
        }

        public void mouseExited(MouseEvent arg0) 
        {
        }

        public void mousePressed(MouseEvent evt) 
        {
        }

        public void mouseReleased(MouseEvent arg0) 
        {
        }

        public void mouseDragged(MouseEvent e) 
        {
        }

        public void mouseMoved(MouseEvent e) 
        {
        }
    }

    class Edge {
        int vertex1, vertex2;
        public Edge(int v1, int v2){
            vertex1 = v1;
            vertex2 = v2;
        }
    }

    public static void main(String[] args){
        main_program circle = new main_program();
    }
}
Теги:
swing
jframe
keylistener

1 ответ

5
Лучший ответ

У вас есть несколько проблем с этой программой, и это говорит о том, что вам будет полезно прочитать многие вопросы и ответы Swing на этом сайте, потому что эти проблемы (и ваша основная проблема) довольно распространены, и решения часто публикуются.

Что касается вашей основной проблемы, проблема снова очень распространена: KeyListeners работают только в том случае, если прослушиваемый компонент имеет фокус. Если он теряет фокус или не фокусируется, вам не повезло. Лучшим решением является не использование KeyListener, а более высокий уровень и более гибкие привязки клавиш. Для этого Google найдет для вас учебники.

Что касается других проблем с вашим кодом:

  • Вы используете нулевой макет, макет, который приводит к негибкому графическому интерфейсу, который очень сложно обновить и улучшить, и это выглядит ужасно на всех, кроме вашей текущей платформы и разрешения экрана. Решение: изучите и используйте менеджеров компоновки.
  • Вы рисуете непосредственно в методе JFrame paint(Graphics g), который имеет риски, поскольку вы рискуете испортить картину любого из компонентов JFrame, выполнив это. Гораздо лучше использовать метод JPanel paintComponent(Graphics g) и получить выгоду от графики Swing (а не AWT), включая автоматическую двойную буферизацию.
  • В вашем классе есть переменная Graphics, g, которая предполагает, что вы рассматриваете использование сохраненного объекта Graphics либо из компонента, либо из JVM. Это увеличивает риск того, что ваша программа выбрасывает исключение NullPointerException, если этот объект Graphics больше не существует, либо это, либо рисунок с ним, но и не видит никакого эффекта. Решение: используйте метод рисования (опять же лучше с помощью метода JComponent paintComponent) или с объектом Graphics из BufferedImage.
  • Вы добавляете MouseListener непосредственно в JPanel, но рисуете другой компонент, JFrame и, делая это без учета вставки, ставят точки в неправильном месте. Используйте MouseListener на том же компоненте, на котором вы рисуете.

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

  • 2
    @ user3044571 JFrame не подходит для KeyListener
  • 0
    @mKorbel: замечательно, спасибо!
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню