201871010111-刘佳华《面向对象程序设计(java)》第十五周学习总结
实验十三 Swing图形界面组件(二)
实验时间 2019-12-6
第一部分:理论知识总结
5>.条(JSlider)
滑动条在构造时默认是横向,如果需要纵向滑动条:
JSlider s = new JSlider(SwingConstants.VERTICAL,min,max,initialValue);
当滑动条滑动时,会触发ChangeEvent,需要调用addChangeListener()并且安装一个实现了ChangeListener接口的对象。这个接口只有一个StateChanged方法
//得到滑动条的当前值
ChangeListener listen = event ->{
JSlider s = (JSlider)event.getSource();
int val = s.getValue();
...
};
如果需要显示滑动条的刻度,则setPaintTicks(true);
如果要将滑动条强制对准刻度,则setSnapToTicks(true);
如果要为滑动条设置标签,则需要先构建一个Hashtable< Integer,Component>,将数字与标签对应起来,再调用setLabelTable(Dictionary label);
5.复杂的布局管理
1>GridBagLayout(网格组布局)
即没有限制的网格布局,行和列的尺寸可以改变,且单元格可以合并
过程:
1)建议一个GridBagLayout对象,不需要指定行列数
2)将容器setLayout为GBL对象
3)为每个组件建立GridBagConstraints对象,即约束组件的大小以及排放方式
4)通过add(component,constraints)增加组件
使用帮助类来管理约束会方便很多。
2>不使用布局管理器
frame.setLayout(null);
JButton btn = new JButton("Yes");
frame.add(btn);
btn.setBounds(10,10,100,30);
//void setBounds(int x,int y,int width,int height)//x,y表示左上角的坐标,width/height表示组件宽和高,Component类的方法
3>组件的遍历顺序(焦点的顺序):从左至右从上到下
component.setFocusable(false);//组件不设置焦点
6.菜单
分为JMenuBar/JMenu/JMenuItem,当选择菜单项时会触发一个动作事件,需要注册监听器监听
7.对话框
对话框分为模式对话框和无模对话框,模式对话框就是未处理此对话框之前不允许与其他窗口交互。
1>JOptionPane
提供了四个用静态方法(showxxxx)显示的对话框:
构造对话框的步骤:
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类)
第二部分:实验部分
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 //private TestAction saveAction; 18 19 /** 20 * A sample action that prints the action name to System.out. 21 */ 22 class TestAction extends AbstractAction 23 { 24 public TestAction(String name) 25 { 26 super(name); 27 } 28 29 public void actionPerformed(ActionEvent event) 30 { 31 System.out.println(getValue(Action.NAME) + " selected."); 32 } 33 } 34 35 public MenuFrame() 36 { 37 setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT); 38 39 JMenu fileMenu = new JMenu("File"); 40 fileMenu.add(new TestAction("New"));//添加匿名类对象 41 42 // 演示加速器 43 44 JMenuItem openItem = fileMenu.add(new TestAction("Open")); 45 openItem.setAccelerator(KeyStroke.getKeyStroke("ctrl O"));//设置open的加速器为ctrl+o 46 47 fileMenu.addSeparator();//添加分隔符号在菜单中 48 49 saveAction = new TestAction("Save"); 50 JMenuItem saveItem = fileMenu.add(saveAction); 51 saveItem.setAccelerator(KeyStroke.getKeyStroke("ctrl S")); 52 53 saveAsAction = new TestAction("Save As"); 54 fileMenu.add(saveAsAction); 55 fileMenu.addSeparator(); 56 57 fileMenu.add(new AbstractAction("Exit") 58 { 59 public void actionPerformed(ActionEvent event) 60 { 61 System.exit(0); 62 } 63 }); 64 65 // 演示复选框和单选按钮菜单 66 67 readonlyItem = new JCheckBoxMenuItem("Read-only"); 68 readonlyItem.addActionListener(new ActionListener()//设置只读判断 69 { 70 public void actionPerformed(ActionEvent event) 71 { 72 boolean saveOk = !readonlyItem.isSelected(); 73 saveAction.setEnabled(saveOk); 74 saveAsAction.setEnabled(saveOk); 75 } 76 }); 77 78 var group = new ButtonGroup(); 79 80 var insertItem = new JRadioButtonMenuItem("Insert"); 81 insertItem.setSelected(true); 82 var overtypeItem = new JRadioButtonMenuItem("Overtype"); 83 84 group.add(insertItem); 85 group.add(overtypeItem); 86 87 // 设置小图标 88 89 var cutAction = new TestAction("Cut"); 90 cutAction.putValue(Action.SMALL_ICON, new ImageIcon("C:\\Users\\83583\\Desktop\\java\\corejava\\v1ch11\\cut.gif")); 91 var copyAction = new TestAction("Copy"); 92 copyAction.putValue(Action.SMALL_ICON, new ImageIcon("C:\\Users\\83583\\Desktop\\java\\corejava\\v1ch11\\copy.gif")); 93 var pasteAction = new TestAction("Paste"); 94 pasteAction.putValue(Action.SMALL_ICON, new ImageIcon("C:\\Users\\83583\\Desktop\\java\\corejava\\v1ch11\\paste.gif")); 95 96 var editMenu = new JMenu("Edit"); 97 editMenu.add(cutAction); 98 editMenu.add(copyAction); 99 editMenu.add(pasteAction); 100 101 // 设置二级菜单 102 103 var optionMenu = new JMenu("Options"); 104 105 optionMenu.add(readonlyItem); 106 optionMenu.addSeparator(); 107 optionMenu.add(insertItem); 108 optionMenu.add(overtypeItem); 109 110 editMenu.addSeparator(); 111 editMenu.add(optionMenu); 112 113 // demonstrate mnemonics 114 115 var helpMenu = new JMenu("Help"); 116 helpMenu.setMnemonic('H'); 117 118 var indexItem = new JMenuItem("Index"); 119 indexItem.setMnemonic('I'); 120 helpMenu.add(indexItem); 121 122 // you can also add the mnemonic key to an action 123 var aboutAction = new TestAction("About"); 124 aboutAction.putValue(Action.MNEMONIC_KEY, new Integer('A')); 125 helpMenu.add(aboutAction); 126 127 // add all top-level menus to menu bar 128 129 var menuBar = new JMenuBar(); 130 setJMenuBar(menuBar); 131 132 menuBar.add(fileMenu); 133 menuBar.add(editMenu); 134 menuBar.add(helpMenu); 135 136 // 添加弹出式菜单 137 138 popup = new JPopupMenu(); 139 popup.add(cutAction); 140 popup.add(copyAction); 141 popup.add(pasteAction); 142 143 var panel = new JPanel(); 144 panel.setComponentPopupMenu(popup);//在panel上设置弹出菜单 145 add(panel); 146 } 147 }
1.点击Exit会关闭窗口
2.使用快捷键Ctrl+O和Ctrl+S,操作结果与鼠标点击相同:
通过控制台上显示单击菜单+selected,仿真模拟者个程序的实现过程:
3.Options子菜单(复选框和单选按钮菜单项)
测试程序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 } 21 }
1 package toolBar; 2 3 import java.awt.*; 4 import java.awt.event.*; 5 import javax.swing.*; 6 7 /** 8 * A frame with a toolbar and menu for color changes. 9 */ 10 public class ToolBarFrame extends JFrame 11 { 12 private static final int DEFAULT_WIDTH = 300; 13 private static final int DEFAULT_HEIGHT = 200; 14 private JPanel panel; 15 16 public ToolBarFrame() 17 { 18 setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT); 19 20 // 添加用于改变颜色的面板 21 22 panel = new JPanel(); 23 add(panel, BorderLayout.CENTER); 24 25 // set up actions 26 27 var blueAction = new ColorAction("Blue", new ImageIcon("blue-ball.gif"), Color.BLUE); 28 var yellowAction = new ColorAction("Yellow", new ImageIcon("yellow-ball.gif"),Color.YELLOW); 29 var redAction = new ColorAction("Red", new ImageIcon("red-ball.gif"), Color.RED); 30 31 var exitAction = new AbstractAction("Exit", new ImageIcon("exit.gif")) 32 { 33 public void actionPerformed(ActionEvent event) 34 { 35 System.exit(0); 36 } 37 }; 38 exitAction.putValue(Action.SHORT_DESCRIPTION, "Exit");//The key used for storing a short Stringdescription for the action, used for tooltip text. 39 40 41 // 填充工具栏 42 43 var bar = new JToolBar(); 44 bar.add(blueAction); 45 bar.add(yellowAction); 46 bar.add(redAction); 47 bar.addSeparator(); 48 bar.add(exitAction); 49 add(bar, BorderLayout.NORTH); 50 51 // 填充菜单 52 53 var menu = new JMenu("Color"); 54 menu.add(yellowAction); 55 menu.add(blueAction); 56 menu.add(redAction); 57 menu.add(exitAction); 58 var menuBar = new JMenuBar(); 59 menuBar.add(menu); 60 //setJMenuBar(menuBar); 61 this.setJMenuBar(menuBar); 62 } 63 64 /** 65 * The color action sets the background of the frame to a given color. 66 */ 67 class ColorAction extends AbstractAction 68 { 69 public ColorAction(String name, Icon icon, Color c)//javax.swing.AbstractAction.putValue(String key, Object newValue) 70 { //构造coloraction的构造器 71 putValue(Action.NAME, name); 72 putValue(Action.SMALL_ICON, icon); 73 putValue(Action.SHORT_DESCRIPTION, name + " background"); 74 putValue("Color", c); 75 } 76 77 public void actionPerformed(ActionEvent event) 78 { 79 Color c = (Color) getValue("Color");//获取颜色值并且赋给颜色对象变量 80 panel.setBackground(c);//设置背景颜色 81 } 82 } 83 }
初始状态:
分别点击小图标之后,面板颜色会变化与小图标一致:(以蓝色为例)
将鼠标放置在四个按钮上都会有对应的提示(如图):
此外,除了小图标控制之后,菜单栏color也能实现同样的操作:
- 问题与疑惑:
1.在于ColorAction类中的ColorAction构造器中的putValue方法
public ColorAction(String name, Icon icon, Color c)//javax.swing.AbstractAction.putValue(String key, Object newValue)
{ //构造coloraction的构造器
putValue(Action.NAME, name);
putValue(Action.SMALL_ICON, icon);
putValue(Action.SHORT_DESCRIPTION, name + " background");
putValue("Color", c);
}
2.在程序中通过add(bar, BorderLayout.NORTH);设置工具栏在面板中的布局为边框布局北位置,但是在拖动工具栏时,
它的位置会发生变化,还可以将整个工具栏拖拽出面板(已解决):
工具栏的特殊之处在于它可以被随处移动,可以将其拖拽至框架的四个边框上(如上图1)也可以完全脱离框架(如上图2),
注意:工具栏只有位于采用边框布局或者支持NORTH,SOURTH,WEST,EAST,约束的布局管理器的容器中才能够被拖拽。
测试程序3
l 在elipse IDE中调试运行教材544页程序12-15、12-16,结合运行结果理解程序;
l 掌握选项对话框的用法。
l 记录示例代码阅读理解中存在的问题与疑惑。
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 JRadioButton b = new JRadioButton(option); 27 b.setActionCommand(option); 28 add(b); 29 group.add(b); 30 b.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 JPanel 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 // 添加带有“显示”按钮的面板 48 49 JPanel showPanel = new JPanel(); 50 JButton 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 * Gets the currently selected message. 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); 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 Graphics2D g2 = (Graphics2D) g; 145 Rectangle2D 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 }
1 package optionDialog; 2 3 import java.awt.*; 4 import javax.swing.*; 5 6 /** 7 * @version 1.34 2015-06-12 8 * @author Cay Horstmann 9 */ 10 public class OptionDialogTest 11 { 12 public static void main(String[] args) 13 { 14 EventQueue.invokeLater(() -> { 15 JFrame frame = new OptionDialogFrame(); 16 frame.setTitle("OptionDialogTest"); 17 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 18 frame.setVisible(true); 19 }); 20 } 21 }
运行截图:
测试程序4
l 在elipse IDE中调试运行教材552页程序12-17、12-18,结合运行结果理解程序;
l 掌握对话框的创建方法;
l 记录示例代码阅读理解中存在的问题与疑惑。
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 the OK button. 13 */ 14 public class AboutDialog extends JDialog 15 { 16 public AboutDialog(JFrame owner) 17 { 18 super(owner, "About DialogTest", true); 19 20 // 将HTML标签添加到中心 21 22 add( 23 new JLabel( 24 "Core Java
By Cay Horstmann"), 25 BorderLayout.CENTER); 26 27 // 确定按钮关闭对话框 28 29 JButton ok = new JButton("OK"); 30 ok.addActionListener(event -> setVisible(false)); 31 32 // 将“确定”按钮添加到南部边界 33 34 JPanel panel = new JPanel(); 35 panel.add(ok); 36 add(panel, BorderLayout.SOUTH); 37 38 pack(); 39 } 40 }
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 // 构造一个文件菜单。 22 23 JMenuBar menuBar = new JMenuBar(); 24 setJMenuBar(menuBar); 25 JMenu fileMenu = new JMenu("File"); 26 menuBar.add(fileMenu); 27 28 // 添加和退出菜单项。 29 30 // About项显示About对话框。 31 32 JMenuItem aboutItem = new JMenuItem("About"); 33 aboutItem.addActionListener(event -> { 34 if (dialog == null) // first time 35 dialog = new AboutDialog(DialogFrame.this); 36 dialog.setVisible(true); // pop up dialog 37 }); 38 fileMenu.add(aboutItem); 39 40 // 退出项退出程序。 41 42 JMenuItem 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.*; 4 import javax.swing.*; 5 6 /** 7 * @version 1.34 2012-06-12 8 * @author Cay Horstmann 9 */ 10 public class DialogTest 11 { 12 public static void main(String[] args) 13 { 14 EventQueue.invokeLater(() -> { 15 JFrame frame = new DialogFrame(); 16 frame.setTitle("DialogTest"); 17 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 18 frame.setVisible(true); 19 }); 20 } 21 }
运行截图:
测试程序5
l 在elipse IDE中调试运行教材556页程序12-19、12-20,结合运行结果理解程序;
l 掌握对话框的数据交换用法;
l 记录示例代码阅读理解中存在的问题与疑惑。
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 // 构造文件菜单 20 21 JMenuBar mbar = new JMenuBar(); 22 setJMenuBar(mbar); 23 JMenu fileMenu = new JMenu("File"); 24 mbar.add(fileMenu); 25 26 // 添加连接和退出菜单项 27 28 JMenuItem connectItem = new JMenuItem("Connect"); 29 connectItem.addActionListener(new ConnectAction()); 30 fileMenu.add(connectItem); 31 32 // 退出项退出程序 33 34 JMenuItem 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 // pop up dialog 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.*; 4 import javax.swing.*; 5 6 /** 7 * @version 1.34 2015-06-12 8 * @author Cay Horstmann 9 */ 10 public class DataExchangeTest 11 { 12 public static void main(String[] args) 13 { 14 EventQueue.invokeLater(() -> { 15 JFrame 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.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 // 使用用户名和密码字段构造面板 32 33 JPanel 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 // 创建终止对话框的“确定”和“取消”按钮 42 43 okButton = new JButton("Ok"); 44 okButton.addActionListener(event -> { 45 ok = true; 46 dialog.setVisible(false); 47 }); 48 49 JButton cancelButton = new JButton("Cancel"); 50 cancelButton.addActionListener(event -> dialog.setVisible(false)); 51 52 // 将按钮添加到南边界 53 54 JPanel 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 // locate the owner frame 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 // if first time, or if owner has changed, make new dialog 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 // set title and show dialog 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-22、12-23,结合程序运行结果理解程序;
l 掌握文件对话框的用法;
l 记录示例代码阅读理解中存在的问题与疑惑。
1 package fileChooser; 2 3 import java.awt.*; 4 import javax.swing.*; 5 6 /** 7 * @version 1.25 2015-06-12 8 * @author Cay Horstmann 9 */ 10 public class FileChooserTest 11 { 12 public static void main(String[] args) 13 { 14 EventQueue.invokeLater(() -> { 15 JFrame 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 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 }
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 JMenuBar menuBar = new JMenuBar(); 26 setJMenuBar(menuBar); 27 28 JMenu menu = new JMenu("File"); 29 menuBar.add(menu); 30 31 JMenuItem 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 JMenuItem 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 // set up file chooser 57 chooser = new JFileChooser(); 58 59 // 接受所有以.jpg、.jpeg、.gif结尾的图像文件 60 FileFilter 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()); 22 23 chooser.addPropertyChangeListener(event -> { 24 if (event.getPropertyName() == JFileChooser.SELECTED_FILE_CHANGED_PROPERTY) 25 { 26 // the user has selected a new file 27 File f = (File) event.getNewValue(); 28 if (f == null) 29 { 30 setIcon(null); 31 return; 32 } 33 34 // 将图像读入图标 35 ImageIcon 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 }
运行截图:
测试程序7
l 在elipse IDE中调试运行教材570页程序12-24,结合运行结果理解程序;
l 了解颜色选择器的用法。
记录示例代码阅读理解中存在的问题与疑惑。
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 // 将颜色选择器面板添加到帧 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 * This listener pops up a modal color chooser 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); 44 } 45 } 46 47 /** 48 * This listener pops up a modeless color chooser. The panel color is changed when the user 49 * clicks the OK button. 50 */ 51 private class ModelessListener implements ActionListener 52 { 53 private JDialog dialog; 54 private JColorChooser chooser; 55 56 public ModelessListener() 57 { 58 chooser = new JColorChooser(); 59 dialog = JColorChooser.createDialog(ColorChooserPanel.this, "Background Color", 60 false /* not modal */, chooser, 61 event -> setBackground(chooser.getColor()), 62 null /* no Cancel button listener */); 63 } 64 65 public void actionPerformed(ActionEvent event) 66 { 67 chooser.setColor(getBackground()); 68 dialog.setVisible(true); 69 } 70 } 71 72 /** 73 * This listener pops up a modeless color chooser. The panel color is changed immediately when 74 * the user picks a new color. 75 */ 76 private class ImmediateListener implements ActionListener 77 { 78 private JDialog dialog; 79 private JColorChooser chooser; 80 81 public ImmediateListener() 82 { 83 chooser = new JColorChooser(); 84 chooser.getSelectionModel().addChangeListener( 85 event -> setBackground(chooser.getColor())); 86 87 dialog = new JDialog((Frame) null, false /* not modal */); 88 dialog.add(chooser); 89 dialog.pack(); 90 } 91 92 public void actionPerformed(ActionEvent event) 93 { 94 chooser.setColor(getBackground()); 95 dialog.setVisible(true); 96 } 97 } 98 }
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 }
运行截图:
第三部分:实验心得
这一周继续学习了Swing用户界面组件以及GUI相关组件。在学习过程中,知识内容较多,也比较庞杂,自己对理论知识的学习也学的比较混乱,混淆了这几部分的学习内容,实验都有很多相同和类似的地方,在实验过程中任然没有理解的太清楚。在查了课本上的内容之后,稍微有了掌握。在运行程序过程中,对程序中有的代码还是不能理解,通过查书、上网查找才得以理解的同时也希望老师可以讲解一下。