201871010131-张兴盼《面向对象程序设计(java)》第十五周学习总结
博文正文开头格式:(2分)
项目 |
内容 |
《面向对象程序设计(java)》 |
https://www.cnblogs.com/nwnu-daizh/ |
这个作业的要求在哪里 |
https://www.cnblogs.com/nwnu-daizh/p/11995615.html |
作业学习目标 |
(1) 掌握菜单组件用途及常用API; (2) 掌握对话框组件用途及常用API; (3) 学习设计简单应用程序的GUI。 |
随笔博文正文内容包括:
第一部分:总结菜单、对话框两类组件用途及常用API(30分)
一、菜单
菜单是GUI编程中经常用到的一种组件。位于窗口顶部的菜单栏(menu bar)中包括下拉菜单的名字。点击一个名字就可以打开包含菜单项(menu items)和子菜单(submenus)的菜单。
分为JMenuBar/JMenu/JMenuItem,当选择菜单项时会触发一个动作事件,需要注册监听器监听。
由类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():删除菜单的所有菜单项。
二、菜单的创建
向窗口增设菜单的方法是:先创建一个菜单条对象,然后再创建若干菜单对象,把这些菜单对象放在菜单条里,再按要求为每个菜单对象添加菜单项。
三、菜单项
类JMenuItem 的实例就是菜单项。类JMenuItem的常用方法如下:
- JMenuItem():构造无标题的菜单项。
- JMenuItem(String s):构造有标题的菜单项。
- setEnabled(boolean b):设置当前单项是否可被选择。
- isEnabled():返回当前菜单项是否可被用户选择。
- getLabel():得到菜单项的名称。
- setLabel():设置菜单选项的名称。
- addActionListener(ActionListener e):为菜单项设置监视器。监视器接受点击某个菜单的动作事件。
四、处理菜单事件
菜单的事件源是用鼠标点击某个菜单项。处理该事件的接口是ActionListener,要实现的接口方法是actionPerformed(ActionEvent e),获得事件源的方法getSource().
五、向菜单增加退出项
增设一个新的菜单项,对该菜单项加入监视,对应的监视方法中使用System.exit()方法,就能实现单击该菜单项时退出Java运行环境。例如,以下示意代码:
…
item7 = new MenuItem(“退出”);
item7.addActionListener(this);
…
public void actionPerformed(ActionEvent e){
if(e.getSource()==item7){
System.exit(0);
}
}
六、对话框
与大多数的窗口系统一样,AWT也分为模式对话框和无模式对话框。
模式对话框是指在结束对它的处理之前,不允许用户与应用程序的其余窗口进行交互。
模式对话框主要用于在程序继续运行之前获取用户提供的信息。
无模式对话框是指允许用户同时在对话框和应用程序的其他窗口中输入信息。
使用无模式对话框的最好例子就是工具栏。工具栏可以停靠在任何地方,
并且用户可以在需要的时候,同时与应用程序窗口和工具栏进行交互。
简单信息模式对话框:
Swing有一个很容易使用的类JOptionPane,它可以弹出一个简单的对话框,而不必编写任何对话框的相关代码。
七、选项对话框
Swing有一套简单的对话框,用于获取用户的一些简单信息。
JOptionPane有4个用于显示这些对话框的静态方法:
showMessageDialog:显示一条消息并等待用户点击OK
showConfirmDialog:显示一条消息并等待用户确认(与OK/Cancel类似)
showOptionDialog:显示一条消息并获得用户在一组选项中的选择
showInputDialog:显示一条消息并获得用户输入的一行文本
输入对话框有一个用于接收用户输入的额外组件。它既可能是用于输入任何字符串的文本域,也可能是允许用户从中选择的组合框
每个对话框类型都有一个方法,可以用来提供自己的图标,以替代原来的图标。
可以为每个对话框类型指定一条消息,如字符串、图标、用户界面组件,或其他类型的对象
唯一底部的按钮取决于对话框类型和选项类型
使用showOptionDialog可以指定任意的选项
八、创建对话框
要想创建一个对话框,需要从JDialog派生一个类,具体过程:
1) 在对话框构造器中,调用超类JDialog的构造器。
2) 添加对话框的用户界面组件。
3) 添加事件处理器。
4) 设置对话框的大小。
在调用超类构造器时,需要提供拥有者框架(owner frame)、对话框标题及模式特征。
拥有者框架控制对话框的显示位置,如果将拥有者标识为null,那么对话框将由一个隐藏框架所拥有。
模式特征将指定对话框处于显示状态时,应用程序中其他窗口是否被锁住。
无模式对话框不会锁住其他窗口,而有模式对话框将锁住应用程序中的所有其他窗口(除对话框的子窗口外)。
用户经常使用的工具栏就是无模式对话框,另一方面,如果想强迫用户在继续操作之前提供一些必要的信息就应该使用模式对话框。
九、文件对话框
一个好的文件对话框可以显示文件和目录,可以让用户浏览文件系统。
Swing中提供了JFileChooser类,它可以显示一个文本对话框,其外观与本地应用程序中使用的文件对话框基本一样。
JFileChooser是一个模式对话框
建立文件对话框并且获取用户选择信息的步骤如下:
1 建立一个JFileChooser对象。与JDialog类的构造器不同,它不需要指定父组件。允许在多个框架中重用一个文件选择器。
2 调用setCurrentDirectory方法设置当前目录。
3 如果有一个想要作为用户选择的默认文件名,可以使用setSelectedFile方法进行指定。
4 如果允许用户在对话框中选择多个文件,需要调用setMultiSelectionEnabled方法
5 如果想让对话框仅显示某一种类型的文件,需要设置文件过滤器。
6 在默认情况下,用户在文件选择器中只能选择文件。如果希望选择目录,需要调用setFileSelectionMode方法。
参数值为:JFileChooser.FILES_ONLY(默认值),JFileChooser.DIRECTORIES_ONLY或者JFileChooser.FILES_AND_DIRECTORIES。
7 调用showOpenDialog或者showSaveDialog方法显示对话框。
8 调用getSelectedFile()或者getSelectedFiles()方法获取用户选择的一个或多个文件。
十、常用API
①java.lang.reflect.AccessibleObject
void setAccessible(boolean flag)
为反射对象设置可访问标志。flag为true表明屏蔽Java语言的访问检查,使得对象的私有属性也可以被查询和设置。
boolean isAccessible()
返回反射对象的可访问标志的值。
static void setAccessible(AccessibleObject[] array,boolean flag)
是一种设置对象数组可访问标志的快捷方法。
②java.lang.Class
Field getField(String name)
Field getField()
返回指定名称的公有域,或包含所有域的数组。
Field getDeclaredField(String name)
Field getDeclaredFields()
返回类中声明的给定名称的域,或者包含声明的全部域的数组。
③java.lang.reflect.Field
Object get(Object obj)
返回obj对象中用Field对象表示的域值。
void set(Object obj,Object newValue)
用一个新值设置Obj对象中Field对象表示的域。
第二部分:实验部分
1、实验目的与要求
(1) 掌握菜单组件用途及常用API;
(2) 掌握对话框组件用途及常用API;
(3) 学习设计简单应用程序的GUI。
2、实验内容和步骤
实验1: 导入第12章示例程序,测试程序并进行组内讨论。
测试程序1
l 在elipse IDE中调试运行教材512页程序12-8,结合运行结果理解程序;
l 掌握菜单的创建、菜单事件监听器、复选框和单选按钮菜单项、弹出菜单以及快捷键和加速器的用法。
l 记录示例代码阅读理解中存在的问题与疑惑。
程序代码如下:
1 package menu; 2 3 import java.awt.*; 4 import javax.swing.*; 5 6 /** 7 * @version 1.25 2018-04-10 8 * @author Cay Horstmann 9 */ 10 public class MenuTest 11 { 12 public static void main(String[] args) 13 { 14 EventQueue.invokeLater(() -> { 15 var frame = new MenuFrame(); 16 frame.setTitle("MenuTest"); 17 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 18 frame.setVisible(true); 19 }); 20 } 21 }
1 package menu; 2 3 import java.awt.event.*; 4 import javax.swing.*; 5 6 /** 7 * A frame with a sample menu bar. 8 */ 9 public class MenuFrame extends JFrame 10 { 11 private static final int DEFAULT_WIDTH = 300; 12 private static final int DEFAULT_HEIGHT = 200; 13 private Action saveAction; 14 private Action saveAsAction; 15 private JCheckBoxMenuItem readonlyItem; 16 private JPopupMenu popup; 17 18 /** 19 *在显示台上显示已选择动作名称 20 */ 21 class TestAction extends AbstractAction 22 { 23 public TestAction(String name) 24 { 25 super(name); 26 } 27 28 public void actionPerformed(ActionEvent event) 29 { 30 System.out.println(getValue(Action.NAME) + " selected.");//getValue返回被存储的值 31 } 32 } 33 34 public MenuFrame() 35 { 36 setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT); 37 38 var fileMenu = new JMenu("File");//菜单定义 39 40 fileMenu.add(new TestAction("New")); 41 42 // 加速器 43 44 var openItem = fileMenu.add(new TestAction("Open")); 45 openItem.setAccelerator(KeyStroke.getKeyStroke("ctrl O"));//"ctrl O"设置为Open菜单项的加速器 46 47 fileMenu.addSeparator();//添加分隔符行 48 49 saveAction = new TestAction("Save"); 50 JMenuItem saveItem = fileMenu.add(saveAction); 51 saveItem.setAccelerator(KeyStroke.getKeyStroke("ctrl S"));//"ctrl S"设置为Save菜单项的加速器 52 53 saveAsAction = new TestAction("Save As"); 54 fileMenu.add(saveAsAction); 55 56 fileMenu.addSeparator();//添加分隔符行 57 58 fileMenu.add(new AbstractAction("Exit") 59 { 60 public void actionPerformed(ActionEvent event) 61 { 62 System.exit(0); 63 } 64 }); 65 66 //复选框和单按钮菜单项 67 68 readonlyItem = new JCheckBoxMenuItem("Read-only"); 69 readonlyItem.addActionListener(new ActionListener() 70 { 71 public void actionPerformed(ActionEvent event) 72 { 73 boolean saveOk = !readonlyItem.isSelected(); 74 saveAction.setEnabled(saveOk);//若"Read-only"复选框未被选择,Save、Save as菜单项均可执行点击操作 75 saveAsAction.setEnabled(saveOk); 76 } 77 }); 78 79 var group = new ButtonGroup(); 80 81 var insertItem = new JRadioButtonMenuItem("Insert"); 82 insertItem.setSelected(true);//默认 83 var overtypeItem = new JRadioButtonMenuItem("Overtype"); 84 85 group.add(insertItem); 86 group.add(overtypeItem); 87 88 // 展示图标 89 90 var cutAction = new TestAction("Cut"); 91 cutAction.putValue(Action.SMALL_ICON, new ImageIcon("cut.gif"));//putValue将值放置在动作对象内 92 var copyAction = new TestAction("Copy"); 93 copyAction.putValue(Action.SMALL_ICON, new ImageIcon("copy.gif")); 94 var pasteAction = new TestAction("Paste"); 95 pasteAction.putValue(Action.SMALL_ICON, new ImageIcon("paste.gif")); 96 97 var editMenu = new JMenu("Edit");//定义菜单 98 editMenu.add(cutAction); 99 editMenu.add(copyAction); 100 editMenu.add(pasteAction); 101 102 //展示子菜单 103 104 var optionMenu = new JMenu("Options"); 105 106 optionMenu.add(readonlyItem); 107 optionMenu.addSeparator();//分隔符 108 optionMenu.add(insertItem); 109 optionMenu.add(overtypeItem); 110 111 editMenu.addSeparator(); 112 113 editMenu.add(optionMenu); 114 115 //展示快捷键 116 117 var helpMenu = new JMenu("Help"); 118 helpMenu.setMnemonic('H');//设置快捷字符,该字符在标签中以下划线的项式显示 119 120 var indexItem = new JMenuItem("Index"); 121 indexItem.setMnemonic('I'); 122 helpMenu.add(indexItem); 123 124 //在快捷键上添加动作 125 var aboutAction = new TestAction("About"); 126 aboutAction.putValue(Action.MNEMONIC_KEY, new Integer('A')); 127 helpMenu.add(aboutAction); 128 129 // 将所有的顶部菜单添加到菜单栏上 130 131 var menuBar = new JMenuBar(); 132 setJMenuBar(menuBar);//设置菜单栏 133 134 menuBar.add(fileMenu); 135 menuBar.add(editMenu); 136 menuBar.add(helpMenu); 137 138 // 展示弹出菜单 139 140 popup = new JPopupMenu(); 141 popup.add(cutAction); 142 popup.add(copyAction); 143 popup.add(pasteAction); 144 145 var panel = new JPanel(); 146 panel.setComponentPopupMenu(popup);//设置组件的弹出菜单 147 add(panel); 148 } 149 }
运行截图如下:
测试程序2
l 在elipse IDE中调试运行教材517页程序12-9,结合运行结果理解程序;
l 掌握工具栏和工具提示的用法;
l 记录示例代码阅读理解中存在的问题与疑惑。
程序代码如下:
1 package toolBar; 2 3 import java.awt.*; 4 import javax.swing.*; 5 6 /** 7 * @version 1.15 2018-04-10 8 * @author Cay Horstmann 9 */ 10 public class ToolBarTest 11 { 12 public static void main(String[] args) 13 { 14 EventQueue.invokeLater(() -> { 15 var frame = new ToolBarFrame(); 16 frame.setTitle("ToolBarTest"); 17 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 18 frame.setVisible(true); 19 }); 20 }
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(); add(panel, BorderLayout.CENTER); // 设置动作 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();//创建工具栏 bar.add(blueAction);//用action对象填充工具栏 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. */ 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 记录示例代码阅读理解中存在的问题与疑惑。
程序代码如下:
1 package optionDialog; 2 3 import java.awt.*; 4 import javax.swing.*; 5 6 /** 7 * @version 1.35 2018-04-10 8 * @author Cay Horstmann 9 */ 10 public class OptionDialogTest 11 { 12 public static void main(String[] args) 13 { 14 EventQueue.invokeLater(() -> { 15 var frame = new OptionDialogFrame(); 16 frame.setTitle("OptionDialogTest"); 17 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 18 frame.setVisible(true); 19 }); 20 } 21 }
1 package optionDialog; 2 3 import javax.swing.*; 4 5 /** 6 * A panel with radio buttons inside a titled border. 7 */ 8 public class ButtonPanel extends JPanel 9 { 10 private ButtonGroup group; 11 12 /** 13 * Constructs a button panel. 14 * @param title the title shown in the border 15 * @param options an array of radio button labels 16 */ 17 public ButtonPanel(String title, String... options) 18 { 19 setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), title));//设置边框即标题 20 setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));//垂直排列 21 group = new ButtonGroup(); 22 23 // 为每一个选项创建一个单选钮 24 for (String option : options) 25 { 26 var button = new JRadioButton(option); 27 button.setActionCommand(option); 28 add(button); 29 group.add(button); 30 button.setSelected(option == options[0]);//设置默认选择 31 } 32 } 33 34 /** 35 * Gets the currently selected option. 36 * @return the label of the currently selected radio button. 37 */ 38 public String getSelection() 39 { 40 return group.getSelection().getActionCommand(); 41 } 42 }
1 package optionDialog; 2 3 import java.awt.*; 4 import java.awt.event.*; 5 import java.awt.geom.*; 6 import java.util.*; 7 import javax.swing.*; 8 9 /** 10 * A frame that contains settings for selecting various option dialogs. 11 */ 12 public class OptionDialogFrame extends JFrame 13 { 14 private ButtonPanel typePanel; 15 private ButtonPanel messagePanel; 16 private ButtonPanel messageTypePanel; 17 private ButtonPanel optionTypePanel; 18 private ButtonPanel optionsPanel; 19 private ButtonPanel inputPanel; 20 private String messageString = "Message"; 21 private Icon messageIcon = new ImageIcon("blue-ball.gif"); 22 private Object messageObject = new Date(); 23 private Component messageComponent = new SampleComponent(); 24 25 public OptionDialogFrame() 26 { 27 var gridPanel = new JPanel(); 28 gridPanel.setLayout(new GridLayout(2, 3)); 29 30 typePanel = new ButtonPanel("Type", "Message", "Confirm", "Option", "Input"); 31 messageTypePanel = new ButtonPanel("Message Type", "ERROR_MESSAGE", "INFORMATION_MESSAGE", 32 "WARNING_MESSAGE", "QUESTION_MESSAGE", "PLAIN_MESSAGE"); 33 messagePanel = new ButtonPanel("Message", "String", "Icon", "Component", "Other", 34 "Object[]"); 35 optionTypePanel = new ButtonPanel("Confirm", "DEFAULT_OPTION", "YES_NO_OPTION", 36 "YES_NO_CANCEL_OPTION", "OK_CANCEL_OPTION"); 37 optionsPanel = new ButtonPanel("Option", "String[]", "Icon[]", "Object[]"); 38 inputPanel = new ButtonPanel("Input", "Text field", "Combo box"); 39 40 gridPanel.add(typePanel); 41 gridPanel.add(messageTypePanel); 42 gridPanel.add(messagePanel); 43 gridPanel.add(optionTypePanel); 44 gridPanel.add(optionsPanel); 45 gridPanel.add(inputPanel); 46 47 // Show按钮的添加 48 49 var showPanel = new JPanel(); 50 var showButton = new JButton("Show"); 51 showButton.addActionListener(new ShowAction()); 52 showPanel.add(showButton); 53 54 add(gridPanel, BorderLayout.CENTER); 55 add(showPanel, BorderLayout.SOUTH); 56 pack(); 57 } 58 59 /** 60 *得到当前选择的信息 61 * @return a string, icon, component, or object array, depending on the Message panel selection 62 */ 63 public Object getMessage() 64 { 65 String s = messagePanel.getSelection(); 66 if (s.equals("String")) return messageString; 67 else if (s.equals("Icon")) return messageIcon; 68 else if (s.equals("Component")) return messageComponent; 69 else if (s.equals("Object[]")) return new Object[] { messageString, messageIcon, 70 messageComponent, messageObject }; 71 else if (s.equals("Other")) return messageObject; 72 else return null; 73 } 74 75 /** 76 * Gets the currently selected options. 77 * @return an array of strings, icons, or objects, depending on the Option panel selection 78 */ 79 public Object[] getOptions() 80 { 81 String s = optionsPanel.getSelection(); 82 if (s.equals("String[]")) return new String[] { "Yellow", "Blue", "Red" }; 83 else if (s.equals("Icon[]")) return new Icon[] { new ImageIcon("yellow-ball.gif"), 84 new ImageIcon("blue-ball.gif"), new ImageIcon("red-ball.gif") }; 85 else if (s.equals("Object[]")) return new Object[] { messageString, messageIcon, 86 messageComponent, messageObject }; 87 else return null; 88 } 89 90 /** 91 * Gets the selected message or option type 92 * @param panel the Message Type or Confirm panel 93 * @return the selected XXX_MESSAGE or XXX_OPTION constant from the JOptionPane class 94 */ 95 public int getType(ButtonPanel panel) 96 { 97 String s = panel.getSelection(); 98 try 99 { 100 return JOptionPane.class.getField(s).getInt(null);//JOptionPane.xxx来获得这个静态字段的值 101 } 102 catch (Exception e) 103 { 104 return -1; 105 } 106 } 107 108 /** 109 * The action listener for the Show button shows a Confirm, Input, Message, or Option dialog 110 * depending on the Type panel selection. 111 */ 112 private class ShowAction implements ActionListener 113 { 114 public void actionPerformed(ActionEvent event) 115 { 116 if (typePanel.getSelection().equals("Confirm")) JOptionPane.showConfirmDialog( 117 OptionDialogFrame.this, getMessage(), "Title", getType(optionTypePanel), 118 getType(messageTypePanel)); 119 else if (typePanel.getSelection().equals("Input")) 120 { 121 if (inputPanel.getSelection().equals("Text field")) JOptionPane.showInputDialog( 122 OptionDialogFrame.this, getMessage(), "Title", getType(messageTypePanel)); 123 else JOptionPane.showInputDialog(OptionDialogFrame.this, getMessage(), "Title", 124 getType(messageTypePanel), null, new String[] { "Yellow", "Blue", "Red" }, 125 "Blue"); 126 } 127 else if (typePanel.getSelection().equals("Message")) JOptionPane.showMessageDialog( 128 OptionDialogFrame.this, getMessage(), "Title", getType(messageTypePanel)); 129 else if (typePanel.getSelection().equals("Option")) JOptionPane.showOptionDialog( 130 OptionDialogFrame.this, getMessage(), "Title", getType(optionTypePanel), 131 getType(messageTypePanel), null, getOptions(), getOptions()[0]); 132 } 133 } 134 } 135 136 /** 137 * A component with a painted surface 138 */ 139 140 class SampleComponent extends JComponent 141 { 142 public void paintComponent(Graphics g) 143 { 144 var g2 = (Graphics2D) g; 145 var rect = new Rectangle2D.Double(0, 0, getWidth() - 1, getHeight() - 1); 146 g2.setPaint(Color.YELLOW); 147 g2.fill(rect); 148 g2.setPaint(Color.BLUE); 149 g2.draw(rect); 150 } 151 152 public Dimension getPreferredSize() 153 { 154 return new Dimension(10, 10); 155 } 156 }
运行截图如下:
测试程序4
l 在elipse IDE中调试运行教材552页程序12-17、12-18,结合运行结果理解程序;
l 掌握对话框的创建方法;
l 记录示例代码阅读理解中存在的问题与疑惑。
程序代码如下:
1 package dialog; 2 3 import java.awt.*; 4 import javax.swing.*; 5 6 /** 7 * @version 1.35 2018-04-10 8 * @author Cay Horstmann 9 */ 10 public class DialogTest 11 { 12 public static void main(String[] args) 13 { 14 EventQueue.invokeLater(() -> { 15 var frame = new DialogFrame(); 16 frame.setTitle("DialogTest"); 17 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 18 frame.setVisible(true); 19 }); 20 }
1 package dialog; 2 3 import javax.swing.JFrame; 4 import javax.swing.JMenu; 5 import javax.swing.JMenuBar; 6 import javax.swing.JMenuItem; 7 8 /** 9 * A frame with a menu whose File->About action shows a dialog. 10 */ 11 public class DialogFrame extends JFrame 12 { 13 private static final int DEFAULT_WIDTH = 300; 14 private static final int DEFAULT_HEIGHT = 200; 15 private AboutDialog dialog; 16 17 public DialogFrame() 18 { 19 setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT); 20 21 //创建File菜单 22 23 var menuBar = new JMenuBar();//菜单栏 24 setJMenuBar(menuBar); 25 var fileMenu = new JMenu("File");//菜单 26 menuBar.add(fileMenu); 27 28 //添加About、Exit菜单项 29 30 //About项展示About对话框 31 32 var aboutItem = new JMenuItem("About");//菜单项 33 aboutItem.addActionListener(event -> { 34 if (dialog == null) // 只建立一次对话框,但可多次重复使用 35 dialog = new AboutDialog(DialogFrame.this); 36 dialog.setVisible(true);//显示对对话框 37 }); 38 fileMenu.add(aboutItem); 39 40 // 关闭程序 41 42 var exitItem = new JMenuItem("Exit"); 43 exitItem.addActionListener(event -> System.exit(0)); 44 fileMenu.add(exitItem); 45 } 46 }
1 package dialog; 2 3 import java.awt.BorderLayout; 4 5 import javax.swing.JButton; 6 import javax.swing.JDialog; 7 import javax.swing.JFrame; 8 import javax.swing.JLabel; 9 import javax.swing.JPanel; 10 11 /** 12 * A sample modal dialog that displays a message and waits for the user to click 13 * the OK button. 14 */ 15 public class AboutDialog extends JDialog 16 { 17 public AboutDialog(JFrame owner) 18 { 19 super(owner, "About DialogTest", true); 20 21 //添加标签 22 23 add( 24 new JLabel( 25 "<html><h1><i>Core Java</i></h1><hr>By Cay Horstmann</html>"), 26 BorderLayout.CENTER); 27 28 //点击OK按钮关闭对话框 29 30 var ok = new JButton("OK"); 31 ok.addActionListener(event -> setVisible(false)); 32 33 // add OK button to southern border 34 35 var panel = new JPanel(); 36 panel.add(ok); 37 add(panel, BorderLayout.SOUTH); 38 39 pack(); 40 } 41 }
运行截图如下:
测试程序5
l 在elipse IDE中调试运行教材556页程序12-19、12-20,结合运行结果理解程序;
l 掌握对话框的数据交换用法;
l 记录示例代码阅读理解中存在的问题与疑惑。
程序代码如下:
1 package dataExchange; 2 3 import java.awt.*; 4 import javax.swing.*; 5 6 /** 7 * @version 1.35 2018-04-10 8 * @author Cay Horstmann 9 */ 10 public class DataExchangeTest 11 { 12 public static void main(String[] args) 13 { 14 EventQueue.invokeLater(() -> { 15 var frame = new DataExchangeFrame(); 16 frame.setTitle("DataExchangeTest"); 17 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 18 frame.setVisible(true); 19 }); 20 } 21 }
1 package dataExchange; 2 3 import java.awt.*; 4 import java.awt.event.*; 5 import javax.swing.*; 6 7 /** 8 * A frame with a menu whose File->Connect action shows a password dialog. 9 */ 10 public class DataExchangeFrame extends JFrame 11 { 12 public static final int TEXT_ROWS = 20; 13 public static final int TEXT_COLUMNS = 40; 14 private PasswordChooser dialog = null; 15 private JTextArea textArea; 16 17 public DataExchangeFrame() 18 { 19 // 创建File菜单 20 21 var mbar = new JMenuBar();//菜单栏 22 setJMenuBar(mbar); 23 var fileMenu = new JMenu("File");//菜单 24 mbar.add(fileMenu); 25 26 //添加Connect、Exit菜单项 27 28 var connectItem = new JMenuItem("Connect");//菜单项 29 connectItem.addActionListener(new ConnectAction()); 30 fileMenu.add(connectItem); 31 32 //关闭程序 33 34 var exitItem = new JMenuItem("Exit"); 35 exitItem.addActionListener(event -> System.exit(0)); 36 fileMenu.add(exitItem); 37 38 textArea = new JTextArea(TEXT_ROWS, TEXT_COLUMNS);//含滚动条的文本区 39 add(new JScrollPane(textArea), BorderLayout.CENTER); 40 pack(); 41 } 42 43 /** 44 * The Connect action pops up the password dialog. 45 */ 46 private class ConnectAction implements ActionListener 47 { 48 public void actionPerformed(ActionEvent event) 49 { 50 //第一次,创建对话框 51 52 if (dialog == null) dialog = new PasswordChooser(); 53 54 //设置默认值 55 dialog.setUser(new User("yourname", null)); 56 57 //弹出对话框 58 if (dialog.showDialog(DataExchangeFrame.this, "Connect")) 59 { 60 // 重新得到用户输入 61 User u = dialog.getUser(); 62 textArea.append("user name = " + u.getName() + ", password = " 63 + (new String(u.getPassword())) + "\n"); 64 } 65 } 66 } 67 }
1 package dataExchange; 2 3 import java.awt.BorderLayout; 4 import java.awt.Component; 5 import java.awt.Frame; 6 import java.awt.GridLayout; 7 8 import javax.swing.JButton; 9 import javax.swing.JDialog; 10 import javax.swing.JLabel; 11 import javax.swing.JPanel; 12 import javax.swing.JPasswordField; 13 import javax.swing.JTextField; 14 import javax.swing.SwingUtilities; 15 16 /** 17 * A password chooser that is shown inside a dialog. 18 */ 19 public class PasswordChooser extends JPanel 20 { 21 private JTextField username; 22 private JPasswordField password; 23 private JButton okButton; 24 private boolean ok; 25 private JDialog dialog; 26 27 public PasswordChooser() 28 { 29 setLayout(new BorderLayout()); 30 31 //创建还有user name与password域的面板 32 33 var panel = new JPanel(); 34 panel.setLayout(new GridLayout(2, 2)); 35 panel.add(new JLabel("User name:")); 36 panel.add(username = new JTextField("")); 37 panel.add(new JLabel("Password:")); 38 panel.add(password = new JPasswordField("")); 39 add(panel, BorderLayout.CENTER); 40 41 // create Ok and Cancel buttons that terminate the dialog 42 43 okButton = new JButton("Ok"); 44 okButton.addActionListener(event -> { 45 ok = true; 46 dialog.setVisible(false);//点击OK按钮后关闭对话框 47 }); 48 49 var cancelButton = new JButton("Cancel"); 50 cancelButton.addActionListener(event -> dialog.setVisible(false)); 51 52 //添加按钮 53 54 var buttonPanel = new JPanel(); 55 buttonPanel.add(okButton); 56 buttonPanel.add(cancelButton); 57 add(buttonPanel, BorderLayout.SOUTH); 58 } 59 60 /** 61 * Sets the dialog defaults. 62 * @param u the default user information 63 */ 64 public void setUser(User u)//放置默认值 65 { 66 username.setText(u.getName()); 67 } 68 69 /** 70 * Gets the dialog entries. 71 * @return a User object whose state represents the dialog entries 72 */ 73 public User getUser() 74 { 75 return new User(username.getText(), password.getPassword()); 76 } 77 78 /** 79 * Show the chooser panel in a dialog. 80 * @param parent a component in the owner frame or null 81 * @param title the dialog window title 82 */ 83 public boolean showDialog(Component parent, String title) 84 { 85 ok = false; 86 87 //拥有者框架 88 89 Frame owner = null; 90 if (parent instanceof Frame) 91 owner = (Frame) parent; 92 else 93 owner = (Frame) SwingUtilities.getAncestorOfClass(Frame.class, parent);//返回给定组件的最先的父容器 94 95 //第一次或改变拥有者,则创建新的对话框 96 97 if (dialog == null || dialog.getOwner() != owner) 98 { 99 dialog = new JDialog(owner, true); 100 dialog.add(this); 101 dialog.getRootPane().setDefaultButton(okButton);//设置默认按钮 102 dialog.pack(); 103 } 104 105 //设置标题并展示对话框 106 107 dialog.setTitle(title); 108 dialog.setVisible(true); 109 return ok; 110 } 111 }
1 package dataExchange; 2 3 /** 4 * A user has a name and password. For security reasons, the password is stored as a char[], not a 5 * String. 6 */ 7 public class User 8 { 9 private String name; 10 private char[] password; 11 12 public User(String aName, char[] aPassword) 13 { 14 name = aName; 15 password = aPassword; 16 } 17 18 public String getName() 19 { 20 return name; 21 } 22 23 public char[] getPassword() 24 { 25 return password; 26 } 27 28 public void setName(String aName) 29 { 30 name = aName; 31 } 32 33 public void setPassword(char[] aPassword) 34 { 35 password = aPassword; 36 } 37 }
运行截图如下:
测试程序6
l 在elipse IDE中调试运行教材556页程序12-21、12-2212-23,结合程序运行结果理解程序;
l 掌握文件对话框的用法;
l 记录示例代码阅读理解中存在的问题与疑惑。
程序代码如下:
1 package fileChooser; 2 3 import java.awt.*; 4 import javax.swing.*; 5 6 /** 7 * @version 1.26 2018-04-10 8 * @author Cay Horstmann 9 */ 10 public class FileChooserTest 11 { 12 public static void main(String[] args) 13 { 14 EventQueue.invokeLater(() -> { 15 var frame = new ImageViewerFrame(); 16 frame.setTitle("FileChooserTest"); 17 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 18 frame.setVisible(true); 19 }); 20 } 21 }
1 package fileChooser; 2 3 import java.io.*; 4 5 import javax.swing.*; 6 import javax.swing.filechooser.*; 7 import javax.swing.filechooser.FileFilter; 8 9 /** 10 * A frame that has a menu for loading an image and a display area for the 11 * loaded image. 12 */ 13 public class ImageViewerFrame extends JFrame 14 { 15 private static final int DEFAULT_WIDTH = 300; 16 private static final int DEFAULT_HEIGHT = 400; 17 private JLabel label; 18 private JFileChooser chooser; 19 20 public ImageViewerFrame() 21 { 22 setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT); 23 24 // set up menu bar 25 var menuBar = new JMenuBar();//菜单栏 26 setJMenuBar(menuBar); 27 28 var menu = new JMenu("File");//菜单 29 menuBar.add(menu); 30 31 var openItem = new JMenuItem("Open"); 32 menu.add(openItem); 33 openItem.addActionListener(event -> { 34 chooser.setCurrentDirectory(new File("."));//设置当前目录 35 36 //文件选择对话框 37 int result = chooser.showOpenDialog(ImageViewerFrame.this); 38 39 // 图像文件接受,把它作为标签的图标 40 if (result == JFileChooser.APPROVE_OPTION) 41 { 42 String name = chooser.getSelectedFile().getPath();//获取用户选择的一个文件路径 43 label.setIcon(new ImageIcon(name)); 44 pack(); 45 } 46 }); 47 48 var exitItem = new JMenuItem("Exit"); 49 menu.add(exitItem); 50 exitItem.addActionListener(event -> System.exit(0)); 51 52 //使用标签显示图像 53 label = new JLabel(); 54 add(label); 55 56 // 创建文件选择器 57 chooser = new JFileChooser(); 58 59 //接受所有以.jpg, .jpeg, .gif格式的图片文件 60 var filter = new FileNameExtensionFilter( 61 "Image files", "jpg", "jpeg", "gif"); 62 chooser.setFileFilter(filter);//文件对话框的文件过滤器 63 64 chooser.setAccessory(new ImagePreviewer(chooser));//设置附件组件 65 66 chooser.setFileView(new FileIconView(filter, new ImageIcon("palette.gif")));//设置文件视图来提供文件过滤器显示信息 67 } 68 }
1 package fileChooser; 2 3 import java.awt.*; 4 import java.io.*; 5 6 import javax.swing.*; 7 8 /** 9 * A file chooser accessory that previews images. 10 */ 11 public class ImagePreviewer extends JLabel 12 { 13 /** 14 * Constructs an ImagePreviewer. 15 * @param chooser the file chooser whose property changes trigger an image 16 * change in this previewer 17 */ 18 public ImagePreviewer(JFileChooser chooser) 19 { 20 setPreferredSize(new Dimension(100, 100)); 21 setBorder(BorderFactory.createEtchedBorder());//3D效果的直线边框 22 23 chooser.addPropertyChangeListener(event -> { 24 if (event.getPropertyName() == JFileChooser.SELECTED_FILE_CHANGED_PROPERTY) 25 { 26 //用户选定新的文件 27 File f = (File) event.getNewValue(); 28 if (f == null) 29 { 30 setIcon(null); 31 return; 32 } 33 34 //将图像设置未图标 35 var icon = new ImageIcon(f.getPath()); 36 37 //图标过大或过小,缩放 38 if (icon.getIconWidth() > getWidth()) 39 icon = new ImageIcon(icon.getImage().getScaledInstance( 40 getWidth(), -1, Image.SCALE_DEFAULT)); 41 42 setIcon(icon);//设置图标 43 } 44 }); 45 } 46 }
1 package fileChooser; 2 3 import java.io.*; 4 import javax.swing.*; 5 import javax.swing.filechooser.*; 6 import javax.swing.filechooser.FileFilter; 7 8 /** 9 * A file view that displays an icon for all files that match a file filter. 10 */ 11 public class FileIconView extends FileView 12 { 13 private FileFilter filter; 14 private Icon icon; 15 16 /** 17 * Constructs a FileIconView. 18 * @param aFilter a file filter--all files that this filter accepts will be shown 19 * with the icon. 20 * @param anIcon--the icon shown with all accepted files. 21 */ 22 public FileIconView(FileFilter aFilter, Icon anIcon) 23 { 24 filter = aFilter; 25 icon = anIcon; 26 } 27 28 public Icon getIcon(File f) 29 { 30 if (!f.isDirectory() && filter.accept(f)) return icon; 31 else return null; 32 } 33 }
运行截图如下:
测试程序7
l 在elipse IDE中调试运行教材570页程序12-24,结合运行结果理解程序;
l 了解颜色选择器的用法。
l 记录示例代码阅读理解中存在的问题与疑惑。
程序代码如下:
1 package colorChooser; 2 3 import java.awt.*; 4 import javax.swing.*; 5 6 /** 7 * @version 1.04 2015-06-12 8 * @author Cay Horstmann 9 */ 10 public class ColorChooserTest 11 { 12 public static void main(String[] args) 13 { 14 EventQueue.invokeLater(() -> { 15 JFrame frame = new ColorChooserFrame(); 16 frame.setTitle("ColorChooserTest"); 17 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 18 frame.setVisible(true); 19 }); 20 } 21 }
1 package colorChooser; 2 3 import javax.swing.*; 4 5 /** 6 * A frame with a color chooser panel 7 */ 8 public class ColorChooserFrame extends JFrame 9 { 10 private static final int DEFAULT_WIDTH = 300; 11 private static final int DEFAULT_HEIGHT = 200; 12 13 public ColorChooserFrame() 14 { 15 setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT); 16 17 // add color chooser panel to frame 18 19 ColorChooserPanel panel = new ColorChooserPanel();//初始颜色为白色的颜色选择器 20 add(panel); 21 } 22 }
1 package colorChooser; 2 3 import java.awt.Color; 4 import java.awt.Frame; 5 import java.awt.event.ActionEvent; 6 import java.awt.event.ActionListener; 7 8 import javax.swing.JButton; 9 import javax.swing.JColorChooser; 10 import javax.swing.JDialog; 11 import javax.swing.JPanel; 12 13 /** 14 * A panel with buttons to pop up three types of color choosers 15 */ 16 public class ColorChooserPanel extends JPanel 17 { 18 public ColorChooserPanel() 19 { 20 JButton modalButton = new JButton("Modal"); 21 modalButton.addActionListener(new ModalListener()); 22 add(modalButton); 23 24 JButton modelessButton = new JButton("Modeless"); 25 modelessButton.addActionListener(new ModelessListener()); 26 add(modelessButton); 27 28 JButton immediateButton = new JButton("Immediate"); 29 immediateButton.addActionListener(new ImmediateListener()); 30 add(immediateButton); 31 } 32 33 /** 34 *弹出模式颜色选择器 35 */ 36 private class ModalListener implements ActionListener 37 { 38 public void actionPerformed(ActionEvent event) 39 { 40 Color defaultColor = getBackground(); 41 Color selected = JColorChooser.showDialog(ColorChooserPanel.this, "Set background", 42 defaultColor); 43 if (selected != null) setBackground(selected);//将当前选中的颜色,点击OK按钮,设置为背景颜色 44 } 45 } 46 47 /** 48 * 弹出无模式颜色选择器,点击OK,对话框的背景颜色就会被设置为所选择的颜色 49 */ 50 private class ModelessListener implements ActionListener 51 { 52 private JDialog dialog; 53 private JColorChooser chooser; 54 55 public ModelessListener() 56 { 57 chooser = new JColorChooser();//颜色选择器 58 dialog = JColorChooser.createDialog(ColorChooserPanel.this, "Background Color", 59 false /* not modal */, chooser, 60 event -> setBackground(chooser.getColor()), 61 null /* no Cancel button listener */); 62 }//点击OK,对话框的背景颜色就会被设置为所选择的颜色 63 64 public void actionPerformed(ActionEvent event) 65 { 66 chooser.setColor(getBackground()); 67 dialog.setVisible(true); 68 } 69 } 70 71 /** 72 * 弹出无模式颜色选择器,当用户选择一种新的颜色,立即改变背景颜色 73 */ 74 private class ImmediateListener implements ActionListener 75 { 76 private JDialog dialog; 77 private JColorChooser chooser; 78 79 public ImmediateListener() 80 { 81 chooser = new JColorChooser(); 82 chooser.getSelectionModel().addChangeListener( 83 event -> setBackground(chooser.getColor()));//监视颜色选择,立即反馈给用户 84 85 dialog = new JDialog((Frame) null, false /* not modal */);//无模式对话框 86 dialog.add(chooser); 87 dialog.pack(); 88 } 89 90 public void actionPerformed(ActionEvent event) 91 { 92 chooser.setColor(getBackground()); 93 dialog.setVisible(true); 94 } 95 } 96 }
运行截图如下:
第三部分:实验总结:
这一周学习了菜单和对话框及API的相关知识,在理论课上老师也对知识点做了相关讲解,在完成此次作业的过程中,好像是因为我的电脑配置问题还是怎样,好几个测试程序都没办法运行出来,最后是在他人的机器上运行出来的。在解读代码的过程中有好多不懂的代码,在程序测试出来后又通过对照运行结果,可以更加直观的体会有些代码的作用,加强对相关知识的理解,在平时要多加强动手能力,多思考。