201871010123-吴丽丽《面向对象程序设计(Java)》第十五周学习总结
项目 | 内容 |
这个作业属于哪个课程 | https://www.cnblogs.com/nwnu-daizh/ |
这个作业的要求在哪里 | https://www.cnblogs.com/nwnu-daizh/p/11995615.html |
作业学习目标 |
(1) 掌握菜单组件用途及常用API; (2) 掌握对话框组件用途及常用API; (3) 学习设计简单应用程序的GUI。 |
第一部分:总结菜单、对话框两类组件用途及常用API
12.5 菜单
位于窗口顶部的菜单栏 (menubar ) 包括了下拉菜单的名字。点击一个名字就可以打开包含菜单项 ( menu items ) 和子菜单 ( submenus) 的菜单。 当用户点击菜单项时, 所有的菜单都会被关闭并且将一条消息发送给程序。
12.5.1 菜单创建
首先要创建一个菜单栏:
JMenuBar menuBar = new JMenuBar();
菜单栏是一个可以添加到任何位置的组件。 通常放置在框架的顶部。可以调用 setJMenuBar 方法将菜单栏添加到框架上:
frame.setJMenuBar(menuBar);
需要为每个菜单建立一个菜单对象:
JMenu editMenu = new JMenu("Edit");
然后将顶层菜单添加到菜单栏中:
menuBar.add(editMenu);
向菜单对象中添加菜单项、分隔符和子菜单:
JMenuItem pasteItem = new JMenuItem("Paste"); editMenu.add(pasteItem) ; editMenu.addSeparator() ; JMenu optionsMenu = . . .; // a submenu editMenu.add(optionsMenu) ;
当用户选择菜单时,将触发一个动作事件。这里需要为每个菜单项安装一个动作监听器。
ActionListener listener = ... ; pasteItem.addActionListener(listener) ;
可以使用 JMenu.add(String s) 方法将菜单项插入到菜单的尾部, 例如:
editMenu.add("Paste");
Add 方法返回创建的子菜单项。可以采用下列方式获取它,并添加监听器:
JMenuItem pasteItem = editMenu.add("Paste"); pasteItem.addActionListener(listener);
在通常情况下, 菜单项触发的命令也可以通过其他用户界面元素(如工具栏上的按钮 )激活。在第 11 章中, 已经看到了如何通过 Action对象来指定命令。通常, 采用扩展抽象类AbstractAction 来定义一个实现 Action 接口的类。这里需要在 AbstractAction 对象的构造器中指定菜单项标签并且覆盖 actionPerformed 方法来获得菜单动作处理器。
----用给定标签构造一个菜单。
JMenuItem add(JMenuItem item)
----添加一个菜单项 (或一个菜单 )。
JMenuItem add(String label)
----用给定标签将一个菜单项添加到菜单中, 并返回这个菜单项。
JMenuItem add(Action a)
----用给定动作将一个菜单项添加到菜单中, 并返回这个菜单项。
void addSeparator()
----将一个分隔符行(separatorline)添加到菜单中。
JMenuItem insert(JMenuItem menu, int index)
----将一个新菜单项(或子菜单)添加到菜单的指定位置。
JMenuItem insert(Action a, int index)
----用给定动作在菜单的指定位置添加一个新菜单项。
void insertSeparator(int index)
----将一个分隔符添加到菜单中。
参数 : index 添加分隔符的位置
void remove(int index)
void remove(JMenuItem item)
----从菜单中删除指定的菜单项。
----用给定标签构造一个菜单项。
JMenuItem(Action a) 1.3
----为给定动作构造一个菜单项。
----为这个按钮或菜单项设置动作。
----为这个框架设置菜单栏。
cutAction.putValue(Action.SMALL_ICON, new ImageIcon("cut.gif"));
当使用动作构造菜单项时,Action.NAME 值将会作为菜单项的文本,而 Action.SMALL_ICON 将会作为图标。
另外, 可以利用 AbstractAction 构造器设置图标
----用给定的标签和图标构造一个菜单项。
----设置文本对应图标的水平位置。
----参数: pos SwingConstants.RIGHT (文本在图标的右侧)或 SwingConstants.LEFT
----用给定的名字和图标构造一个抽象的动作。
JCheckBoxHenuItem readonlyltem = new]CheckBoxMenuItem("Read-only"); optionsMenu.add(readonlyltem);
单选钮菜单项与普通单选钮的工作方式一样, 必须将它们加人到按钮组中。当按钮组中的一个按钮被选中时, 其他按钮都自动地变为未选择项。
ButtonGroup group = new ButtonGroup(); JRadioButtonMenuItem insertItem = new JRadioButtonMenuItem("Insert"); insertItem.setSelected(true); ]RadioButtonMenuItem overtypeItem = new JRadioButtonMenuItem("Overtype"); group.add(insertItem); group.add(overtypeItem); optionsMenu.add(insertItem); optionsMenu.add(overtypeltem);
使用这些菜单项,不需要立刻得到用户选择菜单项的通知。而是使用 isSelected方法来测试菜单项的当前状态(当然, 这意味着应该保留一个实例域保存这个菜单项的引用)。使用setSelected 方法设置状态。
----用给定的标签构造一个复选框菜单项。
JCheckBoxMenuItem(String label , boolean state)
----用给定的标签和给定的初始状态(true 为选定)构造一个复选框菜单。
----用给定的标签构造一个单选钮菜单项。
JRadioButtonMenuItemCString label , boolean state)
----用给定的标签和给定的初始状态(true 为选定)构造一个单选钮菜单项。
void setSelected(boo1ean state)
----获取或设置这个菜单项的选择状态(true 为选定)。
弹出菜单(pop-up menu) 是不固定在菜单栏中随处浮动的菜单。
创建一个弹出菜单与创建一个常规菜单的方法类似,但是弹出菜单没有标题。
JPopupMenu popup = new JPopupMenu();
然后用常规的方法添加菜单项:
JMenuItem item = new JMenuItem("Cut"); item.addActionListener(listener); popup.add(item);
弹出菜单并不像常规菜单栏那样总是显示在框架的顶部,必须调用 show 方法菜单才能显示出来。 调用时需要给出父组件以及相对父组件坐标的显示位置。例如:
popup.show(panel , x, y);
通常, 当用户点击某个鼠标键时弹出菜单。 这就是所谓的弹出式触发器(pop-up trigger) 。 在 Windows 或者 Linux 中, 弹出式触发器是鼠标右键。要想在用户点击某一个组件时弹出菜单, 需要按照下列方式调用方法:
component.setComponentPopupMenu(popup) ;
偶尔会遇到在一个含有弹出菜单的组件中放置一个组件的情况。这个子组件可以调用下列方法继承父组件的弹出菜单。调用:
child.setInheritsPopupMenu(true);
----显示一个弹出菜单。
----参数: c 显示弹出菜单的组件
----x,y 弹出菜单左上角的坐标(C 的坐标空间内)
boolean isPopupTrigger( MouseEvent event ) 1.3
----如果鼠标事件是弹出菜单触发器, 则返回 true 。
JMenuItem aboutltem = new JMenuItem("About" , ' A');
快捷键会自动地显示在菜单项中, 并带有一条下划线。例如,在上面的例子中, 菜单项中的标签为“ About”, 字母 A 带有一个下划线。当显示菜单时,用户只需要按下“ A” 键就可以这个选择菜单项(如果快捷字母没有出现在菜单项标签字符串中, 同样可以按下快捷键选择菜单项, 只是快捷键没有显示出来。显然,这种不可见的快捷键没有提示效果)。
有时候不希望在菜单项的第一个快捷键字母下面加下划线。例如, 如果在菜单项“ Save As” 中使用快捷键“ A”, 则在第二个“ A” ( Save As) 下面加下划线更为合理。可以调用 setDisplayedMnemonicIndex 方法指定希望加下划线的字符。
----用给定的标签和快捷键字符构造一个菜单项。
----参数:label 菜单项的标签
mnemonic 菜单项的快捷键字符, 在标签中这个字符下面会有一个下划线。
void setAccelerator(Keystroke k )
----将 k 设置为这个菜单项的加速器。加速器显示在标签的旁边。
----设置按钮的快捷字符。该字符会在标签中以下划线的形式显示。
void setDisplayedMnemoniclndex( int index ) 1.4
----将按钮文本中的 index 字符设定为带下划线。 如果不希望第一个出现的快捷键字符带下划线, 就可以使用这个方法。
12.5.6 启用和禁用菜单
----启用或禁用菜单项。
----在菜单被选择但尚未打开之前调用。
void menuDeselected(MenuEvent e )
----在菜单被取消选择并且已经关闭之后被调用。
void menuCanceled(MenuEvent e )
----当菜单被取消时被调用。例如, 用户点击菜单以外的区域。
JToolBar ( String titlestring )
JToolBar( int orientation )
JToolBar( String titleString , int orientation )
----用给定的标题字符串和方向构造一个工具栏。orientation 可以是 SwingConstants.HORIZONTAL ( 默认)或 SwingConstants.VERTICAL。
JButton add( Action a )
----用给定的动作名、 图标、 简要的说明和动作回调构造一个工具栏中的新按钮。
void addSeparator( )
----将一个分隔符添加到工具栏的尾部。
----设置当鼠标停留在组件上时显示在工具提示中的文本。
●对话框不能作为一个应用程序的主框架,而必须包含在其他的容器中。
●Java提供多种形式的对话框。
JOptionPane类:支持简单、标准的对话框;
ProgressMonitor类:支持操作进度条控制对话框等。
-showMessageDialog -------信息对话框, 显示信息,告知用户发生了什么情况
-showConfirmDialog -------确认对话框,显示问题,要求用户进行确认(yes/no/cancel)
-showInputDialog -------输入对话框, 提示用户进行输入
1)选择对话框类型(消息、确认、选择、输入)
2)选择消息类型(String/Icon/Component/Object[]/任何其他对象)
3)选择图标(ERROR_MESSAGE/INFORMATION_MESSAGE/WARNING_MESSAGE/QUESTION_MESSAGE/PLAIN_MESSAGE)
4)对于确认对话框,选择按钮类型(DEFAULT_OPTION/YES_NO_OPTION/YES_NO_CANCEL_OPTION/OK_CANCEL_OPTION)
5)对于选项对话框,选择选项(String/Icon/Component)
6)对于输入对话框,选择文本框或组合框
确认对话框和选择对话框调用后会返回按钮值或被选的选项的索引值
2.JDialog类
可以自己创建对话框,需调用超类JDialog类的构造器
public aboutD extends JDialog { public aboutD(JFrame owner) { super(owner,"About Text",true); .... } }
构造JDialog类后需要setVisible才能时窗口可见
if(dialog == null) dialog = new JDialog(); dialog.setVisible(true);
3.文件对话框(JFileChooser类)
4.颜色对话框(JColorChooser类)
实验十三 Swing图形界面组件(二)
实验时间 2019-12-6
1、实验目的与要求
(1) 掌握菜单组件用途及常用API;
(2) 掌握对话框组件用途及常用API;
(3) 学习设计简单应用程序的GUI。
2、实验内容和步骤
实验1: 导入第12章示例程序,测试程序并进行组内讨论。
测试程序1
1)在elipse IDE中调试运行教材512页程序12-8,结合运行结果理解程序;
2)掌握菜单的创建、菜单事件监听器、复选框和单选按钮菜单项、弹出菜单以及快捷键和加速器的用法。
3)记录示例代码阅读理解中存在的问题与疑惑。
MenuTest.java代码如下:
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); }); } }
MenuFrame.java代码如下:
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; /** * A sample action that prints the action name to System.out. */ class TestAction extends AbstractAction { public TestAction(String name) { super(name); } 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")); //将动作添加到菜单中 // demonstrate accelerators 演示加速器 var openItem = fileMenu.add(new TestAction("Open")); openItem.setAccelerator(KeyStroke.getKeyStroke("ctrl O")); // fileMenu.addSeparator(); //向fileMenu添加分隔符 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); //setJMenuBar方法设置菜单栏 //分别将fileMenu、editMenu、helpMenu添加到菜单栏(将顶层菜单添加到菜单栏中) 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); //通过调用setComponentPopupMenu方法,当用户点击面板时弹出菜单 add(panel); } }
运行结果截图如下所示:
测试程序2
1)在elipse IDE中调试运行教材517页程序12-9,结合运行结果理解程序;
2)掌握工具栏和工具提示的用法;
3)记录示例代码阅读理解中存在的问题与疑惑。
ToolBarTest.java代码如下:
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); }); } }
ToolBarFrame.java代码如下:
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 chang( 添加颜色变化面板) 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"); // 填充工具栏 var bar = new JToolBar(); bar.add(blueAction); bar.add(yellowAction); bar.add(redAction); bar.addSeparator(); bar.add(exitAction); add(bar, BorderLayout.NORTH); // 填充菜单 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); } /** * 颜色动作将帧的背景设置为给定的颜色 */ 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
1) 在elipse IDE中调试运行教材544页程序12-15、12-16,结合运行结果理解程序;
2) 掌握选项对话框的用法。
3)记录示例代码阅读理解中存在的问题与疑惑。
ButtonPanel.java代码如下:
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(); } }
OptionDialogTest.java代码如下:
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); }); } }
OptionDialogFrame.java代码如下:
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); } }
运行结果截图如下所示:
测试程序4
1)在elipse IDE中调试运行教材552页程序12-17、12-18,结合运行结果理解程序;
2)掌握对话框的创建方法;
3)记录示例代码阅读理解中存在的问题与疑惑。
DialogTest.java代码如下:
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); }); } }
DialogFrame.java代码如下:
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); // construct a File menu var menuBar = new JMenuBar(); setJMenuBar(menuBar); var fileMenu = new JMenu("File"); menuBar.add(fileMenu); // add About and Exit menu items // the About item shows the About dialog var aboutItem = new JMenuItem("About"); aboutItem.addActionListener(event -> { if (dialog == null) // first time dialog = new AboutDialog(DialogFrame.this); dialog.setVisible(true); // pop up dialog }); fileMenu.add(aboutItem); // the Exit item exits the program var exitItem = new JMenuItem("Exit"); exitItem.addActionListener(event -> System.exit(0)); fileMenu.add(exitItem); } }
AboutDialog.java代码如下:
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); // add HTML label to center add( new JLabel( "<html><h1><i>Core Java</i></h1><hr>By Cay Horstmann</html>"), BorderLayout.CENTER); // OK button closes the dialog var ok = new JButton("OK"); ok.addActionListener(event -> setVisible(false)); // add OK button to southern border var panel = new JPanel(); panel.add(ok); add(panel, BorderLayout.SOUTH); pack(); } }
运行结果截图如下:
点了File下的About后出现结果截图如下:
测试程序5
1) 在elipse IDE中调试运行教材556页程序12-19、12-20,结合运行结果理解程序;
2)掌握对话框的数据交换用法;
3)记录示例代码阅读理解中存在的问题与疑惑。
DataExchangeTest.java代码如下:
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); }); } }
DataExchangeFrame.java代码如下:
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 (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())) + " "); } } } }
PasswordChooser.java代码如下:
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); } /** * 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 (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; } }
User.java代码如下:
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; } }
运行结果截图如下:
测试程序6
1) 在elipse IDE中调试运行教材564页程序12-21、12-22、12-23,结合程序运行结果理解程序;
2)掌握文件对话框的用法;
3)记录示例代码阅读理解中存在的问题与疑惑。
ImageViewerFrame代码如下:
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); // 如果图像文件被接受,将其设置为标签的图标 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、杰伯图形交换格式 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"))); } }
ImagePreviewer.java代码如下:
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); } }); } }
FileIconView.java代码如下:
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; } }
FileChooserTest.java代码如下:
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
1) 在elipse IDE中调试运行教材570页程序12-24,结合运行结果理解程序;
2)了解颜色选择器的用法。
3)记录示例代码阅读理解中存在的问题与疑惑。
ColorChooserFrame.java代码如下:
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); } }
ColorChooserPanel.java代码如下:
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); } } }
ColorChooserTest.java代码如下:
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); }); } }
运行结果截图如下:
点Modal后:
点Immediate后出现:
实验总结:
在本次实验中了解了菜单以及对话框的一些基本操作,知道了菜单组件和对话框组件的用途,并且了解了与他们相关的API,知道如何的去使用,但因自己的学习能力有限,未能将本次实验的内容进行好好的消化,之后自己会再找时间将知识再梳理一遍,争取能更好的掌握知识。