Swing图形界面之鼠键事件

鼠标事件处理

  对于所有Component类的子类对象都能产生鼠标事件,她有俩个与事件处理有关的接口:MouseListener接口,专门处理基本鼠标事件,例如点击鼠标;MouseMotionListener接口,专门处理鼠标移动事件。
MouseListener:

public interface MouseListener extends EventListener{
    public void mouseClicked(MouseEvent e);  // once the mouse clicks
    public void mouseEntered(MouseEvent e);  // once the mouse enters the specific area
    public void mouseExited(MouseEvent e);   // once the mouse exits the specific area
    public void mousePressed(MouseEvent e);  // once the mouse clicks on a component
    public void mouseReleased(MouseEvent e); // once the mouse releases
}

MouseMotionListener:

public interface MouseMotionListener extends EventListener{
    public void mouseDragged(MouseEvent e);  // once the mouse moves with clicked
    public void mouseMoved(MouseEvent e);    // once the mouse moves
}

  Java分成俩个监视器的目的是为了提高性能,因为移动鼠标事件经常发生。MouseEvent类提供有鼠标事件处理的一些方法和常量。
常用的常量:

  • MOUSE_CLICKED:鼠标单击事件
  • MOUSE_DRAGGED:鼠标拖拽事件
  • MOUSE_ENTERED:鼠标进入指定区域事件
  • MOUSE_EXITED:鼠标离开指定区域事件
  • MOUSE_MOVED:鼠标移动事件
  • MOUSE_PRESSED:鼠标按钮按下事件
  • MOUSE_RELEASED:鼠标按钮释放事件

常用的方法:

  • public int getClickCount():获取鼠标单击的次数
  • public Point getPoint():获取事件源位置。返回Point对象,包含鼠标事件发生的坐标
  • public int getX():鼠标事件发生的X坐标
  • public int getY():鼠标事件发生的Y坐标
  • public String paramString():返回事件的字符串表示
  • public synchronized void translatePoint(int x, int y):采用参数增加鼠标位置的偏移量

注意在拖动鼠标时,总是要调用MouseMotionListener中的mouseDragged()方法,同时也调用MouseListener中的mouseReleased()方法

实验效果

import subJFrame;
import java.awt.*;
import java.awt.event.*;

public class MouseEventTest extends subJFrame {
    int xValue, yValue;
    MouseEventTest(){
        super("MouseEventTest");

        addMouseMotionListener(
                new MouseMotionListener() { // normal method
                    @Override
                    public void mouseDragged(MouseEvent e) {
                        xValue = e.getX();
                        yValue = e.getY();
                        repaint();  // transfer the method of paint() to refresh
                    }

                    @Override
                    public void mouseMoved(MouseEvent e) {
                        // Must override or it will be abstract
                    }
                }
        );
        setSize(800,600);
        setVisible(true);
    }

    public void paint(Graphics g){
        g.fillOval(xValue,yValue,10,10);
    }

    public static void main(String[] AUG) {
        new MouseEventTest();
    }

}

运行效果:

强行解释

  这里我解释一些概念上的东西,虽然也没有啥好解释的,注释都给你们写好了

  • 匿名类中的repaint()将自动调用paint()方法
  • paint()方法中的语句g.fillOval(xValue, yValue, 10, 10)是在坐标(xValue, yValue)处画一个圆
  • 程序仅仅支持鼠标的拖动操作,因为程序仅仅实现了MouseMotionListener接口的mouseDragged()方法,而对mouseMoved()方法并没有给出代码

  那么问题来了,我为啥没使用mouseMoved()这个方法,但还是要在代码里写粗来?
  答案是不会马上给你们的,就让你们思考一下思考一下思考一下思考一下思考一下思考一下思考一下思考一下思考一下思考一下思考一下思考一下思考一下思考一下思考一下思考一下思考一下。思考力度差不多了。
  真実はいつも一つ:我们必须完全实现该接口,只有这样才能定义对象,不然他还是一个抽象类。也就是需要把这个抽象类里的所有抽象方法全部实现,不然就不行。空着都可以,就一定要写。

那么,问题又来了,我可不可以按需求使用哪一个方法,就只实现那个方法呢?答案啊是可以的,那么就有了Adapter类。

Adapter类

  这个类是方便我们需要哪个抽象类方法,就使用按一个抽象类方法,而不需要全部实现。称为适配器。但是并非所有接口都可以定义Adapter类,在java.awt.event和javax.swing.event包中,只有几个接口可以定义Adapter类。

Adapter类名称 实现接口名称 Adapter类名称 实现接口名称
ComponentAdapter ComponentListener MouseAdapter MouseListener
ContainerAdapter ContainerListener MouserMotionAdapter MouseMotionListener
FocusAdapter FocusListener WindowAdapter WindowListener
KeyAdapter KeyListener

  所以,上述代码就可以修改了,修改为如下形式:

addMouseMotionListener(
                new MouseMotionAdapter() { // class of Adapter
                    @Override
                    public void mouseDragged(MouseEvent e) {
                        xValue = e.getX();
                        yValue = e.getY();
                        repaint();  // transfer the method of paint() to refresh
                    }
                }
);

键盘事件处理

  Component类的子类不仅可以产生鼠标事件,也可以产生键盘事件。键盘事件表现为键的按下与弹起。与键盘事件的接口只有一个KeyListener,它定义包含3个抽象类方法:

public interface KeyListener extends EventListener{
    public void keyPressed(KeyEvent e);  // once the any keys presses
    public void KeyReleased(KeyEvent e); // once the key releases
    public void keyTyped(KeyEvent e);    // once the Alphabetic keys presses
}

  按下任何键都将调用keyPressed()方法,而keyTyped()方法对操作键不响应,如:方向键、End键、Page Up键、F1~F12等功能键等等这些都属于操作键。当发生键盘事件后,都会调用keyReleased()方法。
  凡是实现KeyListener接口的类,都必须实现上述3个方法。这3个方法的参数类型都是KeyEvent。该类包含的常用方法如下:

  • public char getKeyChar():取得按下键的字符
  • public int getKeyCode():取得按下键的键码
  • public static String getKeyModifiersText(int modifiers):将描述修饰符的文本变成字符串
  • public static String getKeyText(int keyCode):将键码变成描述键的文本
  • public boolean isActionKey():检查是否属于操作键
  • public String paramString():返回事件的字符串表示
  • public void setKeyChar(char keyChar):改变键字符
  • public void setKeyCode(int keyCode):改变键码
  • public void setModifiers(int modifiers):改变键修饰符

实验效果

import javax.swing.*;
import java.awt.event.*;
import subJFrame;

public class KeyEventTest extends subJFrame implements KeyListener {
    String line_1, line_2, line_3;
    JTextArea textArea;

    @Override
    public void keyPressed(KeyEvent e) {
        line_1 = "  Key Pressed: " + KeyEvent.getKeyText(e.getKeyCode());
        setLine2and3(e);
    }

    @Override
    public void keyTyped(KeyEvent e) {
        line_1 = "  Key Typed: " + e.getKeyChar();
        setLine2and3(e);
    }

    @Override
    public void keyReleased(KeyEvent e) {
        line_1 = "  key Released: " + KeyEvent.getKeyText(e.getKeyCode());
        setLine2and3(e);
    }

    private void setLine2and3(KeyEvent e) {
        line_2 = "  Key is: " + (e.isActionKey()?" ":"not") + " an action key.";
        String str = KeyEvent.getKeyModifiersText(e.getModifiers());
        line_3 = "  Modifier keys pressed: " + (str.equals("")?"none":str);
        textArea.setText(line_1+"\n"+line_2+"\n"+line_3+"\n");
    }

    KeyEventTest(){
        super("KeyEventTest");
        textArea = new JTextArea(10,15);
        textArea.setText("  Please press any key.\n");
        textArea.setEnabled(false);
        getContentPane().add(textArea);
        addKeyListener(this);
        setSize(200,100);
        setVisible(true);
    }

    public static void main(String[] AUG) {
        new KeyEventTest();
    }
}

运行效果:

强行解释

  我们依旧需要实现抽象类的全部抽象接口方法,而setLine2and3()是我们自己自定义方法,她的功能是获取键修饰符,以及判断所按下键是否为操作键。将getKeyCode()获取的键码用作getKeyText()方法的参数,就可以获得相应键的名字。
  如果需要测试一些特殊键,那么isAltDown()isShiftDown()isControlDown()这些方法就特别适合你,返回的都是boolean值。


爱狂笑的孩子运气不会差