Java筆記(10)-圖形介面設計、Swing、視窗、JFrame、常用元件和佈局、處理事件、MVC結構、對話方塊、GUI
我希望有個如你一般的人
如山間清爽的風
如古城溫暖的光
只要最後是你就好
今天 你路過了誰
誰又丟失了你呢
或者
從你的全世界路過
圖形介面設計
1 Java Swing 概述
圖形化介面(Graphics User Interface,GUI)
是指採用圖形方式顯示的計算機操作使用者介面。
通過圖形化介面,使用者和程式之間可以方便地進行互動。Java的抽象視窗工具包(Abstract Window Toolkit,AWT)
提供許多用來設計GUI的元件類。
java.awt
和javax.swing
包中一部分類的層次關係UML類圖。
GUI元件按其作用可分為基本元件(Component)
(Container)
兩大類:GUI基本元件,其上不能容納其他元件,如按鈕、文字框等圖形介面元素。容器是一種特殊的元件,可以用來容納其他的元件,如視窗、對話方塊等。
如果我們要在一個視窗中顯示按鈕、文字框等,需要將這些元件放到一個容器中。在java.awt中主要有兩個容器類Window類、Panel類和Applet類。但是Panel類必須放到Frame頂級容器中,一般不獨立使用。同樣我們也可以把Panel類和它的子類理解為一種中間容器,元件可以放到這個中間容器中,也可以放到頂級容器中。
容器和元件的概念與Android中的UI元件非常相似,View元件一定要依附在ViewGroup這個容器之下,此外,因為ViewGroup繼承自View,ViewGroup也可以當做View元件使用。
Android的圖形使用者介面元件層次
2 視窗
一個基於GUI的應用程式應當提供一個能直接和作業系統直接互動的容器,該容器可以被直接顯示、繪製在作業系統所控制的平臺上,如顯示器上,這樣的容器被稱作GUI設計中的底層容器。
JFrame類的例項就是一個底層容器,即通常稱的視窗。其他容器必須被新增到底層容器中,以便藉助這個底層容器和作業系統進行資訊互動。
2.1 JFrame常用方法
JFrame() 建立一個無標題的視窗
JFrame(String s) 建立標題為s的視窗
public void setVisible(boolean b) 設定視窗是否可見,視窗預設不可見
public void dispose() 撤銷當前的視窗,並釋放當前視窗所使用的資源
public void setDefaultCloseOperation(int operation) 設定單擊窗體右上角關閉圖示後,程式會做出怎樣的處理
WindowConstants.DISPOSE_ON_CLOSE 隱藏當前的視窗,並釋放窗體佔有的其他資源
WindowConstants.DO_NOTHING_ON_CLOSE 什麼也不做
WindowConstants.HIDE_ON_CLOSE 隱藏當前視窗
WindowConstants.EXIT_ON_CLOSE 結束視窗所在的應用程式
示例-JFrame建立兩個視窗
用JFrame建立兩個視窗
結果:
import javax.swing.JFrame;
import javax.swing.WindowConstants;
public class Windows {
public static void main(String[] args) {
JFrame window1 = new JFrame("撤銷視窗"); //建立標題名
JFrame window2 = new JFrame("退出程式");
window1.setBounds(0,0,400,200);// 顯示X軸位置,顯示Y軸位置 ,寬,長
window2.setBounds(400,0,400,200);
window1.setVisible(true); // 視窗預設是不可見的
window1.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
//設定單擊窗體右上角關閉圖示後,程式會做出怎樣的處理。
window2.setVisible(true);
window2.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
}
2.2 選單條、選單、選單項
視窗中的選單條、選單、選單項是我們所熟悉的元件,選單放在選單條裡,選單項放在選單中。
選單條
JComponent
類的子類JMenubar
負責建立選單條,即JMenubar
的一個例項就是一個選單條,JFrame
類用一個把選單條放到視窗的方法:setJMenuBar( JMenuBar bar);
該方法將選單條新增到視窗的頂端,需要注意的是,只能向視窗新增一個選單條。
選單
JComponent
類的子類JMenu
負責建立選單,即JMenu
的一個例項就是一個選單。- 選單項
JComponent
類的子類JMenuItem
負責建立選單項,即JMenuItem
的一個例項就是一個選單項
JMenuItem(String text, Icon icon)
嵌入子選單
JMenu
是JMenuItem
的子類,因此選單本身也是一個選單項,當把一個選單看作選單項新增到摸個選單中時,稱這個選單為子選單。選單上的圖示
可以用 圖示類Icon
宣告一個圖示,使用ImageIcon
類建立一個圖示。
Icon icon = new ImageIcon("a.png");
然後選單項呼叫setIcon(Icon icon)
設定圖示
示例-帶選單的視窗
圖片資源a.png、b.png、c.png、d.png存放到專案目錄下
Main.java
public class Main {
public static void main(String[] args) {
WindowMenu win = new WindowMenu("帶視窗的選單", 20, 30, 400, 500);
}
}
WindowMenu.java
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.KeyStroke;
import javax.swing.WindowConstants;
/**
* 自定義視窗WindowMenu
* @author Peng
*/
public class WindowMenu extends JFrame {
JMenuBar menubar;
JMenu menu, subMenu;
JMenuItem item1, item2;
public WindowMenu() {
}
public WindowMenu(String s, int x, int y, int w, int h) {
init(s);
setLocation(x, y);
setSize(w, h);
setVisible(true);
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
}
void init(String s) {
setTitle(s);
menubar = new JMenuBar();
menu = new JMenu("選單"); // JMnud的例項就是一個選單
/**
* 一級選單項
*/
subMenu = new JMenu("軟體專案"); // 子選單
item1 = new JMenuItem("Java話題"); // 建立選單項
//為選單項設定圖示
ImageIcon icon = new ImageIcon("a.png");
item1.setIcon(icon);
//使用JMenuItem的構造方法設定圖示
item2 = new JMenuItem("動畫話題", new ImageIcon("b.png"));
item1.setAccelerator(KeyStroke.getKeyStroke('A'));
item2.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, InputEvent.CTRL_MASK));
menu.add(item1);
menu.addSeparator();
menu.add(item2);
menu.add(subMenu);
/**
* 新增二級選單項
*/
subMenu.add(new JMenuItem("汽車銷售系統", new ImageIcon("c.png")));
subMenu.add(new JMenuItem("農場資訊系統", new ImageIcon("d.png")));
menubar.add(menu); // 選單條中加入選單
setJMenuBar(menubar); // 新增一個選單條
}
}
3 常用元件與佈局
3.1 常見元件
文字框
使用JComponent
的子類JTextField
建立文字框。文字框的允許使用者輸入單行文字。文字區
使用JComponent
的子類JButton
類建立按鈕,允許使用者單擊按鈕。標籤
使用JComponent
的子類JLabel
類建立標籤,標籤為使用者提供資訊提示。選擇框
使用JComponent
的子類JCheckBox
類來建立選擇框,為使用者提供多項懸著。選擇框提供兩種狀態,選中和未選中,使用者通過單擊該元件切換狀態。單選按鈕
使用JComponent
的子類的JRadioButton
類建立單項選擇框,為使用者提供單項選擇。下拉列表
使用JComponent
的子類的JComboBox
類來建立下拉列表,為使用者提供下拉列表。密碼框
使用JComponent
的子類的子類JPasswordField
建立密碼框,允許輸入單行密碼,密碼框預設回顯字元是“*”,也可以通過setEchoChar(char c)
來重新設定回顯字元。密碼框呼叫char[] getPassword()
方法可以返回實際的密碼。
示例 -常見元件
效果圖:
Main.java
public class Main {
public static void main(String[] args) {
ComponentInWindow win = new ComponentInWindow();
win.setBounds(100, 100, 320, 310);
win.setTitle("常用元件");
}
}
ComponentInWindow.java
import java.awt.FlowLayout;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPasswordField;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class ComponentInWindow extends JFrame {
JTextField text;
JButton button;
JCheckBox checkBox1, checkBox2, checkBox3;
JRadioButton radio1, radio2;
ButtonGroup group;
JComboBox<Object> comBox;
JTextArea area;
JPasswordField password;
public ComponentInWindow() {
init();
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
void init() {
setLayout(new FlowLayout()); // 設定佈局
add(new JLabel("文字框:"));
text = new JTextField(10);
add(text);
add(new JLabel("按鈕:"));
button = new JButton("確認");
add(button);
add(new JLabel("密碼框:"));
password = new JPasswordField(10);
add(password);
add(new JLabel("按鈕:"));
button = new JButton("確認");
add(button);
add(new JLabel("選擇框:"));
checkBox1 = new JCheckBox("喜歡音樂");
checkBox2 = new JCheckBox("喜歡旅遊");
checkBox3 = new JCheckBox("喜歡籃球");
add(checkBox1);
add(checkBox2);
add(checkBox3);
add(new JLabel("單選按鈕:"));
group = new ButtonGroup();
radio1 = new JRadioButton("男");
radio2 = new JRadioButton("女");
group.add(radio1);
group.add(radio2);
add(radio1);
add(radio2);
add(new JLabel("下拉列表:"));
comBox = new JComboBox<>();
comBox.addItem("音樂天地");
comBox.addItem("武術天地");
comBox.addItem("象棋樂園");
add(comBox);
add(new JLabel("文字區"));
area = new JTextArea(6, 13);// 文字區設定行數和列數
add(new JScrollPane(area));
}
}
3.2 常見容器
JComponent 是 Comtainer的 子類,因此 JComponent 的子類建立的元件也都是容器,但我們很少將 JButton、JTextField、JCheckBox 等元件當容器來使用。JComponent 專門提供了一些經常用來新增組建的容器。相對於底層容器 JFrame ,下面提到的容器被習慣地稱為中間容器,中間容器必須被新增到底層容器中才能發揮作用。
Jpanel面板
我們會經常使用 JPanel 建立一個面板,再向這個面板新增元件,然後把這個面板新增到其他容器中。JPanel 面板的預設佈局是 FlowLayout 佈局。滾動窗格 JScrollPane
拆分窗格 JSpitPane
分層窗格 JLayeredPane
3.3 常用佈局
當把元件新增到容器中時,希望控制組件在容器中的位置,這就需要用到佈局設計。
容器可以使用方法設定自己的佈局。
setLayout(佈局物件);
設定自己的佈局。
- FlowLayout 佈局
FlowLayout 類建立的物件稱作 FlowLayout 型佈局。FlowLayout 型佈局是 JPanel 型佈局的預設佈局,即 JPanel 及其子類建立的容器物件,如果不專門指定佈局,則他們的佈局就是 FlowLayout 佈局。
FlowLayout flow = new FlowLayout(); // 居中對齊
容器.setLayout(flow);
or
setLayout(new FlowLayout());
通過add 方法將元件按先後順序,從左到右,預設水平和垂直間隙是 5 個畫素的方式排列。元件的大小為預設的最佳大小,例如,控制元件的大小剛好能保證顯示其上面的名字。
- BorderLayout 佈局
- CardLayout 佈局
- GridLayout 佈局
- BoxLayout 佈局
- null 佈局
4 處理事件
處理元件的點選或者選擇事件。
4.1 事件處理模式
事件源
能夠產生處理了事件的物件都可以成為事件源,如文字框,按鈕,下拉式列表等。也就是說,事件源必須是一個物件,而且這個物件必須是Java認為能夠發生事件的物件。監視器
我們需要一個物件對事件源進行監視,以便對發生的事件作出處理。事件源通過呼叫相應的方法將某個物件註冊為自己的監視器。例如,對於文字框,這個方法是:
addActionListener(監視器);
對於註冊監視器的文字框,在文字框獲得焦點後,當用戶對文字框進行操作,如按下回車鍵,Java 執行環境就會自動用 ActionEvent 類建立一個物件,觸發 ActionEvent 事件 。對文字框進行相應的操作就會導致相應的事件發生,並通知監視器,監視器就會做出相應的處理。
- 處理事件的介面
為了讓監視器這個物件能夠對事件源發生的事件進行處理,建立該檢視物件的類必須實現相應的介面,即必須在類體中重寫介面的所有方法,那麼當事件源發生事件是,監視器會自動呼叫類中被重寫的介面方法。
4.2 ActionEvent 事件
ActionEvent 事件源
文字框、按鈕、選單項、密碼框、和單選按鈕都可以觸發事件,都可以成為事件源。註冊監視器
能觸發 ActionEvent 事件的元件,使用addActionListener(ActionListener listen)
,將實現 ActionListener 介面的類的例項註冊為事件源的監視器。ActionListener 介面
ActionListener 介面位於 java.awt.event包中,該介面只有一個方法
public void actionPerformed(ActionEvent e)
在這裡執行想要的操作
- ActionEvent 類中的方法
public Object getSourcee() 獲取事件源物件的引用,返回向上轉型為Object物件的應用
publi String getActionCommand() 獲取和事件發生的一個命令字串,例,文字框引發事件,文字框內的文字字串就是和該事件相關的一個命令字串。
示例-文字框監聽事件
在文字框內輸入檔名(預設目錄下要有檔案),回車後,通過BufferReader流讀出內容。
Main.java
public class Main {
public static void main(String[] args) {
WindowActionEvent win = new WindowActionEvent();
win.setBounds(100,100,310,260);
win.setTitle("處理ActionEvent事件");
}
}
WindowActionEvent.java
import java.awt.FlowLayout;
import java.awt.HeadlessException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import javax.swing.JFrame;
import javax.swing.JTextField;
public class WindowActionEvent extends JFrame {
JTextField text;
ReaderListen listener;
public WindowActionEvent() throws HeadlessException {
init();
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
void init() {
setLayout(new FlowLayout());
text = new JTextField(10);
listener = new ReaderListen();
text.addActionListener(listener);
add(text);
}
}
class ReaderListen implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
String fileName = e.getActionCommand();
System.out.println(fileName + "內容如下:");
try {
File file = new File(fileName);
FileReader inOne = new FileReader(file);// 在專案目錄下 自己把Main.java複製一份到專案目錄下
BufferedReader inTwo = new BufferedReader(inOne);
String s = null;
while ((s = inTwo.readLine()) != null) {
System.out.println(s);
}
inOne.close();
inTwo.close();
} catch (Exception e2) {
e2.printStackTrace();
}
}
}
示例2-文字框、文字區框、按鈕的監聽事件
效果圖:
Main.java
public class Main {
public static void main(String[] args) {
WindowActionEvent win = new WindowActionEvent();
win.setBounds(100,100,360,300);
win.setTitle("處理ActionEvent事件");
}
}
WindowActionEvent.java
import java.awt.FlowLayout;
import java.awt.HeadlessException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class WindowActionEvent extends JFrame {
JTextField text;
JTextArea textShow;
JButton button;
ReaderListen listener;
public WindowActionEvent() throws HeadlessException {
init();
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
void init() {
setLayout(new FlowLayout());
text = new JTextField(10);
button = new JButton("讀取");
textShow = new JTextArea(9,30);
listener = new ReaderListen();
listener.setJTextField(text);
listener.setJTextArea(textShow);
text.addActionListener(listener);
button.addActionListener(listener);
add(text);
add(button);
add(new JScrollPane(textShow));
}
}
class ReaderListen implements ActionListener {
JTextField text;
JTextArea textShow;
public void setJTextField(JTextField text) {
this.text = text;
}
public void setJTextArea(JTextArea textShow) {
this.textShow = textShow;
}
@Override
public void actionPerformed(ActionEvent e) {
try {
File file = new File(text.getText()); //getDocument()
FileReader inOne = new FileReader(file);
BufferedReader inTwo = new BufferedReader(inOne);
String s = null;
while ((s = inTwo.readLine()) != null) {
textShow.append(s+"\n");
}
inOne.close();
inTwo.close();
} catch (Exception e2) {
e2.printStackTrace();
}
}
}
4.3 ActionItem 事件
Item事件源
選擇框和下拉列表都可以觸發 ItemEvent 事件。選擇框提供兩種狀態,一種是未選中,另一種是選中,使用者點選切換了狀態,就會觸發 ItemEvent 事件。對於下拉列表,使用者選中了下拉列表中某個選項,就會觸發 ItemEvent 事件。註冊監視器
選擇框和下拉列表元件使用addItemListener(ItemListener listen)
,註冊為事件源的監視器。ItemListener 介面
class MyListener implements ItemListener{
@Override
public void itemStateChanged(ItemEvent e) {
// 觸發事件後,你想要的操作
}
}
ItemEvent 事件物件使用 getSource() 方法返回 ItemEvent 事件源,使用 getItemSelectable 方法返回發生 ItemEvent 事件的事件源。
@Override
public void itemStateChanged(ItemEvent e) {
...
e.getSource();
e.getItemSelectable();
.
..
}
示例 -下拉列表
下拉列表的選項是當前目錄下Java檔案的名字,使用者選擇下拉列表的選項後,監視器負責在文字區顯示檔案的內容。
效果圖:
Main.java
public class Main {
public static void main(String[] args) {
WindowActionEvent win = new WindowActionEvent();
win.setBounds(100, 100, 400, 300);
win.setTitle("處理ItemEvent事件");
}
}
WindowActionEvent.java
import java.awt.FlowLayout;
import java.awt.HeadlessException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FilenameFilter;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class WindowActionEvent extends JFrame {
JComboBox choice;
JTextArea textShow;
ReaderListen listener;
public WindowActionEvent() throws HeadlessException {
init();
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
void init() {
setLayout(new FlowLayout());
choice = new JComboBox<>();
choice.addItem("請選擇檔案:");
File dir = new File(".");
FileAccept fileAccept = new FileAccept("java"); // 設定字尾名
String[] fileName = dir.list(fileAccept);// 把.java字尾的檔名返回,並存到陣列中
for (String name : fileName) { // 遍歷返回的.java檔名
choice.addItem(name); // 把檔名新增到下拉列表中
}
textShow = new JTextArea(9, 30);
listener = new ReaderListen();
/**
* 在ItemListener中自定義這個方法
* 主要是要用到下拉列表框和文字區的變數,進行相應的操作
*/
listener.setJComboBox(choice);
listener.setJTextArea(textShow);
choice.addItemListener(listener);
add(choice);
add(new JScrollPane(textShow)); //滾動窗格 常用容器
}
class FileAccept implements FilenameFilter { // 檔名過濾器
private String type;
FileAccept(String type) {
this.type = type;
}
@Override
public boolean accept(File dir, String name) {
return name.endsWith(type);
}
}
}
class ReaderListen implements ItemListener {
JComboBox choice;
JTextArea textShow;
public void setJComboBox(JComboBox choice) {
this.choice = choice;
}
public void setJTextArea(JTextArea textShow) {
this.textShow = textShow;
}
@Override
public void itemStateChanged(ItemEvent e) {
textShow.setText(null);
try {
String fileName = choice.getSelectedItem().toString(); // 獲取下拉列表名稱
File file = new File(fileName);
FileReader inOne = new FileReader(file);
BufferedReader inTwo = new BufferedReader(inOne); // 專門用來逐行讀取
String s = null;
while ((s = inTwo.readLine()) != null) { //逐行讀出
textShow.append(s + "\n"); // 依次新增到textShow中
}
inOne.close();
inTwo.close();
} catch (Exception e2) {
textShow.append(e2.toString());
}
}
}
4.4 DocumentEvent 事件
DocumentEvent 事件源
文字區 (JTextArea)含有一個實現 Document 介面的示例,該例項被稱作文字區所維護的文件,文字區呼叫 getDocument 方法返回所維護的文件。文字區的文件能觸發 DocumentEvent 事件。註冊監視器
事件源使用 addDocumentListener (DocumentListener listen),將實現 DocumentListener 介面的類的例項註冊為事件源的監視器。DocumentListener 介面
在 java.swing.event 包中,該介面有三個方法:
public void removeUpdate(DocumentEvent e)
public void insertUpdate(DocumentEvent e)
public void changedUpdate(DocumentEvent e)
示例-文字區
有兩個文字區。當用戶在一個文字區輸入若干字串時(用逗號、空格或回車符作為單詞間的分隔符),另一個文字區同時對使用者輸入的英文單詞按字典集排序。
效果圖:
Main.java
public class {
public static void main(String args[]) {
WindowDocument win=new WindowDocument();
win.setBounds(10,10,360,260);
win.setTitle("處理DocumentEvent事件");
}
}
WindowDocument.java
import java.awt.FlowLayout;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
public class WindowDocument extends JFrame {
JTextArea inputText,showText; //一個用於輸入,一個用於輸出
PoliceListen listen;
WindowDocument() {
init();
setLayout(new FlowLayout());
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
void init() {
inputText = new JTextArea(9,10);
showText = new JTextArea(9,10);
add(new JScrollPane(inputText));
add(new JScrollPane(showText));
listen = new PoliceListen();
listen.setInputText(inputText);
listen.setShowText(showText);
(inputText.getDocument()).addDocumentListener(listen);//向文件註冊監視器
}
}
PoliceListenjava
import javax.swing.event.*;
import javax.swing.*;
import java.util.*;
public class PoliceListen implements DocumentListener {
JTextArea inputText, showText;
public void setInputText(JTextArea text) {
inputText = text;
}
public void setShowText(JTextArea text) {
showText = text;
}
public void removeUpdate(DocumentEvent e) {
changedUpdate(e);
}
public void insertUpdate(DocumentEvent e) {
changedUpdate(e);
}
public void changedUpdate(DocumentEvent e) {
String str = inputText.getText();
// 空格、數字和符號(!"#$%&'()*+,-./:;<=>[email protected][\]^_`{|}~)組成的正則表示式:
String regex = "[\\s\\d\\p{Punct}]+";
String words[] = str.split(regex);
Arrays.sort(words); // 按字典序從小到大排序
showText.setText(null);
for (String s : words)
showText.append(s + ",");
}
}
4.5 MouseEvent 事件
事件源
任何組價上都可以發生滑鼠事件,如滑鼠進入元件,退出元件,在元件上方單擊按鈕,拖到按鈕等都會觸發滑鼠事件,即導致 MouseEvent 類自動建立一個事件物件。
使用 MouseListener 介面處理滑鼠事件
滑鼠事件
MouseListener 介面可以處理的5種滑鼠事件
- 在事件源上按下滑鼠鍵
- 釋放事件源上的滑鼠鍵
- 在事件源上點選滑鼠鍵
- 滑鼠進入事件源
- 滑鼠退出事件源
MouseEvent 方法
int getX() 獲取滑鼠指標在事件源座標系中的 X-座標
int getY() 獲取滑鼠指標在事件源座標系中的 Y-座標
int getButton() 返回更改了狀態的滑鼠按鍵(如果有)。
int getClickCount() 返回與此事件關聯的滑鼠單擊次數。
Point getPoint() 返回事件相對於源元件的 x, y 座標。
Object getSource() 獲取發生滑鼠事件的事件源
String getMouseModifiersText(int modifiers) 返回一個描述事件期間所按下的修改鍵和滑鼠按鍵(如“Shift”或“Ctrl+Shift”)的 String。
註冊 MouseEvent 事件源
public void mousePressed(MouseEvent e) 處理元件上按下滑鼠按鈕事件
public void mouseReleased(MouseEvent e) 處理釋放元件上的滑鼠按鈕事件
public void mouseEntered(MouseEvent e) 處理滑鼠進入元件的事件
public void mouseExited(MouseEvent e) 處理在滑鼠退出元件被呼叫事件
public void mouseClicked(MouseEvent e) 處理在源元件上點選滑鼠按鈕事件
示例-使用 MouseListener 介面處理滑鼠事件
分別監視按鈕 、文字框、和視窗上的按鈕事件,當發生滑鼠事件時,獲取滑鼠指標的座標值,注意,事件源的座標系上的左上角是原點。
軟體效果:
Main.java
public class Main {
public static void main(String args[]) {
WindowMouse win=new WindowMouse();
win.setTitle("處理滑鼠事件");
win.setBounds(100,100,460,360);
}
}
WindowMouse.java
import java.awt.*;
import javax.swing.*;
public class WindowMouse extends JFrame {
JTextField text;
JButton button;
JTextArea textArea;
MousePolice police;
WindowMouse() {
init();
setBounds(100,100,420,220);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
void init() {
setLayout(new FlowLayout());
text=new JTextField(8);
textArea=new JTextArea(10,28);
police=new MousePolice();
police.setJTextArea(textArea);
text.addMouseListener(police);
button=new JButton("按鈕");
button.addMouseListener(police);
addMouseListener(police);
add(button);
add(text);
add(new JScrollPane(textArea));
}
}
MousePolice.java
import java.awt.event.*;
import javax.swing.*;
public class MousePolice implements MouseListener {
JTextArea area;
public void setJTextArea(JTextArea area) {
this.area=area;
}
public void mousePressed(MouseEvent e) {
area.append("\n滑鼠按下,位置:"+"("+e.getX()+","+e.getY()+")");
}
public void mouseReleased(MouseEvent e) {
area.append("\n滑鼠釋放,位置:"+"("+e.getX()+","+e.getY()+")");
}
public void mouseEntered(MouseEvent e) {
if(e.getSource() instanceof JButton) // 得到的事件源是JButton的物件時,返回true
area.append("\n滑鼠進入按紐,位置:"+"("+e.getX()+","+e.getY()+")");
if(e.getSource() instanceof JTextField)
area.append("\n滑鼠進入文字框,位置:"+"("+e.getX()+","+e.getY()+")");
if(e.getSource() instanceof JFrame)
area.append("\n滑鼠進入視窗,位置:"+"("+e.getX()+","+e.getY()+")");
}
public void mouseExited(MouseEvent e) {
area.append("\n滑鼠退出,位置:"+"("+e.getX()+","+e.getY()+")");
}
public void mouseClicked(MouseEvent e) {
if(e.getClickCount()>=2)
area.setText("滑鼠連擊,位置:"+"("+e.getX()+","+e.getY()+")");
}
}
使用 MouseMotionListener 介面處理滑鼠事件
使用 MouseMotionListener 介面可以處理以下兩種操作觸發的滑鼠事件。
- 在事件源上拖動滑鼠
- 在事件源上移動滑鼠
事件源註冊監視器的方法 addMouseMotionListener (MotionListener listen)
MouseMotionListener 介面的方法:
mouseDragged ( MouseEvent ) 處理了負責拖動滑鼠觸發的事件。即當拖動滑鼠是(不必再事件源上),監視器呼叫介面中的這個方法對事件作出處理。
mouseMoved ( MouseEvent ) 負責處理移動滑鼠觸發的事件。即當事件源上移動滑鼠時,監視器呼叫介面中的這個方法對事件作出處理。
可以使用座標變換來實現元件的拖動。當滑鼠拖動元件時,可以先獲取滑鼠指標在元件座標系中的實時座標x,y,以及元件的左上角在容器座標系中的座標a,b;如果在拖動元件時,想讓滑鼠指標相對於拖動的元件保持靜止,那麼元件左上角在容器作弊作息中的位置應當是a+x-x0, b+y-y0,其中x0,y0是最初在元件上按下滑鼠時,滑鼠指標在組建座標系中的初始位置。
示例- 使用 MouseMotionListener 介面處理滑鼠事件
當滑鼠移動或拖動時,給出提示並顯示滑鼠所在位置的座標。
效果圖:
MyMouseMotionListener.java
import java.awt.BorderLayout;
import java.awt.Label;
import java.awt.TextArea;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
public class MyMouseMotionListener {
JFrame myframe; // JFrame通常預設使用BorderLayout佈局管理器的
TextArea tf; // 文字區
MousePolice mousepolice; // 實現監視器介面的類
JButton exitButton; // 按鈕
public MyMouseMotionListener() {
Label label = new Label("點選或拖動滑鼠"); // 初始化標籤
myframe = new JFrame("MyMouseMotionListener"); // 建立標題為MyMouseMotionListener的視窗
tf = new TextArea(); // 初始化文字區
exitButton = new JButton("退出"); // 初始化退出按鈕
mousepolice = new MousePolice(tf); // 利用構造方法把 TextArea傳遞到監視器
tf.addMouseMotionListener(mousepolice); // 註冊監視器
exitButton.addActionListener(new ActionListener() { // 按鈕的監聽事件 匿名內部類方式
@Override
public void actionPerformed(ActionEvent e) {
System.exit(0); // 正常退出
}
});
myframe.add(label, BorderLayout.NORTH); // 新增標籤 位置為北
myframe.add(tf, BorderLayout.CENTER); // 新增文字 在中部
myframe.add(exitButton, BorderLayout.SOUTH); // 設定退出按鈕 在南
myframe.setSize(400, 300); // 設定視窗大小
// myframe.setBounds(x, y, 400, 300); 這個方法可以設定視窗在顯示螢幕的位置 x,y
myframe.setVisible(true); // 視窗可視
}
public static void main(String[] args) {
new MyMouseMotionListener();
}
}
MousePolice.java
import java.awt.TextArea;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
public class MousePolice implements MouseMotionListener {
int number = 1;
TextArea tf;
MousePolice(TextArea tf) {
this.tf = tf;
}
@Override
public void mouseDragged(MouseEvent e) {
// getX(),getY():獲取滑鼠的座標位置
String s = number++ + "" + "滑鼠拖動:x=" + e.getX() + "y=" + e.getY() + "\n";
tf.append(s);
}
@Override
public void mouseMoved(MouseEvent e) {
String s = number++ + "" + "滑鼠移動:x=" + e.getX() + "y=" + e.getY() + "\n";
tf.append(s);
}
}