JFrame MouseListener不起作用

时间:2014-06-06 18:05:11

标签: java swing jframe mouselistener

我有一个小程序,它是JFrame的子类。代码如下:

package complexviewer;  

import java.awt.*;  
import java.awt.event.*;    
import java.util.concurrent.*;  
import static java.util.concurrent.TimeUnit.*;  
import javax.swing.*;   

public class Applet extends JFrame {    

    // Window and applet stats  
    public static final int windowSize = 400;   
    public static final int updateDelay = 20;   

    // Instance variables   
    private ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);   

    public static void main(String[] args) {    
        new Applet();   
    }   
    public Applet() {   
        // Set up window    
        super("Complex Viewing Frame"); 
        setSize(windowSize, windowSize);    
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

        setVisible(true);

        // Add listeners    
        JPanel panel = new JPanel();    
        panel.setFocusable(true);   
        panel.addKeyListener(new KeyListener() {    
            public void keyPressed(KeyEvent key) {  
                System.out.println("Key pressed."); 
            }   
            public void keyReleased(KeyEvent key) {}    
            public void keyTyped(KeyEvent key) {}   
        }); 
        panel.addMouseListener(new MouseListener() {    
            public void mouseReleased(MouseEvent mouse) {}  
            public void mouseClicked(MouseEvent mouse) {}   
            public void mousePressed(MouseEvent mouse) {    
                System.out.println("Mouse clicked.");   
            }   
            public void mouseEntered(MouseEvent mouse) {}   
            public void mouseExited(MouseEvent mouse) {}    
        }); 
        panel.addMouseMotionListener(new MouseMotionListener() {    
            public void mouseDragged(MouseEvent mouse) {    
                System.out.println("Mouse dragged.");   
            }   
            public void mouseMoved(MouseEvent mouse) {} 
        }); 
        add(panel); 
        panel.requestFocus();   

        timer.scheduleAtFixedRate(() -> repaint(), 0, 200, MILLISECONDS);   
    }   

    public void paint(Graphics G) { 
        // Drawing  
    }   

}

当我运行它时,“按下按键”事件工作正常,但没有一个鼠标事件有效。我在这里错过了什么?我看了其他答案,比如

此外,选择不同的组件(如getContentPane())似乎也无法解决问题。

2 个答案:

答案 0 :(得分:3)

如上所述,您应在添加所有组件后致电setVisible(true)。其他问题:

  • 不要命名您的非applet GUI" Applet"因为这个名称与常用的核心Java类冲突,所以对于审查你的工作的其他人来说,这将是非常混乱的。你的班级不是小程序,即使它是,也应该被称为别的东西。
  • 你问,what structure would you suggest using besides JFrame?。我建议您很少扩展JFrame,而是将代码设置为创建(或者如果需要,扩展)JPanel。这样做会增加你的类的灵活性,因为现在它可以在GUI中的任何地方使用,包括在JFrame中,在另一个JPanel中,与CardLayout交换,在JApplet中...
  • 你永远不应该直接在JFrame中绘画。
  • 而是扩展JPanel并使用其paintComponent(...)方法绘制。
  • 您不会显示您的绘画代码,但由于您在计时器中重复调用重绘,并且该计时器不执行任何其他操作,这表明您的班级'在绘制方法中改变了状态,这是不应该发生的,因为你无法完全控制何时或甚至是否调用绘制方法。
  • 你说,According to this question, a javax.swing.Timer, which I heard was deprecated as I should use ScheduledExecutorService instead.这是非常错误的。您应该使用Swing Timer来满足Swing计时器需求,而不是java.util.Timer。这些人都没有被弃用,但我在非Swing应用程序中使用ScheduledExecutorService比使用java util Timer更多。
  • 计时器代码应更改班级然后调用repaint()
  • 您会希望使用Key Bindings代替KeyListeners。例如,你可以避免强迫JPanel或JFrame获得键盘焦点。

答案 1 :(得分:0)

事实证明,正如Hovercraft Full of Eels所建议的那样,问题setVisible(true)add(panel)之前被调用。移动此语句允许所有侦听器正常工作。可编辑的工作代码示例如下:

package complexviewer;  

import java.awt.*;  
import java.awt.event.*;    
import java.util.concurrent.*;  
import static java.util.concurrent.TimeUnit.*;  
import javax.swing.*;   

public class Applet extends JFrame {    

    // Window and applet stats  
    public static final int windowSize = 400;   
    public static final int updateDelay = 20;   

    // Instance variables   
    private ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);   

    public static void main(String[] args) {    
        new Applet();   
    }   
    public Applet() {   
        // Set up window    
        super("Complex Viewing Frame"); 
        setSize(windowSize, windowSize);    
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

        // Incorrect location for setVisible    

        // Add listeners    
        JPanel panel = new JPanel();    
        panel.setFocusable(true);   
        panel.addKeyListener(new KeyListener() {    
            public void keyPressed(KeyEvent key) {  
                System.out.println("Key pressed."); 
            }   
            public void keyReleased(KeyEvent key) {}    
            public void keyTyped(KeyEvent key) {}   
        }); 
        panel.addMouseListener(new MouseListener() {    
            public void mouseReleased(MouseEvent mouse) {}  
            public void mouseClicked(MouseEvent mouse) {}   
            public void mousePressed(MouseEvent mouse) {    
                System.out.println("Mouse clicked.");   
            }   
            public void mouseEntered(MouseEvent mouse) {}   
            public void mouseExited(MouseEvent mouse) {}    
        }); 
        panel.addMouseMotionListener(new MouseMotionListener() {    
            public void mouseDragged(MouseEvent mouse) {    
                System.out.println("Mouse dragged.");   
            }   
            public void mouseMoved(MouseEvent mouse) {} 
        }); 
        add(panel); 
        panel.requestFocus();   

        setVisible(true); // Correct location for setVisible    

        timer.scheduleAtFixedRate(() -> repaint(), 0, 200, MILLISECONDS);   
    }   

    public void paint(Graphics G) { 
        // Drawing  
    }   

}