201871010126 王亚涛 《面向对象程序设计 Java》 第十五周学习总结
|
内容 |
这个作业属于哪个课程 |
https://www.cnblogs.com/nwnu-daizh/ |
这个作业的要求在哪里 |
|
作业学习目标 |
(1) 掌握菜单组件用途及常用API; (2) 掌握对话框组件用途及常用API; (3) 学习设计简单应用程序的GUI。 |
随笔博文正文内容包括:
第一部分:总结菜单、对话框两类组件用途及常用API(30分)
1.Java菜单(菜单条、菜单和菜单项)
有两种类型的菜单:
下拉式菜单和弹出式菜单。
菜单与JComboBox和JCheckBox不同,它们在界面中是一直可见的。
菜单与JComboBox的相同之处是每次只可选择一个项目。
在下拉式菜单或弹出式菜单中选择一个选项就产生一个ActionEvent事件。该事件被发送给那个选项的监视器,事件的意义由监视器解释。
1.1 菜单条、菜单和菜单项
下拉式菜单通过出现在菜单条上的名字可视化表示,菜单条(JMenuBar)通常出现在JFrame的顶部,一个菜单条显示多个下拉式菜单的名字。
可以用两种方式来激活下拉式菜单。一种是按下鼠标的按钮,并保持按下状态,移动鼠标,直至释放鼠标完成选择,高亮度显示的菜单项即为所选择的。
另一种方式是当光标位于菜单条中的菜单名上时,点击鼠标,在这种情况下,菜单会展开,且高亮度显示菜单项。
一个菜单条可以放多个菜单(JMenu),每个菜单又可以有许多菜单项(JMenuItem)。
例如,Eclipse环境的菜单条有File、Edit、Source、Refactor等菜单,每个菜单又有许多菜单项。例如,File菜单有New、Open File、Close 、Close All等菜单项。
向窗口增设菜单的方法是:
先创建一个菜单条对象,然后再创建若干菜单对象,把这些菜单对象放在菜单条里,再按要求为每个菜单对象添加菜单项。
菜单中的菜单项也可以是一个完整的菜单。由于菜单项又可以是另一个完整菜单,因此可以构造一个层次状菜单结构。
1.1.1.菜单条
类JMenuBar的实例就是菜单条。例如,以下代码创建菜单条对象menubar:
JMenuBar menubar = new JMenuBar();
在窗口中增设菜单条,必须使用JFrame类中的setJMenuBar()方法。例如,代码:
setJMenuBar(menubar);
类JMenuBar的常用方法有:
- add(JMenu m):将菜单m加入到菜单条中。
- countJMenus():获得菜单条中菜单条数。
- getJMenu(int p):取得菜单条中的菜单。
- remove(JMenu m):删除菜单条中的菜单m。
1.1.2. 菜单
由类JMenu创建的对象就是菜单。类JMenu的常用方法如下:
- JMenu():建立一个空标题的菜单。
- JMenu(String s):建立一个标题为s的菜单。
- add(JMenuItem item):向菜单增加由参数item指定的菜单选项。
- add(JMenu menu):向菜单增加由参数menu指定的菜单。实现在菜单嵌入子菜单。
- addSeparator():在菜单选项之间画一条分隔线。
- getItem(int n):得到指定索引处的菜单项。
- getItemCount():得到菜单项数目。
- insert(JMenuItem item,int n):在菜单的位置n插入菜单项item.
- remove(int n):删除菜单位置n的菜单项
- removeAll():删除菜单的所有菜单项。
1.1.3.菜单项
类JMenuItem 的实例就是菜单项。类JMenuItem的常用方法如下:
- JMenuItem():构造无标题的菜单项。
- JMenuItem(String s):构造有标题的菜单项。
- setEnabled(boolean b):设置当前单项是否可被选择。
- isEnabled():返回当前菜单项是否可被用户选择。
- getLabel():得到菜单项的名称。
- setLabel():设置菜单选项的名称。
- addActionListener(ActionListener e):为菜单项设置监视器。监视器接受点击某个菜单的动作事件。
1.1.4. 处理菜单事件
菜单的事件源是用鼠标点击某个菜单项。
处理该事件的接口是ActionListener,
要实现的接口方法是actionPerformed(ActionEvent e),
获得事件源的方法getSource().
1.1.5. 嵌入子菜单
创建了一个菜单,并创建多个菜单项,其中某个菜单项又是一个(含其他菜单项的)菜单,这就构成菜单嵌套。
例如,将上述程序中的有关代码改成如下:
Menu menu1,menu2,item4;
MenuItem item3,item5,item6,item41,item42;
另插入以下代码创建item41和item42菜单项,并把它们加入到item4菜单中:
item41= new MenuItem(“东方红”);
item42 = new MenuItem(“牡丹”);
item4.add(item41);
item4.add(item42);
则点击item4菜单时,又会打开两个菜单项供选择。
1.1.6. 向菜单增加退出项
增设一个新的菜单项,对该菜单项加入监视,对应的监视方法中使用System.exit()方法,就能实现单击该菜单项时退出Java运行环境。
例如,以下示意代码:
…
item7 = new MenuItem(“退出”);
item7.addActionListener(this);
…
public void actionPerformed(ActionEvent e){
if(e.getSource()==item7){
System.exit(0);
}
}
1.1.7.设置菜单项的快捷键
用MenuShortcut类为菜单项设置快捷键。构造方法是MenuShortcut(int key)。其中key可以取值KeyEvent.VK_A至KenEvent.VK_Z,也可以取 ‘a’到 ‘z’键码值。
菜单项使用setShortcut(MenuShortcut k)方法来设置快捷键。
例如,以下代码设置字母e为快捷键。
class Herwindow extends Frame implements ActionListener{
MenuBar menbar;
Menu menu;
MenuItem item;
MenuShortcut shortcut = new MenuShortcut(KeyEvent.VK_E);
…
item.setShortcut(shortcut);
…
}
1.2 选择框菜单项
菜单也可以包含具有持久的选择状态的选项,这种特殊的菜单可由JCheckBoxMenuItem类来定义。
JCheckBoxMenuItem对象像选择框一样,能表示一个选项被选中与否,也可以作为一个菜单项加到下拉菜单中。
点击JCheckBoxMenuItem菜单时,就会在它的左边出现打勾符号或清除打勾符号。例如,在类MenuWindow中,将代码
addItem(menu1,“跑步”,this);addItem(menu1,”跳绳”,this);
改写成以下代码,就将两个普通菜单项“跑步“和“跳绳”改成两个选择框菜单项:
JCheckBoxMenuItem item1 = new JCheckBoxMenuItem(“跑步”);
JCheckBoxMenuItem item2 = new JCheckBoxMenuItem(“跳绳”);
item1.setActionCommand(“跑步”);
item1.addActionListener(this);
menu1.add(item1);
item2.setActionCommand(“跳绳”);
item2.addActionListener(this);
menu1.add(item2);
2.对话框
2.1.显示一个错误对话框:
JOptionPane.showMessageDialog(null,"错误信息","标题",JOptionPane.ERROR_MESSAGE);
2.2.显示一个内部信息对话框,需要母体frame:
JOptionPane.showInternalMessageDialog(frame, "信息","标题", JOptionPane.INFORMATION_MESSAGE);
2.3.显示一个信息面板,其 options 为 "yes/no",message 为 'choose one':
JOptionPane.showConfirmDialog(null, "选择其中一个", "标题", JOptionPane.YES_NO_OPTION);
2.4.显示一个内部信息对话框,其 options 为 "yes/no/cancel",message 为 'please choose one',并具有 title 信息:
JOptionPane.showInternalConfirmDialog(frame,
"please choose one", "information",
JOptionPane.YES_NO_CANCEL_OPTION,
JOptionPane.INFORMATION_MESSAGE);
2.5.显示一个警告对话框,其 options 为 OK、CANCEL,title 为 'Warning',message 为 'Click OK to continue':
Object[] options = { "OK", "CANCEL" };
JOptionPane.showOptionDialog(null, "Click OK to continue", "Warning",
JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE,
null, options, options[0]);
2.6.显示一个要求用户键入 String 的对话框:
String inputValue = JOptionPane.showInputDialog("Please input a value");
2.7.显示一个要求用户选择 String 的对话框:
Object[] possibleValues = { "First", "Second", "Third" };
Object selectedValue = JOptionPane.showInputDialog(null, "Choose one", "Input",
JOptionPane.INFORMATION_MESSAGE, null,
possibleValues, possibleValues[0]);
第二部分:实验内容和步骤
实验1: 导入第12章示例程序,测试程序并进行组内讨论。
测试程序1
l 在elipse IDE中调试运行教材512页程序12-8,结合运行结果理解程序;
l 掌握菜单的创建、菜单事件监听器、复选框和单选按钮菜单项、弹出菜单以及快捷键和加速器的用法。
l 记录示例代码阅读理解中存在的问题与疑惑。
例题12.8程序代码及注释如下:
package menu; import java.awt.*; import javax.swing.*; /** * @version 1.25 2018-04-10 * @author Cay Horstmann */ public class MenuTest { public static void main(String[] args) { EventQueue.invokeLater(() -> { var frame = new MenuFrame(); frame.setTitle("MenuTest");//设计框架名称 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//窗口关闭设置为可用 frame.setVisible(true);//将框架设置为可见 }); } }
package menu; import java.awt.event.*; import javax.swing.*; /** * A frame with a sample menu bar. 一个带有示例菜单栏的框架。 */ public class MenuFrame extends JFrame { //私有属性 private static final int DEFAULT_WIDTH = 300; private static final int DEFAULT_HEIGHT = 200;//定义窗口大小宽300,高200 private Action saveAction; private Action saveAsAction; private JCheckBoxMenuItem readonlyItem; private JPopupMenu popup; /** * A sample action that prints the action name to System.out. *将操作名称打印到System.out的示例操作。 */ class TestAction extends AbstractAction { public TestAction(String name) { super(name);//super:完成父类的构造 } public void actionPerformed(ActionEvent event) { System.out.println(getValue(Action.NAME) + " selected.");//实现接口方法 } } public MenuFrame() { setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT); var fileMenu = new JMenu("File");//菜单对象 fileMenu.add(new TestAction("New"));//将TestAction对象添加到菜单中 // demonstrate accelerators 演示加速器 var openItem = fileMenu.add(new TestAction("Open")); openItem.setAccelerator(KeyStroke.getKeyStroke("ctrl O"));//调用setAccelerator方法将加速器键关联到一个菜单项上,使用KeyStroke类型的对象作为参数,将CTRL+O关联到OpenItem菜单项 fileMenu.addSeparator();//Jmenu的一个方法将新分隔符追加到菜单的末尾。 saveAction = new TestAction("Save"); JMenuItem saveItem = fileMenu.add(saveAction); saveItem.setAccelerator(KeyStroke.getKeyStroke("ctrl S")); saveAsAction = new TestAction("Save As");//将要执行的行为赋值给菜单子项 fileMenu.add(saveAsAction); fileMenu.addSeparator(); fileMenu.add(new AbstractAction("Exit") { public void actionPerformed(ActionEvent event) { System.exit(0); } }); // demonstrate checkbox and radio button menus演示复选框和单选按钮菜单 readonlyItem = new JCheckBoxMenuItem("Read-only"); readonlyItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { boolean saveOk = !readonlyItem.isSelected(); saveAction.setEnabled(saveOk); saveAsAction.setEnabled(saveOk); } }); var group = new ButtonGroup(); var insertItem = new JRadioButtonMenuItem("Insert"); insertItem.setSelected(true); var overtypeItem = new JRadioButtonMenuItem("Overtype"); group.add(insertItem); group.add(overtypeItem); // demonstrate icons 演示图标 var cutAction = new TestAction("Cut"); cutAction.putValue(Action.SMALL_ICON, new ImageIcon("cut.gif")); var copyAction = new TestAction("Copy"); copyAction.putValue(Action.SMALL_ICON, new ImageIcon("copy.gif")); var pasteAction = new TestAction("Paste"); pasteAction.putValue(Action.SMALL_ICON, new ImageIcon("paste.gif")); var editMenu = new JMenu("Edit"); editMenu.add(cutAction); editMenu.add(copyAction); editMenu.add(pasteAction); // demonstrate nested menus // 演示嵌套菜单 var optionMenu = new JMenu("Options"); optionMenu.add(readonlyItem); optionMenu.addSeparator(); optionMenu.add(insertItem); optionMenu.add(overtypeItem); editMenu.addSeparator(); editMenu.add(optionMenu); // demonstrate mnemonics // 助记符演示 var helpMenu = new JMenu("Help"); helpMenu.setMnemonic('H'); var indexItem = new JMenuItem("Index"); indexItem.setMnemonic('I'); helpMenu.add(indexItem); // you can also add the mnemonic key to an action // 可以将助记键添加到动作中。 var aboutAction = new TestAction("About"); aboutAction.putValue(Action.MNEMONIC_KEY, new Integer('A')); helpMenu.add(aboutAction); // add all top-level menus to menu bar // 将所有顶级菜单添加到菜单栏 var menuBar = new JMenuBar(); setJMenuBar(menuBar); menuBar.add(fileMenu); menuBar.add(editMenu); menuBar.add(helpMenu); // demonstrate pop-ups // 演示弹出窗口 popup = new JPopupMenu(); popup.add(cutAction); popup.add(copyAction); popup.add(pasteAction); var panel = new JPanel(); panel.setComponentPopupMenu(popup); add(panel); } }
运行截图如下:
测试程序2
l 在elipse IDE中调试运行教材517页程序12-9,结合运行结果理解程序;
l 掌握工具栏和工具提示的用法;
例题12.9程序代码及注释如下:
package toolBar; import java.awt.*; import javax.swing.*; /** * @version 1.15 2018-04-10 * @author Cay Horstmann */ public class ToolBarTest { public static void main(String[] args) { EventQueue.invokeLater(() -> { var frame = new ToolBarFrame(); frame.setTitle("ToolBarTest"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); }); } }
package toolBar; import java.awt.*; import java.awt.event.*; import javax.swing.*; /** * A frame with a toolbar and menu for color changes. */ public class ToolBarFrame extends JFrame { private static final int DEFAULT_WIDTH = 300; private static final int DEFAULT_HEIGHT = 200;//定义两个私有属性 private JPanel panel; public ToolBarFrame()//定义工具提示类 { setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT); // add a panel for color change panel = new JPanel();//创建新的JPanel add(panel, BorderLayout.CENTER); // set up actions //建立动作 var blueAction = new ColorAction("Blue", new ImageIcon("blue-ball.gif"), Color.BLUE); var yellowAction = new ColorAction("Yellow", new ImageIcon("yellow-ball.gif"), Color.YELLOW); var redAction = new ColorAction("Red", new ImageIcon("red-ball.gif"), Color.RED); var exitAction = new AbstractAction("Exit", new ImageIcon("exit.gif")) { public void actionPerformed(ActionEvent event) { System.exit(0); } }; exitAction.putValue(Action.SHORT_DESCRIPTION, "Exit"); // populate toolbar var bar = new JToolBar(); //用Action对象填充工具栏 bar.add(blueAction); bar.add(yellowAction); bar.add(redAction); bar.addSeparator();//用分隔符将按钮分组 bar.add(exitAction); add(bar, BorderLayout.NORTH); // populate menu var menu = new JMenu("Color");//显示颜色的菜单 menu.add(yellowAction);//在菜单添加颜色动作 menu.add(blueAction); menu.add(redAction); menu.add(exitAction); var menuBar = new JMenuBar(); menuBar.add(menu); setJMenuBar(menuBar); } /** * The color action sets the background of the frame to a given color.//color操作将背景设置为给定的颜色 */ class ColorAction extends AbstractAction { public ColorAction(String name, Icon icon, Color c) { putValue(Action.NAME, name);//动作名称,显示在按钮和菜单 putValue(Action.SMALL_ICON, icon);//存储小图标的地方;显示在按钮、菜单项或工具栏中 putValue(Action.SHORT_DESCRIPTION, name + " background"); putValue("Color", c); } public void actionPerformed(ActionEvent event) { Color c = (Color) getValue("Color"); panel.setBackground(c); } }
运行截图如下:
测试程序3
l 在elipse IDE中调试运行教材544页程序12-15、12-16,结合运行结果理解程序;
l 掌握选项对话框的用法。
l 记录示例代码阅读理解中存在的问题与疑惑。
例题12.15、12.16程序代码及注释如下:
package optionDialog; import java.awt.*; import javax.swing.*; /** * @version 1.35 2018-04-10 * @author Cay Horstmann */ public class OptionDialogTest { public static void main(String[] args) { EventQueue.invokeLater(() -> { var frame = new OptionDialogFrame(); frame.setTitle("OptionDialogTest"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); }); } }
package optionDialog; import java.awt.*; import java.awt.event.*; import java.awt.geom.*; import java.util.*; import javax.swing.*; /** * A frame that contains settings for selecting various option dialogs. */ //包含用于选择各种选项对话框的设置的框架 public class OptionDialogFrame extends JFrame//对话框 { private ButtonPanel typePanel; private ButtonPanel messagePanel; private ButtonPanel messageTypePanel; private ButtonPanel optionTypePanel; private ButtonPanel optionsPanel; private ButtonPanel inputPanel; private String messageString = "Message"; private Icon messageIcon = new ImageIcon("blue-ball.gif"); private Object messageObject = new Date(); private Component messageComponent = new SampleComponent(); public OptionDialogFrame() { var gridPanel = new JPanel(); gridPanel.setLayout(new GridLayout(2, 3)); typePanel = new ButtonPanel("Type", "Message", "Confirm", "Option", "Input"); messageTypePanel = new ButtonPanel("Message Type", "ERROR_MESSAGE", "INFORMATION_MESSAGE", "WARNING_MESSAGE", "QUESTION_MESSAGE", "PLAIN_MESSAGE"); messagePanel = new ButtonPanel("Message", "String", "Icon", "Component", "Other", "Object[]"); optionTypePanel = new ButtonPanel("Confirm", "DEFAULT_OPTION", "YES_NO_OPTION", "YES_NO_CANCEL_OPTION", "OK_CANCEL_OPTION"); optionsPanel = new ButtonPanel("Option", "String[]", "Icon[]", "Object[]"); inputPanel = new ButtonPanel("Input", "Text field", "Combo box"); gridPanel.add(typePanel); gridPanel.add(messageTypePanel); gridPanel.add(messagePanel); gridPanel.add(optionTypePanel); gridPanel.add(optionsPanel); gridPanel.add(inputPanel); // add a panel with a Show button添加带有“显示”按钮的面板 var showPanel = new JPanel(); var showButton = new JButton("Show"); showButton.addActionListener(new ShowAction()); showPanel.add(showButton); add(gridPanel, BorderLayout.CENTER); add(showPanel, BorderLayout.SOUTH); pack(); } /** * Gets the currently selected message. * 获取当前选定的邮件 * @return a string, icon, component, or object array, depending on the Message panel selection */ public Object getMessage() { String s = messagePanel.getSelection(); if (s.equals("String")) return messageString; else if (s.equals("Icon")) return messageIcon; else if (s.equals("Component")) return messageComponent; else if (s.equals("Object[]")) return new Object[] { messageString, messageIcon, messageComponent, messageObject }; else if (s.equals("Other")) return messageObject; else return null; } /** * Gets the currently selected options. * 获取当前选定的选项 * @return an array of strings, icons, or objects, depending on the Option panel selection */ public Object[] getOptions() { String s = optionsPanel.getSelection(); if (s.equals("String[]")) return new String[] { "Yellow", "Blue", "Red" }; else if (s.equals("Icon[]")) return new Icon[] { new ImageIcon("yellow-ball.gif"), new ImageIcon("blue-ball.gif"), new ImageIcon("red-ball.gif") }; else if (s.equals("Object[]")) return new Object[] { messageString, messageIcon, messageComponent, messageObject }; else return null; } /** * Gets the selected message or option type * 获取选定的消息或选项类型 * @param panel the Message Type or Confirm panel * @return the selected XXX_MESSAGE or XXX_OPTION constant from the JOptionPane class */ public int getType(ButtonPanel panel) { String s = panel.getSelection(); try { return JOptionPane.class.getField(s).getInt(null); } catch (Exception e) { return -1; } } /** * The action listener for the Show button shows a Confirm, Input, Message, or Option dialog * “显示”按钮的操作侦听器显示确认、输入、消息或选项对话框; * depending on the Type panel selection. * 取决于类型面板选择 */ private class ShowAction implements ActionListener { public void actionPerformed(ActionEvent event) { if (typePanel.getSelection().equals("Confirm")) JOptionPane.showConfirmDialog( OptionDialogFrame.this, getMessage(), "Title", getType(optionTypePanel), getType(messageTypePanel)); else if (typePanel.getSelection().equals("Input")) { if (inputPanel.getSelection().equals("Text field")) JOptionPane.showInputDialog( OptionDialogFrame.this, getMessage(), "Title", getType(messageTypePanel)); else JOptionPane.showInputDialog(OptionDialogFrame.this, getMessage(), "Title", getType(messageTypePanel), null, new String[] { "Yellow", "Blue", "Red" }, "Blue"); } else if (typePanel.getSelection().equals("Message")) JOptionPane.showMessageDialog( OptionDialogFrame.this, getMessage(), "Title", getType(messageTypePanel)); else if (typePanel.getSelection().equals("Option")) JOptionPane.showOptionDialog( OptionDialogFrame.this, getMessage(), "Title", getType(optionTypePanel), getType(messageTypePanel), null, getOptions(), getOptions()[0]); } } } /** * A component with a painted surface */ class SampleComponent extends JComponent { public void paintComponent(Graphics g) { var g2 = (Graphics2D) g; var rect = new Rectangle2D.Double(0, 0, getWidth() - 1, getHeight() - 1); g2.setPaint(Color.YELLOW); g2.fill(rect); g2.setPaint(Color.BLUE); g2.draw(rect); } public Dimension getPreferredSize() { return new Dimension(10, 10); } }
package optionDialog; import javax.swing.*; /** * A panel with radio buttons inside a titled border.在有标题的边框内有单选按钮的面板 */ public class ButtonPanel extends JPanel { private ButtonGroup group; /** * Constructs a button panel. * @param title the title shown in the border * @param options an array of radio button labels */ public ButtonPanel(String title, String... options) { setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), title)); setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); group = new ButtonGroup(); // make one radio button for each option//给每个对象一个单选按钮 for (String option : options) { var button = new JRadioButton(option); button.setActionCommand(option); add(button);//添加按纽 group.add(button); button.setSelected(option == options[0]); } } /** * Gets the currently selected option. * @return the label of the currently selected radio button. */ public String getSelection() { return group.getSelection().getActionCommand(); } }
运行截图如下:
测试程序4
l 在elipse IDE中调试运行教材552页程序12-17、12-18,结合运行结果理解程序;
l 掌握对话框的创建方法;
l 记录示例代码阅读理解中存在的问题与疑惑。
例题12.17、12.18程序代码及注释如下:
package dialog; import java.awt.*; import javax.swing.*; /** * @version 1.35 2018-04-10 * @author Cay Horstmann */ public class DialogTest { public static void main(String[] args) { EventQueue.invokeLater(() -> { var frame = new DialogFrame(); frame.setTitle("DialogTest"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); }); } }
package dialog; import javax.swing.JFrame; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; /** * A frame with a menu whose File->About action shows a dialog. * 带有菜单的框架,其文件关于操作显示一个对话框 */ public class DialogFrame extends JFrame { private static final int DEFAULT_WIDTH = 300; private static final int DEFAULT_HEIGHT = 200; private AboutDialog dialog; public DialogFrame() { setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT); // 构造文件菜单 var menuBar = new JMenuBar(); setJMenuBar(menuBar); var fileMenu = new JMenu("File"); menuBar.add(fileMenu); // 添加和退出菜单项 var aboutItem = new JMenuItem("About"); aboutItem.addActionListener(event -> { if (dialog == null) // first time dialog = new AboutDialog(DialogFrame.this); dialog.setVisible(true); // 弹出对话框 }); fileMenu.add(aboutItem); // 退出项退出程序 var exitItem = new JMenuItem("Exit"); exitItem.addActionListener(event -> System.exit(0)); fileMenu.add(exitItem); } }
package dialog; import java.awt.BorderLayout; import javax.swing.JButton; import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; /** * A sample modal dialog that displays a message and waits for the user to click * 显示消息并等待用户敲击的示例模式对话框 * the OK button. */ public class AboutDialog extends JDialog { public AboutDialog(JFrame owner) { super(owner, "About DialogTest", true); // 将HTML标签添加到中心 add( new JLabel( "<html><h1><i>Core Java</i></h1><hr>By Cay Horstmann</html>"), BorderLayout.CENTER); // 确定按钮关闭对话框 var ok = new JButton("OK"); ok.addActionListener(event -> setVisible(false)); // 将“确定”按钮添加到南部边界 var panel = new JPanel(); panel.add(ok); add(panel, BorderLayout.SOUTH); pack(); } }
运行截图如下:
测试程序5
l 在elipse IDE中调试运行教材556页程序12-19、12-20,结合运行结果理解程序;
l 掌握对话框的数据交换用法;
l 记录示例代码阅读理解中存在的问题与疑惑。
例题12.19、12.20程序代码及注释如下:
package dataExchange; import java.awt.*; import javax.swing.*; /** * @version 1.35 2018-04-10 * @author Cay Horstmann */ public class DataExchangeTest { public static void main(String[] args) { EventQueue.invokeLater(() -> { var frame = new DataExchangeFrame(); frame.setTitle("DataExchangeTest"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); }); } }
package dataExchange; import java.awt.*; import java.awt.event.*; import javax.swing.*; /** * A frame with a menu whose File->Connect action shows a password dialog. */ public class DataExchangeFrame extends JFrame { public static final int TEXT_ROWS = 20; public static final int TEXT_COLUMNS = 40; private PasswordChooser dialog = null; private JTextArea textArea; public DataExchangeFrame() { // 构造文件菜单 var mbar = new JMenuBar(); setJMenuBar(mbar); var fileMenu = new JMenu("File"); mbar.add(fileMenu); // 添加连接和退出菜单项 var connectItem = new JMenuItem("Connect"); connectItem.addActionListener(new ConnectAction()); fileMenu.add(connectItem); // 退出项退出程序 var exitItem = new JMenuItem("Exit"); exitItem.addActionListener(event -> System.exit(0)); fileMenu.add(exitItem); textArea = new JTextArea(TEXT_ROWS, TEXT_COLUMNS); add(new JScrollPane(textArea), BorderLayout.CENTER); pack(); } /** * The Connect action pops up the password dialog. */ private class ConnectAction implements ActionListener { public void actionPerformed(ActionEvent event) { // if first time, construct dialog if (dialog == null) dialog = new PasswordChooser(); // 设置默认值 dialog.setUser(new User("yourname", null)); // pop up dialog if (dialog.showDialog(DataExchangeFrame.this, "Connect")) { // if accepted, retrieve user input User u = dialog.getUser(); textArea.append("user name = " + u.getName() + ", password = " + (new String(u.getPassword())) + "\n"); } } } }
package dataExchange; /** * A user has a name and password. For security reasons, the password is stored as a char[], not a * String. */ public class User { private String name; private char[] password; public User(String aName, char[] aPassword) { name = aName; password = aPassword; } public String getName() { return name; } public char[] getPassword() { return password; } public void setName(String aName) { name = aName; } public void setPassword(char[] aPassword) { password = aPassword; } }
package dataExchange; import java.awt.BorderLayout; import java.awt.Component; import java.awt.Frame; import java.awt.GridLayout; import javax.swing.JButton; import javax.swing.JDialog; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JPasswordField; import javax.swing.JTextField; import javax.swing.SwingUtilities; /** * A password chooser that is shown inside a dialog. */ public class PasswordChooser extends JPanel { private JTextField username; private JPasswordField password; private JButton okButton; private boolean ok; private JDialog dialog; public PasswordChooser() { setLayout(new BorderLayout()); // construct a panel with user name and password fields var panel = new JPanel(); panel.setLayout(new GridLayout(2, 2)); panel.add(new JLabel("User name:")); panel.add(username = new JTextField("")); panel.add(new JLabel("Password:")); panel.add(password = new JPasswordField("")); add(panel, BorderLayout.CENTER); // create Ok and Cancel buttons that terminate the dialog okButton = new JButton("Ok"); okButton.addActionListener(event -> { ok = true; dialog.setVisible(false); }); var cancelButton = new JButton("Cancel"); cancelButton.addActionListener(event -> dialog.setVisible(false)); // add buttons to southern border var buttonPanel = new JPanel(); buttonPanel.add(okButton); buttonPanel.add(cancelButton); add(buttonPanel, BorderLayout.SOUTH); } /** * Sets the dialog defaults. * @param u the default user information */ public void setUser(User u) { username.setText(u.getName()); } /** * Gets the dialog entries. * @return a User object whose state represents the dialog entries */ public User getUser() { return new User(username.getText(), password.getPassword()); } /** * Show the chooser panel in a dialog. * @param parent a component in the owner frame or null * @param title the dialog window title */ public boolean showDialog(Component parent, String title) { ok = false; // 定位所有框架 Frame owner = null; if (parent instanceof Frame) owner = (Frame) parent; else owner = (Frame) SwingUtilities.getAncestorOfClass(Frame.class, parent); // if first time, or if owner has changed, make new dialog if (dialog == null || dialog.getOwner() != owner) { dialog = new JDialog(owner, true); dialog.add(this); dialog.getRootPane().setDefaultButton(okButton); dialog.pack(); } // 设置标题和显示对话框 dialog.setTitle(title); dialog.setVisible(true); return ok; } }
运行截图如下:
测试程序6
l 在elipse IDE中调试运行教材556页程序12-21、12-22、12-23,结合程序运行结果理解程序;
l 掌握文件对话框的用法;
l 记录示例代码阅读理解中存在的问题与疑惑。
例题12-21、12-22、12-23程序代码及注释如下:
package fileChooser; import java.awt.*; import javax.swing.*; /** * @version 1.26 2018-04-10 * @author Cay Horstmann */ public class FileChooserTest { public static void main(String[] args) { EventQueue.invokeLater(() -> { var frame = new ImageViewerFrame(); frame.setTitle("FileChooserTest"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); }); } }
package fileChooser; import java.io.*; import javax.swing.*; import javax.swing.filechooser.*; import javax.swing.filechooser.FileFilter; /** * A file view that displays an icon for all files that match a file filter. * 显示与文件筛选匹配的所有文件图标的文件视图 */ public class FileIconView extends FileView { private FileFilter filter; private Icon icon; /** * Constructs a FileIconView. * @param aFilter a file filter--all files that this filter accepts will be shown * with the icon. * @param anIcon--the icon shown with all accepted files. */ public FileIconView(FileFilter aFilter, Icon anIcon) { filter = aFilter; icon = anIcon; } public Icon getIcon(File f) { if (!f.isDirectory() && filter.accept(f)) return icon; else return null; } }
package fileChooser; import java.awt.*; import java.io.*; import javax.swing.*; /** * A file chooser accessory that previews images. */ public class ImagePreviewer extends JLabel { /** * Constructs an ImagePreviewer. * @param chooser the file chooser whose property changes trigger an image * change in this previewer */ public ImagePreviewer(JFileChooser chooser) { setPreferredSize(new Dimension(100, 100)); setBorder(BorderFactory.createEtchedBorder()); chooser.addPropertyChangeListener(event -> { if (event.getPropertyName() == JFileChooser.SELECTED_FILE_CHANGED_PROPERTY) { // 用户选择了一个新文件 File f = (File) event.getNewValue(); if (f == null) { setIcon(null); return; } // 将图像读入图标 var icon = new ImageIcon(f.getPath()); // 如果图标太大而无法容纳,请缩放它 if (icon.getIconWidth() > getWidth()) icon = new ImageIcon(icon.getImage().getScaledInstance( getWidth(), -1, Image.SCALE_DEFAULT)); setIcon(icon); } }); } }
package fileChooser; import java.io.*; import javax.swing.*; import javax.swing.filechooser.*; import javax.swing.filechooser.FileFilter; /** * A frame that has a menu for loading an image and a display area for the * loaded image. */ public class ImageViewerFrame extends JFrame { private static final int DEFAULT_WIDTH = 300; private static final int DEFAULT_HEIGHT = 400; private JLabel label; private JFileChooser chooser; public ImageViewerFrame() { setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT); // 设置菜单栏 var menuBar = new JMenuBar(); setJMenuBar(menuBar); var menu = new JMenu("File"); menuBar.add(menu); var openItem = new JMenuItem("Open"); menu.add(openItem); openItem.addActionListener(event -> { chooser.setCurrentDirectory(new File(".")); //显示文件选择器对话框 int result = chooser.showOpenDialog(ImageViewerFrame.this); // 如果接受图像文件,则将其设置为标签的图标l if (result == JFileChooser.APPROVE_OPTION) { String name = chooser.getSelectedFile().getPath(); label.setIcon(new ImageIcon(name)); pack(); } }); var exitItem = new JMenuItem("Exit"); menu.add(exitItem); exitItem.addActionListener(event -> System.exit(0)); // 使用标签显示图像 label = new JLabel(); add(label); // 设置文件选择器 chooser = new JFileChooser(); // accept all image files ending with .jpg, .jpeg, .gif var filter = new FileNameExtensionFilter( "Image files", "jpg", "jpeg", "gif"); chooser.setFileFilter(filter); chooser.setAccessory(new ImagePreviewer(chooser)); chooser.setFileView(new FileIconView(filter, new ImageIcon("palette.gif"))); } }
运行截图如下:
测试程序7
l 在elipse IDE中调试运行教材570页程序12-24,结合运行结果理解程序;
l 了解颜色选择器的用法。
l 记录示例代码阅读理解中存在的问题与疑惑。
例题12.24程序代码及注释如下:
package colorChooser; import javax.swing.*; /** * A frame with a color chooser panel */ public class ColorChooserFrame extends JFrame { private static final int DEFAULT_WIDTH = 300; private static final int DEFAULT_HEIGHT = 200; public ColorChooserFrame() { setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT); // 添加颜色选择器面板到框架 ColorChooserPanel panel = new ColorChooserPanel(); add(panel); } } 复制代码 复制代码 package colorChooser; import java.awt.Color; import java.awt.Frame; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JColorChooser; import javax.swing.JDialog; import javax.swing.JPanel; /** * A panel with buttons to pop up three types of color choosers */ public class ColorChooserPanel extends JPanel { public ColorChooserPanel() { JButton modalButton = new JButton("Modal"); modalButton.addActionListener(new ModalListener()); add(modalButton); JButton modelessButton = new JButton("Modeless"); modelessButton.addActionListener(new ModelessListener()); add(modelessButton); JButton immediateButton = new JButton("Immediate"); immediateButton.addActionListener(new ImmediateListener()); add(immediateButton); } /** * This listener pops up a modal color chooser */ private class ModalListener implements ActionListener { public void actionPerformed(ActionEvent event) { Color defaultColor = getBackground(); Color selected = JColorChooser.showDialog(ColorChooserPanel.this, "Set background", defaultColor); if (selected != null) setBackground(selected); } } /** * This listener pops up a modeless color chooser. The panel color is changed when the user * clicks the OK button. */ private class ModelessListener implements ActionListener { private JDialog dialog; private JColorChooser chooser; public ModelessListener() { chooser = new JColorChooser(); dialog = JColorChooser.createDialog(ColorChooserPanel.this, "Background Color", false /* not modal */, chooser, event -> setBackground(chooser.getColor()), null /* no Cancel button listener */); } public void actionPerformed(ActionEvent event) { chooser.setColor(getBackground()); dialog.setVisible(true); } } /** * This listener pops up a modeless color chooser. The panel color is changed immediately when * the user picks a new color. */ private class ImmediateListener implements ActionListener { private JDialog dialog; private JColorChooser chooser; public ImmediateListener() { chooser = new JColorChooser(); chooser.getSelectionModel().addChangeListener( event -> setBackground(chooser.getColor())); dialog = new JDialog((Frame) null, false /* not modal */); dialog.add(chooser); dialog.pack(); } public void actionPerformed(ActionEvent event) { chooser.setColor(getBackground()); dialog.setVisible(true); } } }
package colorChooser; import java.awt.*; import javax.swing.*; /** * @version 1.04 2015-06-12 * @author Cay Horstmann */ public class ColorChooserTest { public static void main(String[] args) { EventQueue.invokeLater(() -> { JFrame frame = new ColorChooserFrame(); frame.setTitle("ColorChooserTest"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); }); }
运行截图如下:
实验总结:(20分)
1):通过本次课程的学习让我们对Java中第十二章相关内容有了进一步的了解,在上周的学习的基础上添加了一些新的内容;在上课老师的讲解过程中学习了Java中的菜单及对话框和工具栏等相关知识, 掌握菜单组件用途及常用API;对话框组件用途及常用API; 学习了设计简单应用程序的GUI。
2):通过老师上课详细的讲解和实验过程中对不懂得知识的查找资料及同学的讲解我们对第十二章的知识点有了进一步的强化认识,在做作业的过程中遇到了一些问题,但都通过问同学或查资料一一解决了,在讨论的过程中了解了自己的不足,掌握了许多不知道不熟悉的知识,对菜单和对话框的相关知识进一步的理解与掌握。
3).通过这次的实验使我学到了不少实用的知识,并且锻炼了自己的动手能力;虽然在学习的过程中遇到了许多不懂得地方,但是课下都通过问同学及查找相关资料等一些方式都一一解决了;在这次实验中意识到自己的动手能力很差,应在课下多学习多交流,相信在以后的学习中,通过不断努力,我可以学到更多的关于Java编程的相关知识。