面向对象的程序设计- java

77
面面面面面面面面面Java

Upload: marly

Post on 12-Jan-2016

135 views

Category:

Documents


0 download

DESCRIPTION

面向对象的程序设计- Java. 第六章 GUI 设计和事件处理. 6.1 概述 6.2 GUI 设计 6.3 Java 的事件处理模型 6.4 常见事件处理 6.5 响应用户输入 6.6 小结. 输入. 事件. 事件处理. 用户. 输出. 处理. 6.1 概述. 一、与用户的交互. 6.1 概述. 二、 GUI 的元素: Top-Level Containers. 6.1 概述. 二、 GUI 的元素: General-Purpose Containers. 6.1 概述. - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: 面向对象的程序设计- Java

面向对象的程序设计- Java

Page 2: 面向对象的程序设计- Java

第六章 GUI 设计和事件处理

6.1 概述

6.2 GUI 设计

6.3 Java 的事件处理模型

6.4 常见事件处理

6.5 响应用户输入

6.6 小结

Page 3: 面向对象的程序设计- Java

6.1 概述

一、与用户的交互

用户用户

输入

事件处理事件处理事件

处理输出

Page 4: 面向对象的程序设计- Java

6.1 概述

二、 GUI 的元素: Top-Level Containers

Page 5: 面向对象的程序设计- Java

6.1 概述

二、 GUI 的元素: General-Purpose Containers

Page 6: 面向对象的程序设计- Java

6.1 概述

二、 GUI 的元素: Special-Purpose Containers

Page 7: 面向对象的程序设计- Java

6.1 概述

二、 GUI 的元素: Basic Controls

Page 8: 面向对象的程序设计- Java

6.1 概述

二、 GUI 的元素: Uneditable Information Displays

Page 9: 面向对象的程序设计- Java

6.1 概述

二、 GUI 的元素 :Editable Displays of Formatted Information

Page 10: 面向对象的程序设计- Java

6.1 概述

事件是代表另一对象抽象状态下变化的对象。事件本身就是抽象。生成事件的过程是无法从对象外部直接观察的。

三、什么是事件?

本地事件是使用单一 Java 虚拟且运行于单一平台上的应用程序生成的事件。

分布事件就是由远程目标生成的事件,运行于不同的平台使用不同的 JVM 。

Page 11: 面向对象的程序设计- Java

6.1 什么是事件

四、与 GUI 和事件处理有关的包

java.awt

java.awt.event

javax.swing ( JFC1.1 )

javax.swing.event

推荐使用 swing 组件

Page 12: 面向对象的程序设计- Java

6.2 GUI 设计

一、容器与组件

容器容器

组件组件

容器容器

组件组件

组件组件

组件组件

组件组件组件组件

Page 13: 面向对象的程序设计- Java

6.2 GUI 设计

容器是可以放置其他组件的组件,主要有

Panel 、 Frame 和 Window

容器是 java.awt.Container 的子类。Swing 组件都是抽象类

java.awt.Container.Jcomponent 的子类。

Page 14: 面向对象的程序设计- Java

6.2 GUI 设计

二、 Swing 组件的类结构

…………

ContainerContainer

WindowWindow

…………

JComponentJComponent

PanelPanel DialogDialog

JWindowJWindow

FrameFrame JFrameJFrame

FileDialogFileDialog

JDialogJDialog

Page 15: 面向对象的程序设计- Java

6.2 GUI 设计

JComponent 的直接子类( JDK1.4 )

AbstractButton, BasicInternalFrameTitlePane, Box, Box.Filler, JColorChooser, JComboBox, JFileChooser, JInternalFrame, JInternalFrame.JDesktopIcon, JLabel, JLayeredPane, JList, JMenuBar, JOptionPane, JPanel, JPopupMenu, JProgressBar, JRootPane, JScrollBar, JScrollPane, JSeparator, JSlider, JSpinner, JSplitPane, JTabbedPane, JTable, JTableHeader, JTextComponent, JToolBar, JToolTip, JTree, JViewport

AbstractButton, BasicInternalFrameTitlePane, Box, Box.Filler, JColorChooser, JComboBox, JFileChooser, JInternalFrame, JInternalFrame.JDesktopIcon, JLabel, JLayeredPane, JList, JMenuBar, JOptionPane, JPanel, JPopupMenu, JProgressBar, JRootPane, JScrollBar, JScrollPane, JSeparator, JSlider, JSpinner, JSplitPane, JTabbedPane, JTable, JTableHeader, JTextComponent, JToolBar, JToolTip, JTree, JViewport

Page 16: 面向对象的程序设计- Java

6.2 GUI 设计

三、创建主界面要创建 Swing 应用程序,首先要创建一个表示图形用户界面的类,这个类的对象将被用作容器,用于放置要显示的其他组件。大 部 分 应 用 程 序 的 主 界 面 是 一 个 简 单 窗 口( Jwindow )或是一个框架窗口( JFrame )。

Page 17: 面向对象的程序设计- Java

6.2 GUI 设计

一个最简单的 Swing 应用程序import javax.swing.*;

public class HelloWorldSwing {

public static void main(String[] args) {

JFrame frame = new JFrame("HelloWorldSwing");

final JLabel label = new JLabel("Hello World");

frame.getContentPane().add(label); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

frame.pack();

frame.setVisible(true);

}}

Page 18: 面向对象的程序设计- Java

6.2 GUI 设计

四、创建并添加组件创建组件其实就是生成一个满足外观要求的某个某个组件对象。

JLabel label = new JLabel("Hello World");

JButton okButton = new JButton(“Ok");

将组件加入到简单容器( JPanel )中,只要调用容器的add(Component) 方法,参数是该组件。对于大多数其他容器(框架、窗口、 JApplet 和对话框)则采用其他方法。

Page 19: 面向对象的程序设计- Java

6.2 GUI 设计

这些非简单容器实际上被划分为窗格( Pane ),后者是一种容器中的容器。通常情况下组件被加入容器的内容窗格( ContentPane )中。组件加入容器的内容窗格的步骤是:1 )创建一个面板。2 )使用面板的 add(Component) 方法将组件加入到面板中。

3 )调用 setContentPane(Container) 方法,将面板作为参数,将面板加入到内容窗格中。

Page 20: 面向对象的程序设计- Java

6.2 GUI 设计

五、布局管理Java 通过布局管理器来排列组件。

Page 21: 面向对象的程序设计- Java

6.2 GUI 设计

布局管理器决定了组件被加入到容器中时被如何排列。Java 中布局管理器包括FlowLayout 、 GridLayout 、 BorderLayout 、 CardLayout 和 GridBagLayout 类。在将组件加入到容器之前,必须建立容器的布局管理器。 FlowLayout flo=new FlowLayout();

面板的缺省输出管理器是 FlowLayout ;框架和窗口的是 BorderLayout 。

创建完布局管理器后,需要用容器的setLayout() 方法将它与容器关联。

Page 22: 面向对象的程序设计- Java

6.2 GUI 设计

1 、 FlowLayout

组件按照加入的先后顺序从从左到右排列,一行排满之后转到下一行继续从左到右排列。要想让每一行中的组件向左、向右和居中排列,需要在构造时加参数: FlowLayout.LEFT 、 FlowLayout.RIGHT和 FlowLayout.CENTER 。居中是其缺省排列。构造函数 FlowLayout(int, int, int) 有三个参数分别表示对齐方式、组件水平间距和组件垂直间距。

Page 23: 面向对象的程序设计- Java

6.2 GUI 设计

2 、 GridLayout

组件按照加入的先后顺序从从左到右依次填满单元格,一行排满之后转到下一行继续。构造函数有四个参数:

GridLayout glo = new GridLayout(3,2,0,0)

分别是行单元格数、列单元格数、单元水平间距和单元垂直间距。

Page 24: 面向对象的程序设计- Java

6.2 GUI 设计

3 、 BorderLayout

容器分成北、南、东、西和中央五个区。在加入组件时,需要指明加入到哪个区中。

add("West", new Button (" 西 "));

add("Center",new Button(" 中 "));

Page 25: 面向对象的程序设计- Java

6.2 GUI 设计

4 、 GridBagLayout

GridBagLayout 是功能最为强大的布局管理器。它与 GridLayout 的区别在于:

组件可以占据网格中多个单元格;不同行和列的比例不必相等;单元格中的组件可以以不同的方式排列。

Page 26: 面向对象的程序设计- Java

Swing 界面要成为 Java 程序,必须能够处理用户事件。Swing 用一组称之为事件监听器( Event Listener )来处理事件。如果没有委托(注册)监听器,事件将不被处理。

6.3 Java 的事件处理模型

一、 Java 事件处理的委托模型

事件源事件源 事件监听器事件监听器委托(注册)委托(注册)

Page 27: 面向对象的程序设计- Java

6.3 Java 的事件处理模型

二、 Java 中,事件监听器是实现了相应接口的类。ActionListener :行为事件AdjustmentListener :调整事件FocusListener :焦点事件KeyListener :键盘事件ItemListener :选项事件MouseListener :鼠标事件MouseMotionListener :鼠标移动事件WindowListener :窗口事件

Page 28: 面向对象的程序设计- Java

6.3 Java 的事件处理模型

三、委托(注册)事件监听器addActionListener :JButton , JCheckBox , JCombobox , JTextfield 和JRadioButton

addAdjustmentListener : JScrollBar

addFocusListener :所有的 Swing 组件addKeyListener :所有的 Swing 组件addItemListener : JCheckBox , JCombobox 和JRadioButton

addMouseListener :所有的 Swing 组件addMouseMotionListener :所有的 Swing 组件addWindowListener :所有的 JWindow 和 JFrame 组件

Page 29: 面向对象的程序设计- Java

6.3 Java 的事件处理模型

注意:将组件加入到容器之前,必须将监听器与组件关联起来,并完成相应其他配置工作,否则,程序运行时,这些设置将被忽略。

Page 30: 面向对象的程序设计- Java

6.3 Java 的事件处理模型

四、事件处理方法实现监听器接口的类必须处理接口中所有的方法。ActionListener : actionPerformed(ActionEvent)

KeyListener : keyPressed(KeyEvent)

keyReleased(KeyEvent)

keyTyped(KeyEvent)

MouseListener : mouseClicked(MouseEvent)

mouseEntered(MouseEvent)

mouseExited(MouseEvent)

mousePressed(MouseEvent)

mouseReleased(MouseEvent)为了方便, Java提供了相应接口的适配器( Adapter )。

Page 31: 面向对象的程序设计- Java

6.3 Java 的事件处理模型

五、 Swing 中处理各组件事件的一般步骤

1 )新建一个组件(如 JButton )。

2 )将该组件添加到相应的面板(如 JPanel )。

3 )注册监听器以监听事件源产生的事件(如通过 ActionListener 来响应用户点击按钮)。 4)定义处理事件的方法(如在 ActionListener中的 actionPerformed 中定义相应方法)。

Page 32: 面向对象的程序设计- Java

6.3 Java 的事件处理模型

六、例import java.awt.*;import java.awt.event.*;import javax.swing.*;

public class Simple1{ private static JFrame frame; // 定义为静态变量以便 main 使用 private static JPanel myPanel; // 该面板用来放置按钮组件 private JButton button1; // 这里定义按钮组件 private JButton button2; // 以便让 ActionListener 使用

Page 33: 面向对象的程序设计- Java

6.3 Java 的事件处理模型

public Simple1() { // 构造器 , 建立图形界面 myPanel = new JPanel(); // 新建面板 button1 = new JButton(" 按钮 1"); // 新建按钮 1 button2 = new JButton(" 按钮 2"); // 新建按钮 1

SimpleListener ourListener = new SimpleListener();

// 建立一个 actionlistener 让两个按钮共享 button1.addActionListener(ourListener); button2.addActionListener(ourListener);

myPanel.add(button1); // 添加按钮到面板 myPanel.add(button2); }

Page 34: 面向对象的程序设计- Java

6.3 Java 的事件处理模型 private class SimpleListener implements ActionListener {

public void actionPerformed(ActionEvent e){ // 利用 getActionCommand获得按钮名称 // 也可以利用 getSource() 来实现 // if (e.getSource() ==button1)

String buttonName = e.getActionCommand(); if (buttonName.equals(" 按钮 1")) JOptionPane.showMessageDialog(frame, " 按钮 1 被点击 "); else if (buttonName.equals(" 按钮 2")) JOptionPane.showMessageDialog(frame, " 按钮 2 被点击 "); else JOptionPane.showMessageDialog(frame, "Unknown event" ); } }

Page 35: 面向对象的程序设计- Java

6.3 Java 的事件处理模型

public static void main(String s[]){ Simple1 gui = new Simple1(); // 新建 Simple1 组件 frame = new JFrame("Simple1"); // 新建 JFrame // 处理关闭事件的通常方法 frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) {System.exit(0);} });

frame.getContentPane().add(myPanel); frame.pack(); frame.setVisible(true); }}

Page 36: 面向对象的程序设计- Java

6.3 Java 的事件处理模型

程序运行结果:

Page 37: 面向对象的程序设计- Java

6.4 常见事件处理

一、行为事件接口: ActionListener

注册: addActionListener(ActionListener)

处理: actionPerformed(ActionEvent evt)

判 断 事 件 源 : getSource() 和getActionCommand()

判断是否同时按下其他键: getModifiers()

动作命令( action command )是与按钮、菜单等相关联的文本,如它们的标签。通过组件的setActionCommand(String) 方法,可以设置不同的动作命令。多用于多个组件可激发同样事件时。

Page 38: 面向对象的程序设计- Java

接口: KeyListener

注册: add KeyListener(KeyListener)

处理: keyPressed(KeyEvent) keyReleased(KeyEvent)

keyTyped(KeyEvent)

6.4 常见事件处理

二、键盘事件

依赖平台和键盘布局

依赖平台和键盘布局

仅响应 Unicode字符键仅响应 Unicode字符键

判断按下 Unicode字符:键盘事件的 getKeyChar() 方法判断按下虚拟键码:键盘事件的 getKeyCode() 方法修改输入键码: setKeyChar(char) 与 setKeyCode(int)

Page 39: 面向对象的程序设计- Java

6.4 常见事件处理import javax.swing.*; import java.awt.event.*;import java.awt.*;

public class KeyEventDemo extends JApplet implements KeyListener, ActionListener { JTextArea displayArea; JTextField typingArea; static final String newline = "\n";

public void init() { JButton button = new JButton("Clear"); button.addActionListener(this);

typingArea = new JTextField(20); typingArea.addKeyListener(this);

Page 40: 面向对象的程序设计- Java

6.4 常见事件处理 displayArea = new JTextArea(); displayArea.setEditable(false); JScrollPane scrollPane = new JScrollPane(displayArea); scrollPane.setPreferredSize(new Dimension(375, 125));

JPanel contentPane = new JPanel(); contentPane.setLayout(new BorderLayout()); contentPane.add(typingArea, BorderLayout.NORTH); contentPane.add(scrollPane, BorderLayout.CENTER); contentPane.add(button, BorderLayout.SOUTH); setContentPane(contentPane); }

Page 41: 面向对象的程序设计- Java

6.4 常见事件处理 /** Handle the key typed event from the text field. */ public void keyTyped(KeyEvent e) { displayInfo(e, "KEY TYPED: "); }

/** Handle the key pressed event from the text field. */ public void keyPressed(KeyEvent e) { displayInfo(e, "KEY PRESSED: "); }

/** Handle the key released event from the text field. */ public void keyReleased(KeyEvent e) { displayInfo(e, "KEY RELEASED: "); }

Page 42: 面向对象的程序设计- Java

6.4 常见事件处理

/** Handle the button click. */ public void actionPerformed(ActionEvent e) { //Clear the text components. displayArea.setText(""); typingArea.setText("");

//Return the focus to the typing area. typingArea.requestFocus(); }

Page 43: 面向对象的程序设计- Java

6.4 常见事件处理 protected void displayInfo(KeyEvent e, String s){ String charString, keyCodeString, modString, tmpString;

char c = e.getKeyChar(); int keyCode = e.getKeyCode(); int modifiers = e.getModifiers();

if (Character.isISOControl(c)) { charString = "key character = " + "(an unprintable control character)"; } else { charString = "key character = ’" + c + "’"; } keyCodeString = "key code = " + keyCode + " (" + KeyEvent.getKeyText(keyCode) + ")";

Page 44: 面向对象的程序设计- Java

6.4 常见事件处理

modString = "modifiers = " + modifiers; tmpString = KeyEvent.getKeyModifiersText(modifiers); if (tmpString.length() > 0) { modString += " (" + tmpString + ")"; } else { modString += " (no modifiers)"; }

displayArea.append(s + newline + " " + charString + newline + " " + keyCodeString + newline + " " + modString + newline); }}

Page 45: 面向对象的程序设计- Java

6.4 常见事件处理

程序运行结果:

Page 46: 面向对象的程序设计- Java

6.4 常见事件处理

三、鼠标事件

接口: MouseListener

注册: addMouseListener(MouseListener)处理: mouseClicked(MouseEvent) mouseEntered(MouseEvent)

mouseExited(MouseEvent) mousePressed(MouseEvent) mouseReleased(MouseEvent)

Page 47: 面向对象的程序设计- Java

6.4 常见事件处理

鼠标事件的主要方法:getClickCount() , getPoint() , getX() , getY()判断是否按下其他键:

boolean isAltDown() boolean isControlDown() boolean isMetaDown() boolean isShiftDown()

getModifiersEx()-jdk1.4

String getMouseModifiersText(int modifiers)

Page 48: 面向对象的程序设计- Java

6.5 响应用户输入

例 1 :import javax.swing.*; import java.awt.*; import java.awt.event.*;

public class PasswordDemo {

public static void main(String[] argv) {

final JFrame f = new JFrame("PasswordDemo");

JLabel label = new JLabel("Enter the password: ");

JPasswordField passwordField = new JPasswordField(10);

passwordField.setEchoChar('#');

Page 49: 面向对象的程序设计- Java

6.5 响应用户输入

passwordField.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { JPasswordField input = (JPasswordField)e.getSource(); char[] password = input.getPassword(); if (isPasswordCorrect(password)) { JOptionPane.showMessageDialog(f, "Success! You typed the right password."); } else { JOptionPane.showMessageDialog(f, "Invalid password. Try again.", "Error Message", JOptionPane.ERROR_MESSAGE); } } });

Page 50: 面向对象的程序设计- Java

6.5 响应用户输入JPanel contentPane = new JPanel(new BorderLayout());

contentPane.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));

contentPane.add(label, BorderLayout.WEST);

contentPane.add(passwordField, BorderLayout.CENTER);

f.setContentPane(contentPane);

f.addWindowListener(new WindowAdapter() {

public void windowClosing(WindowEvent e) { System.exit(0); }

});

f.pack();

f.setVisible(true); }

Page 51: 面向对象的程序设计- Java

6.5 响应用户输入

private static boolean isPasswordCorrect(char[] input) {

char[] correctPassword = { 'b', 'u', 'g', 'a', 'b', 'o', 'o' };

if (input.length != correctPassword.length)

return false;

for (int i = 0; i < input.length; i ++)

if (input[i] != correctPassword[i])

return false;

return true;

}

}

Page 52: 面向对象的程序设计- Java

6.5 响应用户输入

运行结果:

Page 53: 面向对象的程序设计- Java

6.5 响应用户输入

例 2 :import java.awt.*;

import java.awt.event.*;

import javax.swing.*;

public class Demo extends JPanel implements ActionListener {

JButton myButton;

JTextField myTextField;

JLabel myLabel;

Page 54: 面向对象的程序设计- Java

6.5 响应用户输入 public Demo() { ImageIcon ButtonIcon = new ImageIcon("images/right.gif"); ImageIcon LabelIcon = new ImageIcon("images/middle.gif"); myButton = new JButton("Delete", ButtonIcon); myButton.setMnemonic(KeyEvent.VK_D); myButton.setToolTipText("delete the text."); myButton.addActionListener(this); myLabel = new JLabel("Show the text",LabelIcon,JLabel.CENTER); myTextField = new JTextField("",20); myTextField.addActionListener(this);

Page 55: 面向对象的程序设计- Java

6.5 响应用户输入

//Add Components to this container, using GridLayout. setLayout(new GridLayout()); add(myLabel); add(myButton); add(myTextField); }public void actionPerformed(ActionEvent e) { if (e.getSource() == myButton) { myTextField.setText(""); myLabel.setText("Please input text:"); } else if (e.getSource() == myTextField){ myLabel.setText(myTextField.getText()); } else { } }

Page 56: 面向对象的程序设计- Java

6.5 响应用户输入

public static void main(String[] args) { //Make sure we have nice window decorations. JFrame.setDefaultLookAndFeelDecorated(true); JFrame frame = new JFrame("Demo"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setContentPane(new Demo());

//Display the window. frame.pack(); frame.setVisible(true); }}

Page 57: 面向对象的程序设计- Java

6.5 响应用户输入

运行结果:

Page 58: 面向对象的程序设计- Java

6.5 响应用户输入

二、菜单一个典型的菜单系统

Page 59: 面向对象的程序设计- Java

6.5 响应用户输入

1. 菜单系统的组成

菜单系统一般菜单 可撕下菜单 帮助菜单

类 JMenuBar

选项 #1

菜单中的菜单

选项 #3

选项 #4

选项 #1

选项 #2

第三层菜单

选项 #3

选项 #1

选项 #2

类 JMenu

类 JMenuItem

选项 #2菜单容器

非菜单容器

Page 60: 面向对象的程序设计- Java

6.5 响应用户输入

2. 菜单类结构

Page 61: 面向对象的程序设计- Java

6.5 响应用户输入

3. 菜单设计与实现1 )创建菜单条: mMenuBar = new JMeunBar()

2 )创建不同的菜单并加入到菜单条中:mEditMenu = new JMenu("Edit");

mMenuBar.add(mEditMenu);

3 )为每个菜单创建更下一级的菜单项,并加入到菜单中:mCopyMenuItem = new JMenuItem("Copy");

mEditMenu.add(mCopyMenuItem)

Page 62: 面向对象的程序设计- Java

6.5 响应用户输入

4 ) 将 菜 单 条 加 入 到 容 器 中 。 只 有 实 现 了MenuContainer 接口的容器才能加入菜单条。

5 )为各菜单项注册监听器:

mCopyMenuItem.addActionListener(this);

6 )在监听器中进行相应处理。采用 getSource() 和getActionCommand() 方法判断用户点击的菜单和菜单项。

Page 63: 面向对象的程序设计- Java

6.5 响应用户输入

4 、其他菜单结构使用分隔线-菜单的 addSeparator() 方法,注意菜单项是按照加入的先后顺序排列在菜单中的。使用快捷键。有两种方法: (1) mCopyMenu=new

JMenuItem("Copy",new MenuShortcut('O'));

(2) mCopyMenu.setShortcut(new MenuShortcut('O'));

使 用 二级菜单 。 首 先 创 建 一 个 包含若干菜单 子项( JMenuItem )的菜单项( JMenu ),再把这个菜单项像菜单子项一样加到一级菜单项中。

Page 64: 面向对象的程序设计- Java

6.5 响应用户输入

使用检测盒菜单子项( JCheckboxMenuItem )( 1 )生成检测盒菜单子项

mc=new JCheckboxMenuItem("Cut")

( 2 )加入到菜单中。mEditMenu.add(mc);

注意:它引发的事件不是 ActionEvent ,而是选择事件ItemEvent ,所以要注册 ItemListener ,并具体实现其itemStateChanged(ItemEvent e) 事件。

Page 65: 面向对象的程序设计- Java

6.5 响应用户输入

5 、弹出式菜单 PopupMenu

弹出式菜单附在某一个组件或容器上,一般不可见,只有鼠标在该组件或容器单击右键时显示。( 1 )创建弹出式菜单。

JPopupMenu popM = new JPopupMenu();JMenuItem pi_1=new JMenuItem("open");popM.add(pi_1);pi_1.addActionListener(this);

( 2 )附在某个组件或容器上。btn1.add(popM);

( 3 ) 为 该 组 件 或 容 器注册鼠标 事 件 监 听 器MouserListener : btn1.addMouseListener(this) 。

Page 66: 面向对象的程序设计- Java

6.5 响应用户输入

( 4 )重载MouseListener 的mouseReleased ( MouseEvent e )方法,同时使用弹出式菜单的 show 方法显示。public void mouseReleased ( MouseEvent e ) {

if(e.isPopupTrigger()){

popM.show((Component)e.getSource(),

e.getX(),e.getY());

} }

Page 67: 面向对象的程序设计- Java

6.5 响应用户输入

例 MenuDemo :

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

public class MenuDemo extends JFrame implements ActionListener, ItemListener {

JTextArea output; JScrollPane scrollPane; String newline = "\n";

Page 68: 面向对象的程序设计- Java

6.5 响应用户输入

public MenuDemo() { JMenuBar menuBar; JMenu menu, submenu; JMenuItem menuItem; JRadioButtonMenuItem rbMenuItem; JCheckBoxMenuItem cbMenuItem;

addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } });

Page 69: 面向对象的程序设计- Java

6.5 响应用户输入

Container contentPane = getContentPane(); output = new JTextArea(5, 30); output.setEditable(false); scrollPane = new JScrollPane(output); contentPane.add(scrollPane, BorderLayout.CENTER);

//Create the menu bar. menuBar = new JMenuBar(); setJMenuBar(menuBar);

//Build the first menu. menu = new JMenu("A Menu"); menu.setMnemonic(KeyEvent.VK_A); menu.getAccessibleContext().setAccessibleDescription( "The only menu in this program that has menu items"); menuBar.add(menu);

Page 70: 面向对象的程序设计- Java

6.5 响应用户输入

menuItem = new JMenuItem("A text-only menu item", KeyEvent.VK_T); menuItem.setAccelerator(KeyStroke.getKeyStroke( KeyEvent.VK_1, ActionEvent.ALT_MASK)); menuItem.getAccessibleContext().setAccessibleDescription( "This doesn't really do anything"); menuItem.addActionListener(this); menu.add(menuItem);

menuItem = new JMenuItem("Both text and icon", new ImageIcon("images/middle.gif")); menuItem.setMnemonic(KeyEvent.VK_B); menuItem.addActionListener(this); menu.add(menuItem);

Page 71: 面向对象的程序设计- Java

6.5 响应用户输入

//a group of radio button menu items menu.addSeparator(); ButtonGroup group = new ButtonGroup(); rbMenuItem = new JRadioButtonMenuItem("A radio button menu item"); rbMenuItem.setSelected(true); rbMenuItem.setMnemonic(KeyEvent.VK_R); group.add(rbMenuItem); rbMenuItem.addActionListener(this); menu.add(rbMenuItem); rbMenuItem = new JRadioButtonMenuItem("Another one"); rbMenuItem.setMnemonic(KeyEvent.VK_O); group.add(rbMenuItem); rbMenuItem.addActionListener(this); menu.add(rbMenuItem);

Page 72: 面向对象的程序设计- Java

6.5 响应用户输入 //a group of check box menu items menu.addSeparator(); cbMenuItem = new JCheckBoxMenuItem("A check box menu item"); cbMenuItem.setMnemonic(KeyEvent.VK_C); cbMenuItem.addItemListener(this); menu.add(cbMenuItem); cbMenuItem = new JCheckBoxMenuItem("Another one"); cbMenuItem.setMnemonic(KeyEvent.VK_H); cbMenuItem.addItemListener(this); menu.add(cbMenuItem);

//a submenu menu.addSeparator(); submenu = new JMenu("A submenu"); submenu.setMnemonic(KeyEvent.VK_S);

Page 73: 面向对象的程序设计- Java

6.5 响应用户输入 menuItem = new JMenuItem("An item in the submenu"); menuItem.setAccelerator(KeyStroke.getKeyStroke( KeyEvent.VK_2, ActionEvent.ALT_MASK)); menuItem.addActionListener(this); submenu.add(menuItem);

menuItem = new JMenuItem("Another item"); menuItem.addActionListener(this); submenu.add(menuItem); menu.add(submenu);

menu = new JMenu(“Another Menu”); // 另一个菜单 menu.setMnemonic(KeyEvent.VK_N); menu.getAccessibleContext().setAccessibleDescription( "This menu does nothing"); menuBar.add(menu); }

Page 74: 面向对象的程序设计- Java

6.5 响应用户输入public void actionPerformed(ActionEvent e) { JMenuItem source = (JMenuItem)(e.getSource()); String s = "Action event detected." + newline + " Event source: " + source.getText() + " (an instance of " + getClassName(source) + ")"; output.append(s + newline); }

public void itemStateChanged(ItemEvent e) { JMenuItem source = (JMenuItem)(e.getSource()); String s = "Item event detected." + newline + " Event source: " + source.getText() + " (an instance of " + getClassName(source) + ")" + newline + " New state: " + ((e.getStateChange() == ItemEvent.SELECTED) ? "selected":"unselected"); output.append(s + newline); }

Page 75: 面向对象的程序设计- Java

6.5 响应用户输入

// Returns just the class name -- no package info. protected String getClassName(Object o) { String classString = o.getClass().getName(); int dotIndex = classString.lastIndexOf("."); return classString.substring(dotIndex+1); }

public static void main(String[] args) { MenuDemo window = new MenuDemo();

window.setTitle("MenuDemo"); window.setSize(450, 260); window.setVisible(true); } }

Page 76: 面向对象的程序设计- Java

6.5 响应用户输入

运行结果:

Page 77: 面向对象的程序设计- Java

6.6 小结

重要的是,了解类及其常用方法。

创建类的实例new

创建类的实例new

设计好容器层次

设计好容器层次

创建输出管理器setLayout

创建输出管理器setLayout

加到上一级容器中 add

加到上一级容器中 add

定义事件的处理

监听器

定义事件的处理

监听器