项目 |
内容 |
这个作业属于哪个课程 |
https://www.cnblogs.com/nwnu-daizh/ |
这个作业的要求在哪里 |
https://www.cnblogs.com/nwnu-daizh/p/11995615.html |
作业学习目标 |
(1)掌握GUI布局管理器用法; (2)掌握Java Swing文本输入组件用途及常用API; (3)掌握Java Swing选择输入组件用途及常用API。
|
第一部分:总结第十二章本周理论知识(25分)
一、 菜单
菜单创建 菜单项中的图标 复选框和单选按钮菜单项 弹出菜单 快捷键和加速器 启用和禁用菜单项 工具栏 工具提示
1. 网格组布局 (GridBagLayout):GridBagLayout与GridLayout有点相似,它也是 将组件排在格子里,但是GridBagLayout在网格 的基础上提供更复杂的布局。
2. GridBagLayout允许单个组件在一个单元中不填 满整个单元,而只是占用最佳大小,也允许单个 组件扩展成不止一个单元,并且可以用任意顺序 加入组件。
3. 定制布局管理器: 程序员可通过自己设计LayoutManager类来实现 特殊的布局方式。
4. 定制布局管理器需要实现LayoutManager接口, 并覆盖其中的方法。
5. 菜单的创建
●创建一个菜单栏
菜单栏是一个可以添加到容器组件任何位置的组件。通常放置在框架的项部。
JMenuBar menuBar=new JMenuBar();
●调用框架的setJMenuBar方法可将- -个菜单栏对象添加到框架上
frame .setJMenuBar ( menuBar) ;
●创建菜单对象,并将菜单对象添加到菜单栏中
JMenu editMenu=new Jmenu("Edit");menuBar.add(editMenu);
●向菜单对象添加一个菜单项。
JMenltem pasteltem=new JMenItem();editMenu.add(pasteltem);
●向菜单对象添加分隔符行。
editMenu. addSeperator();
●向菜单对象项添加子菜单。
JMenu optionsMenu=new Jmenu("option");editMenu. add(optionsMenu);
6.菜单事件监听器的插入方法
● 当用户选择菜单时,将触发-一个动作事件。这里需要为每个菜单项安装-一个动作监听器。
ActionListener listener= ..,;
pasteltem.addActionListener(listener);
● 菜单对象的add方法可返回创建的子菜单项。可以使用下列方式获取它,并添加监听器:
JMenultem pasteltem = editMenu.add("Paste");pasteltem.addActionListener(listener);
7.弹出菜单(JPopupMenu)
●弹出菜单是不固定在菜单栏中随处浮动的菜单;
8.创建弹出菜单
●创建一个弹出菜单与创建-一个常规菜单的方法类似,但是弹出菜单没有标题:
JPopupMenu popup = new JPopupMenu();
●然后用常规方法为弹出菜单添加菜单项:
JMenultem item = new JMenultem("Cut");item.addAction istener(listener);popup.add(item);
●弹出菜单调用show方法才能显示出来:
popup.show(panel,x,y);
9.弹出式触发器
●弹出式触发器(pop-up trigger):用户点击鼠标某个键时弹出菜单。
●在Windows或者Linux中,弹出式触发器是鼠标右键。
●要想在用户点击某一个组件的时候弹出菜单,该组件就要调用以下方法设置弹出式触发器:
component.setComponentPopupMenu(popup);
10.快捷键
●可以为菜单项设置快捷键。在当前菜单打开的情况下,可以按下某菜单项的快捷键,相当于鼠标单击了该菜单项。
JMenultem Cutltem=new JMenultem(" Index ");
Cutltem. setMnemonic(" I");
●此快捷键就会自动显示在菜单项中,快捷键下面有一条下划线。
11.加速器
●加速器可以在不打开菜单的情况下选中菜单项的快捷键。例如, 很多应用程序把CTRL + 0和CTRL+ S关联到菜单中的Open和Save项。
●使用SetAccelerator方 法可以将加速器关联到一个菜单项。该方法使用KeyStroke类型的对象作为参数。例如:
openltem.setAccelerator(KeyStroke.getKeyStroke("ctrlo" ));
●当用户按下加速器组合键时,就自动选择了相应的菜单项,同时激活-一个动作事件。
●加速器只能关联在菜单项,而不能关联菜单;
●加速器实际上并不打开菜单,而是直接激活菜单关联的动作事件。
12.启用和禁用菜单项,
●在程序运行过程中,经常需要屏蔽某些暂时不适用的命令,待到条件允许时再使之重新可用。
●屏蔽/启用菜单项的方法:
-aMenultem.setEnabled(boolean)
-当参数值为false时,屏蔽该菜单项;
-当参数值为true时,启用该菜单项;
●如果需要动态启用/屏蔽某菜单项,则需要为菜单项注册“menuSelected"事件监听器。
javax.swing.event包定义了MenuListener接口,它有三个方法:
- void menuSelected(MenuEvent event)
- void menuDeselected(MenuEvent event)
- void menuCanceled(MenuEvent event) ;
13.工具栏(JToolBar)
●工具栏在程序中提供快速访问常用命令的按钮栏。
●工具栏的优点在于可以移动,脱离菜单栏或拖拽到框架其他地方。
JToolBar bar = new JToolBar();
bar add(blueAcfion);
bar. addyellowAction);
bar. add(redAction);
bar. addSeparator(),
●关闭包含工具栏的框架后,工具栏回到原始的框架中。
14.工具提示
●工具提示(tooltips) 提示工具栏中某个按钮的含义当光标停留在某个按钮上时,工具提示就会激活。工具提示文本显示在-一个矩形里。当用户移开鼠标是,工具提示就会自动地消失;
● 调用setToolTest方法添加工具提示到JComponent;exitButton,setToolTipText(" Exit ");
● 另外一种方法是,如果使用Action对象,就可以用SHORT-DESCRIPTION关联工具提示:
exitButton.putValue(Action.SHORT-DESCRIPTION, " Exit ");
二、 对话框
选项对话框 创建对话框 数据选择 文件对话框 颜色选择器
(1)对话框是一种大小不能变化、不能有菜单的容器窗口; 对话框不能作为一个应用程序的主框架,而必须包含在其 他的容器中。
(2)选项对话框:JOptionPane提供的对话框是模式对话框。当模式对话框显示时,它不允许用户输入到程序的其他的窗口。使用JOptionPane,可以创建和自定义问题、信息、警告和错误等几种类型的对 话框。
(3)数据交换:输入对话框含有供用户输入文本的文本框、一个确认和取 消按钮,是有模式对话框。当输入对话框可见时,要求用户 输入一个字符串。
(4)文件对话框:专门用于对文件(或目录)进行浏览和选择的对话框,常用的构造方法: – JFileChooser():根据用户的缺省目录创建文件对话框 – JFileChooser(File currentDirectory):根据File型参数 currentDirectory指定的目录创建文件对话框
(5)颜色对话框: javax.swing包中的JColorChooser类的静态方 法: public static Color showDialog(Component component, String title, Color initialColor)创建一个颜色对话框
(6)参数component指定对话框所依赖的组件,title指定对话框的标题;initialColor指定对话框返回的初始颜色,即对话框消失后,返回的默认值。 颜色对话框可根据用户在颜色对话框中选择的颜色返回一个颜色对象.
(7)创建对话框(JDialog)
●对话框的构造方法
-JDialog(Frame owner)一构造一 个没有 标题的非模式对话框JDialog(Frame owner, boolean modal)
-构造一个没有标题的对话框,boolean型参 数modal指定对话框是否为模式窗口
-JDialog(Frame owner, String title)构造一个有标题 的非模式对话框
-JDialog(Frame owner, String title, boolean modal)一构造一 个有标题的对话框
(8)showXXXDialog方法的参数
●Component parentComponent
- 对话框的父窗口对象,其屏幕坐标将决定对话框的显示位置;此参数也可以为nul1,表示采用缺省的Frame作为父窗口,此时对话框将设置在屏幕的正中
●Object message ;
一显示在对话框中的描述信息。该参数通常是一个String对象,但也可以是一个图标、一个组件或者一个对象 数组
●int messageType
●String title 对话框的标题
第二部分:实验部分
实验1: 导入第12章示例程序,测试程序并进行组内讨论。
测试程序1
● 在elipse IDE中调试运行教材512页程序12-8,结合运行结果理解程序;
● 掌握菜单的创建、菜单事件监听器、复选框和单选按钮菜单项、弹出菜单以及快捷键和加速器的用法。
● 记录示例代码阅读理解中存在的问题与疑惑。
代码如下:
MenuFrame类:
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; private Action saveAction; private Action saveAsAction; private JCheckBoxMenuItem readonlyItem; private JPopupMenu popup; /** * 将操作名称打印到System.out的示例操作。 */ //通常,采用扩展抽象类AbstractAction来定义一个实现Action接口的类 class TestAction extends AbstractAction { //需要在AbstractAction对象的构造器中指定菜单项标签 public TestAction(String name) { super(name); } //覆盖actionPerformed方法来获得菜单动作处理器 public void actionPerformed(ActionEvent event) { //打印操作名称 System.out.println(getValue(Action.NAME) + " selected."); } } public MenuFrame() { setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT); //创建顶层菜单FILE var fileMenu = new JMenu("File"); //用给定动作讲一个菜单项添加到菜单中,并返回这个菜单项 fileMenu.add(new TestAction("New")); // 演示加速器 //创建菜单项Open,并关联快捷键 var openItem = fileMenu.add(new TestAction("Open")); //使用setAccelerator将加速器键关联到一个菜单项上 openItem.setAccelerator(KeyStroke.getKeyStroke("ctrl O")); //讲一个分隔符行添加到菜单中 fileMenu.addSeparator(); //创建Save菜单项,并关联加速器 saveAction = new TestAction("Save"); JMenuItem saveItem = fileMenu.add(saveAction); saveItem.setAccelerator(KeyStroke.getKeyStroke("ctrl S")); //创建Save As菜单项,并关联加速器 saveAsAction = new TestAction("Save As"); fileMenu.add(saveAsAction); fileMenu.addSeparator(); //采用匿名内部类为Exit菜单项创建单独动作 fileMenu.add(new AbstractAction("Exit") { public void actionPerformed(ActionEvent event) { System.exit(0); } }); // 演示复选框和单选按钮菜单 //创建复选框Read-only readonlyItem = new JCheckBoxMenuItem("Read-only"); //为Read-only复选框添加监听器事件 readonlyItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { //如果只可读复选框被选中,则禁用Save和SaveAs动作,否则不禁用 boolean saveOk = !readonlyItem.isSelected(); saveAction.setEnabled(saveOk); saveAsAction.setEnabled(saveOk); } }); //创建按钮组 var group = new ButtonGroup(); //创建两个单选钮菜单项,并将Insert单选钮状态初始化为true var insertItem = new JRadioButtonMenuItem("Insert"); insertItem.setSelected(true); var overtypeItem = new JRadioButtonMenuItem("Overtype"); //将单选钮菜单添加到按钮组中 group.add(insertItem); group.add(overtypeItem); // 演示图标 //将一个图标添加到一个动作上,当使用动作构造菜单项时,Action.NAME值将会作为菜单项的文本,而 //Action.SMALL_ICON将会作为图标 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")); //创建顶层菜单Edit,并将cut,copy,paste菜单项添加到Edit中 var editMenu = new JMenu("Edit"); editMenu.add(cutAction); editMenu.add(copyAction); editMenu.add(pasteAction); // 演示嵌套菜单 //创建子菜单Options var optionMenu = new JMenu("Options"); //将readonly复选按钮,insert和overtype单选按钮添加到子菜单Options中 optionMenu.add(readonlyItem); optionMenu.addSeparator(); optionMenu.add(insertItem); optionMenu.add(overtypeItem); editMenu.addSeparator(); //再将子菜单Options添加到Edit菜单中 editMenu.add(optionMenu); // 演示记忆法 //创建顶层菜单Help var helpMenu = new JMenu("Help"); //为顶层菜单设置快捷键 helpMenu.setMnemonic('H'); //创建菜单项Index,并设置快捷键 var indexItem = new JMenuItem("Index"); indexItem.setMnemonic('I'); //将Index菜单项添加到Help菜单中 helpMenu.add(indexItem); // 还可以将助记键添加到操作 //对于一个Action对象,就可以把快捷键作为Action.MNEMONIC_KEY的键值添加到对象中 var aboutAction = new TestAction("About"); aboutAction.putValue(Action.MNEMONIC_KEY, new Integer('A')); helpMenu.add(aboutAction); // 将所有顶级菜单添加到菜单栏 //创建菜单栏 var menuBar = new JMenuBar(); //将菜单栏放置在框架中,默认位置是顶部 setJMenuBar(menuBar); //将顶层菜单添加到菜单栏中 menuBar.add(fileMenu); menuBar.add(editMenu); menuBar.add(helpMenu); // 演示弹出菜单 //菜单的add方法参数可以是动作,用给定动作将一个菜单项添加到菜单中,并返回这个菜单项 popup = new JPopupMenu(); popup.add(cutAction); popup.add(copyAction); popup.add(pasteAction); //将弹出菜单添加到面板中 var panel = new JPanel(); panel.setComponentPopupMenu(popup); //将面板添加到框架中 add(panel); } }
MenuTest类:
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); }); } }
运行结果如下:
测试程序2
● 在elipse IDE中调试运行教材517页程序12-9,结合运行结果理解程序;
● 掌握工具栏和工具提示的用法;
●l 记录示例代码阅读理解中存在的问题与疑惑。
代码如下:
ToolBarFrame类:
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); // 添加用于颜色更改的面板 panel = new JPanel(); add(panel, BorderLayout.CENTER); // 设置操作 //创建blue,yellow,red,exit作对象 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); //为exit单独实现AbstractAction类 var exitAction = new AbstractAction("Exit", new ImageIcon("exit.gif")) { public void actionPerformed(ActionEvent event) { System.exit(0); } }; //用SHORT_DESCRIPTION关联Exit exitAction.putValue(Action.SHORT_DESCRIPTION, "Exit"); // 填充工具栏 //创建工具栏 var bar = new JToolBar(); //用Action对象填充工具栏 bar.add(blueAction); bar.add(yellowAction); bar.add(redAction); bar.addSeparator(); bar.add(exitAction); add(bar, BorderLayout.NORTH); // 填充菜单 //创建顶层菜单Color var menu = new JMenu("Color"); //用Action对象填充菜单 menu.add(yellowAction); menu.add(blueAction); menu.add(redAction); menu.add(exitAction); var menuBar = new JMenuBar(); //将顶层菜单添加到菜单栏 menuBar.add(menu); //将菜单栏添加到框架上 setJMenuBar(menuBar); } /** * “颜色”操作将帧的背景设置为给定颜色。 */ //创建实现了AbstractAction类的ColorAction类 class ColorAction extends AbstractAction { //构造器中传入的参数分别为名称,图标以及颜色 public ColorAction(String name, Icon icon, Color c) { //使用NAME关联名称 putValue(Action.NAME, name); //使用SMALL_ICON关联图标 putValue(Action.SMALL_ICON, icon); //使用SHORT_DESCRIPTION关联工作提示 putValue(Action.SHORT_DESCRIPTION, name + " background"); //使用Color字符串关联颜色 putValue("Color", c); } //重写方法 public void actionPerformed(ActionEvent event) { //获取Color键所对应的颜色值,并转为Color类型 Color c = (Color) getValue("Color"); panel.setBackground(c); } } }
ToolBarTest类:
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); }); } }
运行结果如下:
测试程序3
● 在elipse IDE中调试运行教材544页程序12-15、12-16,结合运行结果理解程序;
● 掌握选项对话框的用法。
● 记录示例代码阅读理解中存在的问题与疑惑。
代码如下:
ButtonPanel类:
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 */ /*java类型后面跟三个点是代表可以接受多个实际参数,这里的多个指的是不限个数, * 可以是一个、两个、三个甚至更多。 */ public ButtonPanel(String title, String... options) { //设置蚀刻边框 setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), title)); /*设置布局方式,BoxLayout是javax.swing里的一个布局管理器,允许垂直或水平布置多个组件, Y_AXIS是指定从上到下垂直布置组件。 */ setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); group = new ButtonGroup(); // 为每个选项制作一个单选按钮 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(); } }
OptionDialogFrame类:
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() { //设置整个面板布局为2行3列的网格布局 var gridPanel = new JPanel(); gridPanel.setLayout(new GridLayout(2, 3)); //创建type,meddageType,message,confirm,option,input这6个面板 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"); //将6个面板添加到网格面板当中 gridPanel.add(typePanel); gridPanel.add(messageTypePanel); gridPanel.add(messagePanel); gridPanel.add(optionTypePanel); gridPanel.add(optionsPanel); gridPanel.add(inputPanel); // 添加带有“显示”按钮的面板,并为显示按钮添加动作事件 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(); } /** * 获取当前选定的信息。 * @return 字符串、图标、组件或对象数组,具体取决于消息面板的选择 */ 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; } /** * 获取当前选定的选项。 * @return 字符串、图标或对象的数组,具体取决于选项面板的选择 */ 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; } /** * 获取选定的消息或选项类型 * @param 面板消息类型或确认面板 * @return 从JOptionPane类中选择的XXX_消息或XXX_选项常量 */ public int getType(ButtonPanel panel) { String s = panel.getSelection(); try { return JOptionPane.class.getField(s).getInt(null); } catch (Exception e) { return -1; } } /** * 根据类型面板的选择,“显示”按钮的操作侦听器将显示“确认”、“输入”、“消息”或“选项”对话框。 */ 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]); } } } /** * 绘制表面的部件 */ 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); } }
OptionDialogTest类:
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); }); } }
运行结果:
测试程序4
● 在elipse IDE中调试运行教材552页程序12-17、12-18,结合运行结果理解程序;
● 掌握对话框的创建方法;
● 记录示例代码阅读理解中存在的问题与疑惑。
AboutDialog类:
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; /** * 显示消息并等待用户单击“确定”按钮的示例模式对话框。 */ public class AboutDialog extends JDialog { public AboutDialog(JFrame owner) { //在调用超类构造器时,需要提供拥有者框架,对话框标题及模式特征 //如果将拥有者标识为null,那么对话框将由一个隐藏框架所拥有 super(owner, "About DialogTest", true); // 将HTML标签添加到中心 add( new JLabel( "Core Java
By Cay Horstmann"), BorderLayout.CENTER); // 确定按钮关闭对话框 var ok = new JButton("OK"); ok.addActionListener(event -> setVisible(false)); // 将“确定”按钮添加到南部边界 var panel = new JPanel(); panel.add(ok); add(panel, BorderLayout.SOUTH); pack(); } }
DialogFrame类:
package dialog; import javax.swing.JFrame; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; /** * 带有菜单的框架,其“文件”->“关于操作”显示一个对话框。 */ 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); // 添加和退出菜单项 // About项显示About对话框 var aboutItem = new JMenuItem("About"); aboutItem.addActionListener(event -> { if (dialog == null) // 第一次 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); } }
DialogTest类:
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); }); } }
运行结果如下:
测试程序5
● 在elipse IDE中调试运行教材556页程序12-19、12-20,结合运行结果理解程序;
● 掌握对话框的数据交换用法;
● 记录示例代码阅读理解中存在的问题与疑惑。
User类:
package dataExchange; /** * 设置标题并显示对话框用户有名称和密码。出于安全原因,密码存储为char[],而不是字符串。 */ 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; } }
DataExchangeFrame类:
package dataExchange; import java.awt.*; import java.awt.event.*; import javax.swing.*; /** * 带有菜单的框架,其文件->连接操作显示密码对话框。 */ 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(); } /** * 连接操作会弹出密码对话框。 */ private class ConnectAction implements ActionListener { public void actionPerformed(ActionEvent event) { // 如果是第一次,则构造对话框 if (dialog == null) dialog = new PasswordChooser(); // 设置默认值 dialog.setUser(new User("yourname", null)); // 弹出对话框 if (dialog.showDialog(DataExchangeFrame.this, "Connect")) { // 如果接受,则检索用户输入 User u = dialog.getUser(); textArea.append("user name = " + u.getName() + ", password = " + (new String(u.getPassword())) + "\n"); } } } }
PasswordChooser类:
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()); // 使用用户名和密码字段构造面板 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); // 创建终止对话框的“确定”和“取消”按钮 okButton = new JButton("Ok"); okButton.addActionListener(event -> { ok = true; dialog.setVisible(false); }); var cancelButton = new JButton("Cancel"); cancelButton.addActionListener(event -> dialog.setVisible(false)); // 将按钮添加到南边界 var buttonPanel = new JPanel(); buttonPanel.add(okButton); buttonPanel.add(cancelButton); add(buttonPanel, BorderLayout.SOUTH); } /** * 设置对话框默认值。 * @param u默认用户信息 */ public void setUser(User u) { username.setText(u.getName()); } /** * 获取对话框输入. * @return 一个用户对象,其状态表示对话框条目 */ public User getUser() { return new User(username.getText(), password.getPassword()); } /** * 在对话框中显示选择器面板。 * @param 在所有者框架中为组件设置父级或为空 * @param 标题对话框窗口标题 */ 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 (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; } }
DataExchangeTest类:
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); }); } }
运行结果如下:
测试程序6
● 在elipse IDE中调试运行教材556页程序12-21、12-2212-23,结合程序运行结果理解程序;
● 掌握文件对话框的用法;
● 记录示例代码阅读理解中存在的问题与疑惑。
FileIconView类:
package fileChooser; import java.io.*; import javax.swing.*; import javax.swing.filechooser.*; import javax.swing.filechooser.FileFilter; /** * 显示与文件筛选器匹配的所有文件的图标的文件视图。 */ public class FileIconView extends FileView { private FileFilter filter; private Icon icon; /** * 构造文件图标视图。 * @param 过滤一个文件过滤器——这个过滤器接受的所有文件都将显示图标。 * @param anIcon——显示所有接受文件的图标。 */ 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; } }
ImagePreviewer类:
package fileChooser; import java.awt.*; import java.io.*; import javax.swing.*; /** * 预览图像的文件选择器附件。 */ public class ImagePreviewer extends JLabel { /** * 构造图像预览器。 * @param 选择其属性更改触发图像的文件选择器 * 此预览器中的更改 */ 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); } }); } }
ImageViewerFrame类:
package fileChooser; import java.io.*; import javax.swing.*; import javax.swing.filechooser.*; import javax.swing.filechooser.FileFilter; /** * 一种帧,具有加载图像的菜单和加载图像的显示区域。 */ 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); // 如果接受图像文件,请将其设置为标签的图标 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(); // 接受所有以.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"))); } }
FileChooseTest类:
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); }); } }
运行结果如下:
测试程序7
● 在elipse IDE中调试运行教材570页程序12-24,结合运行结果理解程序;
● 了解颜色选择器的用法。
● 记录示例代码阅读理解中存在的问题与疑惑。
代码如下:
ColorChooserFrame类:
package colorChooser; import javax.swing.*; /** * 带有颜色选择器面板的框架 */ 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); } }
ColorChooserPanel类:
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; /** * 带有按钮的面板,可弹出三种颜色选择器 */ 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); } /** * 这个监听器弹出一个模态颜色选择器 */ 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); } } /** * 这个监听器弹出一个无模式颜色选择器。当用户单击“确定”按钮时,面板颜色将更改。 */ private class ModelessListener implements ActionListener { private JDialog dialog; private JColorChooser chooser; public ModelessListener() { chooser = new JColorChooser(); dialog = JColorChooser.createDialog(ColorChooserPanel.this, "Background Color", false /* 非模态 */, chooser, event -> setBackground(chooser.getColor()), null /* 没有取消按钮侦听器 */); } public void actionPerformed(ActionEvent event) { chooser.setColor(getBackground()); dialog.setVisible(true); } } /** * 这个监听器弹出一个无模式颜色选择器。当用户选择新颜色时,面板颜色立即更改。 */ 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); } } }
ColorChooserTest类:
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); }); } }
运行结果如下:
第三部分、实验总结:(16分)
通过本周的学习,我了解了菜单组件用途及常用API、对话框组件用途及常用API,学习了设计简单应用程序的GUI。本周的测试程序很多,而且代码理解起来也是十分的不容易,我知道,仅靠是实验中的测试代码这一环节是远远不够的,还需要下来将书中的代码反复理解,并动手编程,在练习中才能逐渐掌握菜单和对话框组件的使用方法。我会继续加油,争取尽快理解。