java.awt.event.MouseEvent鼠标事件的定义和使用 以及 Java Swing-JTextArea的使用

最近发现一个CSDN大佬写的Java-Swing全部组件的介绍:Java Swing 图形界面开发(目录)

 

JTextArea

文本区域。JTextArea 用来编辑多行的文本。JTextArea 除了允许多行编辑外,其他基本用法和 JTextField(文本框) 基本一致。

文本框就一行,文本区域是一个多行区域。

 

JTextArea构造方法

/**
 * 参数说明:
 *      text: 默认显示的文本
 *      rows: 默认可见的行数
 *      columns: 默认可见的列数
 *      
 * 默认由 rows 和 columns 决定首选大小
 */
JTextArea()

JTextArea(String text)
JTextArea(int rows, int columns)
JTextArea(String text, int rows, int columns)

 

JTextArea的一些函数

// 是否自动换行,默认为 false。自动换行也就是一行内可写字符是有限的,如果你超过这个数量不用你回车就会自动切到下一行
void setLineWrap(boolean wrap)

// 设置自动换行方式。如果为 true,则将在单词边界(空白)处换行; 如果为 false,则将在字符边界处换行。默认为 false。
void setWrapStyleWord(boolean word)

// 获取文本框中的文本
String getText()

// 追加文本到文档末尾
void append(String str)

// 替换部分文本
void replaceRange(String str, int start, int end)

// 设置文本框的 文本、字体 和 字体颜色
void setText(String text)
void setFont(Font font)
void setForeground(Color fg)

// 获取内容的行数(以换行符计算,满行自动换下一行不算增加行数)
int getLineCount()

// 获取指定行(行数从0开始)的行尾(包括换行符)在全文中的偏移量
int getLineEndOffset(int line)

// 获取指定偏移量所在的行数(行数从0开始)
int getLineOfOffset(int offset)

// 设置颜色,分别为: 光标颜色、呈现选中部分的背景颜色、选中部分文本的颜色、不可用时文本的颜色
void setCaretColor(Color c)
void setSelectionColor(Color c)
void setSelectedTextColor(Color c)
void setDisabledTextColor(Color c)

// 设置文本框是否可编辑
void setEditable(boolean b)

/* 下面方法定义在 java.awt.Component 基类中 */

// 判断组件当前是否拥有焦点
boolean isFocusOwner()

// 设置组件是否可用
void setEnabled(boolean b)

 

 

MouseEvent事件

处理在任何组件上都可以发生的按住、释放、移入组件、移出组件、单击触发的MouseEvent事件,应让监听器实现MouseListener接口。

如果要处理任何组件上都可以发生的拖动鼠标和移动鼠标时候触发的MouseEvent事件,应让监听器实现MouseMotionListener接口。

 

先用一个程序说MouseListener

MousePolice.java

import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.JTextField;

//作为MouseEvent事件的监听器,需要实现接口中的5个方法
public class MousePolice implements MouseListener{
    JTextArea jta;

    //获取所需资源
    public void setTextArea(JTextArea jta) {
        this.jta=jta;
    }

    //单击
    @Override
    public void mouseClicked(MouseEvent e) {
        //多次单击即是连击
        if(e.getClickCount()>=2)
            jta.append("连击在:"+e.getX()+","+e.getY()+"\n");
    }

    //进入
    @Override
    public void mouseEntered(MouseEvent e) {
        //getSource直接获得事件源实例
        if(e.getSource() instanceof JButton)
            jta.append("进入按钮在:"+e.getX()+","+e.getY()+"\n");
        if(e.getSource() instanceof JTextField)
            jta.append("进入文本框在:"+e.getX()+","+e.getY()+"\n");
        if(e.getSource() instanceof JFrame)
            jta.append("进入窗口在:"+e.getX()+","+e.getY()+"\n");
    }

    //退出
    @Override
    public void mouseExited(MouseEvent e) {
        jta.append("退出在:"+e.getX()+","+e.getY()+"\n");
    }

    //按下
    @Override
    public void mousePressed(MouseEvent e) {
        jta.append("按下在:"+e.getX()+","+e.getY()+"\n");
    }

    //松开
    @Override
    public void mouseReleased(MouseEvent e) {
        jta.append("释放在:"+e.getX()+","+e.getY()+"\n");
    }
}

 

WindowMouse.java

import java.awt.FlowLayout;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;

public class WindowMouse extends JFrame {
    JTextField jtf;
    JButton jb;
    JTextArea jta;
    MousePolice mp;

    WindowMouse() {
        init();
        this.setVisible(true);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    private void init() {
        // 当new FlowLayout()换成null时,就会变成绝对布局
        // null,绝对布局。绝对布局没有特定一个布局管理器类来表示,给容器的布局管理器设置为 null,就表示使用绝对布局,
        // 即通过设置组件的坐标和宽高来布置组件。
        // 绝对布局需要明确指定每一个组件的坐标和宽高,否则不显示。
        this.setLayout(new FlowLayout());
        jtf = new JTextField(8); // 文本框。JTextField 用来编辑单行的文本。
        jb = new JButton("按钮");
        jta = new JTextArea(2, 28);
        /*
         * JTextArea(String text, int rows, int columns) 参数说明: text: 默认显示的文本 rows:
         * 默认可见的行数 columns: 默认可见的列数 默认由 rows 和 columns 决定首选大小
         */
        mp = new MousePolice();

        mp.setTextArea(jta);// 为监听器传入资源

        // 注册监听器
        jb.addMouseListener(mp);
        jta.addMouseListener(mp);
        jtf.addMouseListener(mp);
        this.addMouseListener(mp);

        this.add(jb);
        this.add(jtf);
        this.add(new JScrollPane(jta));

    }
}

 

Main.java

// 设置自动换行,就是在输入的时候,如果输入内容超过一行所能容纳最多字符,就跳出
//    textArea.setLineWrap(true); 

public class Main {

    public static void main(String[] args) {
        WindowMouse wm=new WindowMouse();
        wm.setTitle("处理MouseEvent事件");
        wm.setBounds(300,300,360,200);
        wm.setLocationRelativeTo(null);  //自动把对话框弄到屏幕中间
    }

}

 

 

MouseMotionListener接口的例子

JLayeredPane(层次面板)

JLayeredPane为容器添加了深度,允许组件在需要时互相重叠。

JLayeredPane将深度范围按 层 划分,在同一层内又对组件按位置进一步划分,将组件放入容器时需要指定组件所在的层,以及组件在该层内的 位置(position/index)。

层的编号越大越显示在前面;同层内位置编号越大越靠近底部(位置编号取值范围: [-1, n - 1],n 表示层内组件数量,其中 -1 表示最底,0 表示最顶)。

通过 setLayer(Component c, int layer) 可设置组件所在的层数。

同一层内的组件,可通过调用 moveToFront(Component)、moveToBack(Component) 和 setPosition(int) 调整层内的位置。

PS: 添加到 JLayeredPane 内的组件需要明确指定组在位置和宽高,否则不显示(类似绝对布局)。

 

常用方法

/**
 * 添加组件到指定的层(默认放到层内最底部),参数说明:
 *     comp: 待添加的组件
 *     layer: 所在的层, 层数是int类型, 由于该方法与另一个 add(Component, int) 方法类似, 直接使用会有冲突, 所以使
 *            用该方法传递 layer 参数时, 必须使用 Integer 类型来明确调用的是下面 add(Component, Object) 方法。
 */
void add(Component comp, Object layer)

// 添加组件到指定的层和层内的位置
void add(Component comp, Object layer, int position)

// 设置组件所在层(默认放到层内最底部)
void setLayer(Component c, int layer)

// 设置组件所在层,以及在层内的位置
void setLayer(Component c, int layer, int position)

// 移动组件到其所在层的最顶部位置
void moveToFront(Component c)

// 移动组件到其所在层的最底部位置
void moveToBack(Component c)

// 设置组件在其所在层的位置,其中 position 取值范围为: [-1, n - 1],n 表示层内组件数量,其中 -1 表示最底,0 表示最顶
void setPosition(Component c, int position)

 

构造方法

JLayeredPane()

 

 

Swing的面板层次(参考链接:https://blog.csdn.net/kewbblog/article/details/8625917)

         |Grass Pane
         |
Root Pane|
         |            |Content Pane
         |Layered Pane|
                      |Menu Bar

Root Pane可以看成是虚拟的容器,包含着Grass Pane、Layered Pane、Content Pane与Menu Bar.Swing的容器包括JApplet ,JFrame,JDialog,JWindow与JInternalFrame都是构造在此结构上,JApplet、JFrame、JDialog、JWindow都是heavyweight容器,只 有JInternalFrame是lightweight容器。当我们要加入某个组件到Swing的容器中时,并不是直接加入到Root Pane,而是加入到 RootPane下面的某一成员(Layered Pane或Content Pane)

 

Content Pane与Menu Bar只是Layered Pane的其中一层,我们称此层为Frame-Content Layer.若你想知道Frame-Content Layer 在Layered Pane的层次是什么?你可以由JLayeredPane类中的Frame_Content_layer类常数取得。

由此我们可以知道,Layered Pane基本上可拥有非常多的“层”(Layer),那么如何分辨哪一层是在哪一层的上面或下面呢? 答案是Z_order.Z_order本身具有两个整数值,一个是代表层(Layer)的深度,另一个代表同层的相关位置(Position),当Z_order 的Layer数值越小时,表示其位置就在越底层,当Z_order的Layer数值越大时,表示其位置就在越上层。在JLayeredPane类中,共定 义了6个Z_order常数供用户参考,如下所示:

DEFAULT_LAYER:Z_order的Layer数值为0,以整数对象Integer(0)来表示,一般我们加入的组件若没有标记是第几层,默认值就 把组件放在此Default Layer中。

PALETTE_LAYER:Z_order的Layer数值为100,以整数对象Integer(100)来表示,位于Default Layer之上,一般用于放置可移动的 工具栏(Floatable Toolbar).

MODAL_LAYER:Z_order的Layer数值为200,以整数对象Integer(200)来表示,位于PALETTE_LAYER之上,一般用于放置对话框 (Dialog Box).

POPUP_LAYER:Z_order的Layer数值为300,以整数对象Integer(300)来表示,位于MODAL_LAYER之上,一般用于快捷菜单(Poup Menu)与工具栏提示(Tool Tips)中.

DRAG_LAYER:Z_order的Layer数值为400,以整数对象Integer(400)来表示,位于POPUP_LAYER之上,一般用于拖曳组件使其在不同 区域上.

FRAME_CONTENT_LAYER:Z_order的Layer数值为-30000,以整数对象Integer(-30000)来表示,一般来说,Frame Content Layer 最底层的是Layer,用来表示Content Pane与Menu Bar的位置,大部份情况我们不会更改到这个数值。

一般程序会提供良好的Z-order自动管理机制,当然java也不例外,因此大部份情况我们不会使用到Z-order,因为系统会自动 帮我们管理得好好的。用户只需将所需的组件直接加入Content Pane即可,不需要知道它们之间的顺序关系。但如果今天您必须处 理对象之间的层次关系时,例如Word中你可以把某个绘图对象下推至下一层,你就必须亲自处理Z-order的关系了。

 

下面用代码展示MouseMotionListener接口的例子

MousePolice.java

import java.awt.Component;
import java.awt.FlowLayout;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JLayeredPane;

//中间容器层次面板,直接实现了监听器该实现的接口
//所以其中的组件按钮直接拿自己这个类做监听器就可以了
//这也是比较方便的编程方式
public class MousePolice extends JLayeredPane
    implements MouseListener,MouseMotionListener{

    JButton jb;
    int x,y,a,b,x0,y0;

    MousePolice(){
        jb=new JButton("被拖动的按钮");
        jb.addMouseListener(this);
        jb.addMouseMotionListener(this);
        //setLayout设置布局管理器的布局为流式布局
        this.setLayout(new FlowLayout());
        //把按钮添加进来
        this.add(jb, JLayeredPane.DEFAULT_LAYER);   
    }

    //MouseListener:按下
    @Override
    public void mousePressed(MouseEvent e) {
        //除顶层容器外所有Swing组件的基类
        JComponent jc=null;
        jc=(JComponent)e.getSource();//获得事件源,并向上转换
        
        //使用setLayer方法把组件设置在层次面板中的哪一层中出现
        //但是程序并没 有把该组件添加到该层中
        //在使用setLayer方法后还应使用add方法把组件添加进层面板的这一层中
        //而且add方法 应出现在setLayer方法之后
        //层级面板,设置出现层级。更多内置层级变量见:
        //https://blog.csdn.net/kewbblog/article/details/8625917
        this.setLayer(jc, JLayeredPane.DRAG_LAYER);

        //获取事件源(左上角)位置坐标
        a=jc.getBounds().x;
        b=jc.getBounds().y;
        //获取鼠标在事件源中的位置坐标
        //这里的x0,y0也就是按下时候的坐标
        x0=e.getX();
        y0=e.getY();
    }

    //MouseListener:释放
    @Override
    public void mouseReleased(MouseEvent e) {
        JComponent jc=null;
        jc=(JComponent)e.getSource();
        //拖拽完成后,放回原来那一层去  default_layer
        this.setLayer(jc, JLayeredPane.DEFAULT_LAYER);
    }

    //MouseListener:进入
    @Override
    public void mouseEntered(MouseEvent e) {
        // TODO Auto-generated method stub

    }

    //MouseListener:单击
    @Override
    public void mouseClicked(MouseEvent e) {
        // TODO Auto-generated method stub

    }

    //MouseListener:退出
    @Override
    public void mouseExited(MouseEvent e) {
        // TODO Auto-generated method stub

    }

    //MouseMotionListener:移动
    @Override
    public void mouseMoved(MouseEvent e) {
        // TODO Auto-generated method stub

    }

    //MouseMotionListener:拖动
    @Override
    public void mouseDragged(MouseEvent e) {
        Component cpnt=null;//最大的组件类
        //如果事件源是组件,也不管是什么组件
        if(e.getSource() instanceof Component) {
            cpnt=(Component)e.getSource();//先向上转换成组件类对象
            //组件(左上角)坐标
            a=cpnt.getBounds().x;
            b=cpnt.getBounds().y;
            //拖动的实时坐标x,y
            x=e.getX();
            /*
             * Java中的mouseReleased(MouseEvent e)中坐标(e.getX(),e.getY())
              *   确定的是Pressed的时候的坐标
             * */
            y=e.getY();
            //拖动的坐标影响组件的坐标,则看起来是动态的拖动
            a=a+x;
            b=b+y;
            //设置其新位置
            //也就是说,新的位置坐标=刚才位置坐标+(当前鼠标坐标-鼠标按下坐标)
            //注意!组件的坐标是在容器坐标系中的!
            //而鼠标的坐标是在其下的组件的坐标系中的!
            cpnt.setLocation(a-x0,b-y0);
        }
    }
}

 

WindowMouse.java

import java.awt.BorderLayout;

import javax.swing.JFrame;

public class WindowMouse extends JFrame{
    //往组件里装好监听器的层次面板
    MousePolice lp;

    WindowMouse() {
        lp=new MousePolice();
        this.add(lp,BorderLayout.CENTER);//方位布局的中央
        this.setVisible(true);
        this.setBounds(12,12,300,300);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}

 

main.java

public class Main {

    public static void main(String[] args) {
        WindowMouse wm=new WindowMouse(); 
        wm.setTitle("处理MouseEvent事件");
        wm.setBounds(10,10,400,300);
    }

}

 

setLayout函数作用:设置布局管理器的布局为什么布局

Java中的mouseReleased(MouseEvent e)中坐标(e.getX(),e.getY())确定的是Pressed的时候的坐标(如果你一直按着鼠标移动,那么这个值就会跟着改变)

 

posted @ 2020-11-29 00:12  kongbursi  阅读(2131)  评论(0编辑  收藏  举报