KeyHandler没有响应keyevents

时间:2014-03-29 19:32:43

标签: java swing jframe keylistener

我正在尝试设置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();
    }
}

1 个答案:

答案 0 :(得分:5)

您在该计划中遇到了一些问题,并且它表明您可以阅读本网站上的许多Swing Q&amp; A,因为这些问题(以及您的主要问题) (问题)很常见,经常发布解决方案。

关于你的主要问题,问题再次出现很常见:KeyListeners仅在被侦听组件具有焦点时才起作用。如果它失去焦点或无法集中注意力,那么你运气不好。最好的解决方案通常不是使用KeyListener,而是使用更高级别和更灵活的Key Bindings。 Google会为您找到适合您的教程。

至于您的代码的其他问题:

  • 您使用的是null布局,这种布局导致GUI不灵活,升级和增强非常困难,而且除了您当前的平台和屏幕分辨率之外,它看起来很糟糕。解决方案:研究和使用布局管理器。
  • 您正在直接绘制JFrame的paint(Graphics g)方法,这样做有风险,因为您可能会通过这样做弄乱任何和所有JFrame成员的绘画。使用JPanel的paintComponent(Graphics g)方法绘制更好,并获得Swing(而不是AWT)图形的好处,包括自动双缓冲。
  • 您的类有一个Graphics变量g,这表明您正在考虑从组件或JVM中使用存储的Graphics对象。这会增加程序在该Graphics对象不再存在时抛出NullPointerException的风险,无论是该对象还是使用它绘制但没有看到任何效果。解决方案:仅在绘制方法内绘制(再次使用JComponent&#39; s paintComponent方法更好),或者使用BufferedImage中的Graphics对象。
  • 您正在将一个MouseListener直接添加到JPanel但是正在绘制一个不同的组件JFrame,并且这样做而不考虑插入,将点放在错误的位置。在您正在绘制的同一组件上使用MouseListener。

再次,请在这里查看,因为我认为您会在本网站上找到许多可以用来增强您的计划的宝藏。