第十四周学习总结
第一部分:理论知识
理论知识:本周学习Swing用户界面
内容:Swing与模型-视图-控制器设计模式;布局管理概述;文本输入 ;选择组件;菜单;复杂的布局管理;对话框;
第二部分:实验部分
实验十四 Swing图形界面组件
实验时间 20178-11-29
1、实验目的与要求
(1) 掌握GUI布局管理器用法;
(2) 掌握各类Java Swing组件用途及常用API;
2、实验内容和步骤
实验1: 导入第12章示例程序,测试程序并进行组内讨论。
测试程序1
l 在elipse IDE中运行教材479页程序12-1,结合运行结果理解程序;
l 掌握各种布局管理器的用法;
l 理解GUI界面中事件处理技术的用途。
l 在布局管理应用代码处添加注释;
1 package First; 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 Calculator 11 { 12 public static void main(String[] args) 13 { 14 EventQueue.invokeLater(() -> { 15 CalculatorFrame frame = new CalculatorFrame(); 16 frame.setTitle("Calculator"); 17 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 18 frame.setVisible(true); 19 }); 20 } 21 }
1 package First; 2 3 import javax.swing.*; 4 5 /** 6 * A frame with a calculator panel. 7 */ 8 public class CalculatorFrame extends JFrame 9 { 10 public CalculatorFrame() 11 { 12 add(new CalculatorPanel()); 13 pack(); 14 } 15 }
1 package First; 2 3 import java.awt.*; 4 import java.awt.event.*; 5 import javax.swing.*; 6 /** 7 * A panel with calculator buttons and a result display. 8 */ 9 public class CalculatorPanel extends JPanel 10 { 11 private JButton display; 12 private JButton increase; 13 private JPanel panel,panel2; 14 private double result; 15 private String lastCommand; 16 private boolean start; 17 18 public CalculatorPanel() 19 { 20 setLayout(new BorderLayout()); 21 22 result = 0; 23 lastCommand = "="; 24 start = true; 25 26 // add the display 27 display = new JButton("0");//显示结果; 28 display.setEnabled(false);//使得显示结果不能更改,与按钮区别开来;使得上面只起到显示作用; 29 add(display, BorderLayout.NORTH);//将结果显示屏放在上面; 30 31 32 ActionListener insert = new InsertAction(); 33 ActionListener command = new CommandAction(); 34 35 // add the buttons in a 4 x 4 grid 36 37 panel = new JPanel(); 38 panel.setLayout(new GridLayout(4, 4)); 39 40 addButton("7", insert); 41 addButton("8", insert); 42 addButton("9", insert); 43 addButton("/", command); 44 45 addButton("4", insert); 46 addButton("5", insert); 47 addButton("6", insert); 48 addButton("*", command); 49 50 addButton("1", insert); 51 addButton("2", insert); 52 addButton("3", insert); 53 addButton("-", command); 54 55 addButton("0", insert); 56 addButton(".", insert); 57 addButton("=", command); 58 addButton("+", command); 59 60 add(panel, BorderLayout.CENTER);//将按键放在中间; 61 62 63 64 JButton b1 = new JButton("验证"); 65 add(b1, BorderLayout.SOUTH); 66 67 JButton bright = new JButton("验证1"); 68 add(bright, BorderLayout.EAST); 69 70 JButton bleft=new JButton("验证2"); 71 add(bleft, BorderLayout.WEST); 72 73 } 74 /** 75 * Adds a button to the center panel. 76 * @param label the button label 77 * @param listener the button listener 78 */ 79 private void addButton(String label, ActionListener listener) 80 { 81 JButton button = new JButton(label);//生成按钮对象; 82 button.addActionListener(listener);//注册监听器对象; 83 panel.add(button);//将按钮添加到面板上去; 84 85 } 86 /** 87 * This action inserts the button action string to the end of the display text. 88 */ 89 private class InsertAction implements ActionListener 90 { 91 public void actionPerformed(ActionEvent event) 92 { 93 String input = event.getActionCommand(); 94 if (start) 95 { 96 display.setText(""); 97 start = false; 98 } 99 display.setText(display.getText() + input); 100 } 101 } 102 /** 103 * This action executes the command that the button action string denotes. 104 */ 105 private class CommandAction implements ActionListener 106 { 107 public void actionPerformed(ActionEvent event) 108 { 109 String command = event.getActionCommand(); 110 111 if (start) 112 { 113 if (command.equals("-")) 114 { 115 display.setText(command); 116 start = false; 117 } 118 else lastCommand = command; 119 } 120 else 121 { 122 //将字符串类型数字符号转化为基本类型的数据; 123 calculate(Double.parseDouble(display.getText())); 124 lastCommand = command; 125 start = true; 126 } 127 } 128 } 129 /** 130 * Carries out the pending calculation. 131 * @param x the value to be accumulated with the prior result. 132 */ 133 public void calculate(double x) 134 { 135 if (lastCommand.equals("+")) result += x; 136 else if (lastCommand.equals("-")) result -= x; 137 else if (lastCommand.equals("*")) result *= x; 138 else if (lastCommand.equals("/")) result /= x; 139 else if (lastCommand.equals("=")) result = x; 140 display.setText("" + result); 141 } 142 }
测试程序2
l 在elipse IDE中调试运行教材486页程序12-2,结合运行结果理解程序;
l 掌握各种文本组件的用法;
l 记录示例代码阅读理解中存在的问题与疑惑。
1 package Forth; 2 3 import java.awt.*; 4 import javax.swing.*; 5 6 /** 7 * @version 1.41 2015-06-12 8 * @author Cay Horstmann 9 */ 10 public class TextComponentTest 11 { 12 public static void main(String[] args) 13 { 14 EventQueue.invokeLater(() -> { 15 JFrame frame = new TextComponentFrame(); 16 frame.setTitle("TextComponentTest"); 17 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 18 frame.setVisible(true); 19 }); 20 } 21 }
1 package Forth; 2 3 import java.awt.BorderLayout; 4 import java.awt.GridLayout; 5 6 import javax.swing.JButton; 7 import javax.swing.JFrame; 8 import javax.swing.JLabel; 9 import javax.swing.JPanel; 10 import javax.swing.JPasswordField; 11 import javax.swing.JScrollPane; 12 import javax.swing.JTextArea; 13 import javax.swing.JTextField; 14 import javax.swing.SwingConstants; 15 16 /** 17 * A frame with sample text components. 18 */ 19 public class TextComponentFrame extends JFrame 20 { 21 public static final int TEXTAREA_ROWS = 8; 22 public static final int TEXTAREA_COLUMNS = 20; 23 24 public TextComponentFrame() 25 { 26 //本窗口有文本域和密码域 27 JTextField textField = new JTextField(); 28 JPasswordField passwordField = new JPasswordField(); 29 30 31 //定义一个Panel,设置了表格布局管理器并指定行与列 32 33 JPanel northPanel = new JPanel(); 34 northPanel.setLayout(new GridLayout(2, 2)); 35 // 添加文本域的标签 36 37 northPanel.add(new JLabel("User name: ", SwingConstants.RIGHT)); 38 northPanel.add(textField);//将文本域添加到panel 39 northPanel.add(new JLabel("Password: ", SwingConstants.RIGHT)); 40 northPanel.add(passwordField); 41 42 add(northPanel, BorderLayout.NORTH);//将pannel添加到frame 43 44 45 JTextArea textArea = new JTextArea(TEXTAREA_ROWS, TEXTAREA_COLUMNS); 46 JScrollPane scrollPane = new JScrollPane(textArea); 47 48 add(scrollPane, BorderLayout.CENTER); 49 50 // 添加按钮以将文本附加到文本区域 51 52 JPanel southPanel = new JPanel(); 53 54 //定义一个按钮,添加到frame下方,并定义监听事件,点击按钮,文本区显示用户名与密码 55 JButton insertButton = new JButton("Insert"); 56 southPanel.add(insertButton); 57 insertButton.addActionListener(event -> 58 textArea.append("User name: " + textField.getText() + " Password: " 59 + new String(passwordField.getPassword()) + "\n")); 60 61 add(southPanel, BorderLayout.SOUTH); 62 pack(); 63 } 64 }
测试程序3
l 在elipse IDE中调试运行教材489页程序12-3,结合运行结果理解程序;
l 掌握复选框组件的用法;
l 记录示例代码阅读理解中存在的问题与疑惑。
1 package practise; 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 CheckBoxTest 11 { 12 public static void main(String[] args) 13 { 14 EventQueue.invokeLater(() -> { 15 JFrame frame = new CheckBoxFrame(); 16 frame.setTitle("CheckBoxTest"); 17 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 18 frame.setVisible(true); 19 }); 20 } 21 }
1 package practise; 2 3 import java.awt.*; 4 import java.awt.event.*; 5 import javax.swing.*; 6 7 /** 8 * A frame with a sample text label and check boxes for selecting font 9 * attributes. 10 */ 11 public class CheckBoxFrame extends JFrame 12 { 13 private JLabel label; 14 private JCheckBox bold; 15 private JCheckBox italic; 16 private static final int FONTSIZE = 24; 17 18 public CheckBoxFrame() 19 { 20 // add the sample text label 21 //添加示例文本标签; 22 23 label = new JLabel("The quick brown fox jumps over the lazy dog."); 24 label.setFont(new Font("Serif", Font.BOLD, FONTSIZE)); 25 add(label, BorderLayout.CENTER); 26 27 //此侦听器将标签的字体属性设置为复选框状态; 28 29 ActionListener listener = event -> { 30 int mode = 0; 31 if (bold.isSelected()) mode += Font.BOLD; 32 if (italic.isSelected()) mode += Font.ITALIC; 33 label.setFont(new Font("Serif", mode, FONTSIZE)); 34 }; 35 36 // 添加复选框 37 38 JPanel buttonPanel = new JPanel(); 39 40 bold = new JCheckBox("Bold"); 41 bold.addActionListener(listener); 42 bold.setSelected(true); 43 buttonPanel.add(bold); 44 45 italic = new JCheckBox("Italic"); 46 italic.addActionListener(listener); 47 buttonPanel.add(italic); 48 49 add(buttonPanel, BorderLayout.SOUTH); 50 pack(); 51 } 52 }
测试程序4
l 在elipse IDE中调试运行教材491页程序12-4,运行结果理解程序;
l 掌握单选按钮组件的用法;
l 记录示例代码阅读理解中存在的问题与疑惑。
1 package Second; 2 3 import java.awt.*; 4 5 import javax.swing.*; 6 7 /** 8 * @version 1.34 2015-06-12 9 * @author Cay Horstmann 10 */ 11 public class RadioButtonTest 12 { 13 public static void main(String[] args) 14 { 15 EventQueue.invokeLater(() -> { 16 JFrame frame = new RadioButtonFrame(); 17 frame.setTitle("RadioButtonTest"); 18 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 19 frame.setVisible(true); 20 }); 21 } 22 }
1 package Second; 2 3 import java.awt.*; 4 import java.awt.event.*; 5 import javax.swing.*; 6 7 /** 8 * A frame with a sample text label and radio buttons for selecting font sizes. 9 */ 10 public class RadioButtonFrame extends JFrame 11 { 12 private JPanel buttonPanel; 13 private ButtonGroup group; 14 private JLabel label; 15 private static final int DEFAULT_SIZE = 36; 16 17 public RadioButtonFrame() 18 { 19 // 添加示例文本标签 20 21 label = new JLabel("The quick brown fox jumps over the lazy dog."); 22 label.setFont(new Font("Serif", Font.PLAIN, DEFAULT_SIZE)); 23 add(label, BorderLayout.CENTER); 24 25 // 添加单选按钮; 26 27 buttonPanel = new JPanel(); 28 group = new ButtonGroup(); 29 30 addRadioButton("Small", 8); 31 addRadioButton("Medium", 12); 32 addRadioButton("Large", 18); 33 addRadioButton("Extra large", 36); 34 35 add(buttonPanel, BorderLayout.SOUTH); 36 pack(); 37 } 38 39 /** 40 * Adds a radio button that sets the font size of the sample text. 41 * @param name the string to appear on the button 42 * @param size the font size that this button sets 43 */ 44 public void addRadioButton(String name, int size) 45 { 46 boolean selected = size == DEFAULT_SIZE; 47 JRadioButton button = new JRadioButton(name, selected); 48 group.add(button); 49 buttonPanel.add(button); 50 51 // 此监听器设定标签字型大小 52 53 ActionListener listener = event -> label.setFont(new Font("Serif", Font.PLAIN, size)); 54 55 button.addActionListener(listener); 56 } 57 }
测试程序5
l 在elipse IDE中调试运行教材494页程序12-5,结合运行结果理解程序;
l 掌握边框的用法;
l 记录示例代码阅读理解中存在的问题与疑惑。
1 package Third; 2 3 import java.awt.*; 4 import javax.swing.*; 5 6 /** 7 * @version 1.34 2015-06-13 8 * @author Cay Horstmann 9 */ 10 public class BorderTest 11 { 12 public static void main(String[] args) 13 { 14 EventQueue.invokeLater(() -> { 15 JFrame frame = new BorderFrame(); 16 frame.setTitle("BorderTest"); 17 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 18 frame.setVisible(true); 19 }); 20 } 21 }
1 package Third; 2 3 import java.awt.*; 4 import javax.swing.*; 5 import javax.swing.border.*; 6 7 /** 8 * A frame with radio buttons to pick a border style. 9 */ 10 public class BorderFrame extends JFrame 11 { 12 private JPanel demoPanel; 13 private JPanel buttonPanel; 14 private ButtonGroup group; 15 16 public BorderFrame() 17 { 18 demoPanel = new JPanel(); 19 buttonPanel = new JPanel(); 20 group = new ButtonGroup(); 21 22 addRadioButton("Lowered bevel", BorderFactory.createLoweredBevelBorder());//创建一个具有凹面效果的边框; 23 addRadioButton("Raised bevel", BorderFactory.createRaisedBevelBorder());//创建一个具有凸面效果的边框; 24 addRadioButton("Etched", BorderFactory.createEtchedBorder());//创建一个具有3D效果的直线边框; 25 addRadioButton("Line", BorderFactory.createLineBorder(Color.BLUE));//创建一个具有3D效果的蓝色直线边框; 26 addRadioButton("Matte", BorderFactory.createMatteBorder(10, 10, 10, 10, Color.BLUE));//创建一个用蓝色填充的粗边框; 27 addRadioButton("Empty", BorderFactory.createEmptyBorder());//创建一个空边框; 28 //将一个带有标题的蚀刻边框添加到面板; 29 Border etched = BorderFactory.createEtchedBorder(); 30 Border titled = BorderFactory.createTitledBorder(etched, "Border types"); 31 buttonPanel.setBorder(titled); 32 33 setLayout(new GridLayout(2, 1));//设置了表格布局管理器并指定行与列 34 add(buttonPanel); 35 add(demoPanel); 36 pack(); 37 } 38 39 public void addRadioButton(String buttonName, Border b) 40 { 41 JRadioButton button = new JRadioButton(buttonName); 42 button.addActionListener(event -> demoPanel.setBorder(b)); 43 group.add(button); 44 buttonPanel.add(button); 45 } 46 }
测试程序6
l 在elipse IDE中调试运行教材498页程序12-6,结合运行结果理解程序;
l 掌握组合框组件的用法;
l 记录示例代码阅读理解中存在的问题与疑惑。
1 package Fifth; 2 3 import java.awt.*; 4 import javax.swing.*; 5 6 /** 7 * @version 1.35 2015-06-12 8 * @author Cay Horstmann 9 */ 10 public class ComboBoxTest 11 { 12 public static void main(String[] args) 13 { 14 EventQueue.invokeLater(() -> { 15 JFrame frame = new ComboBoxFrame(); 16 frame.setTitle("ComboBoxTest"); 17 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 18 frame.setVisible(true); 19 }); 20 } 21 }
1 package Fifth; 2 3 import java.awt.BorderLayout; 4 import java.awt.Font; 5 6 import javax.swing.JComboBox; 7 import javax.swing.JFrame; 8 import javax.swing.JLabel; 9 import javax.swing.JPanel; 10 11 /** 12 * A frame with a sample text label and a combo box for selecting font faces. 13 */ 14 public class ComboBoxFrame extends JFrame 15 { 16 private JComboBoxfaceCombo; 17 private JLabel label; 18 private static final int DEFAULT_SIZE = 24; 19 20 public ComboBoxFrame() 21 { 22 //添加示例文本标签 23 24 label = new JLabel("The quick brown fox jumps over the lazy dog."); 25 label.setFont(new Font("Serif", Font.PLAIN, DEFAULT_SIZE)); 26 add(label, BorderLayout.CENTER); 27 28 // 创建组合框并添加人脸名称 29 30 faceCombo = new JComboBox<>(); 31 faceCombo.addItem("Serif"); 32 faceCombo.addItem("SansSerif"); 33 faceCombo.addItem("Monospaced"); 34 faceCombo.addItem("Dialog"); 35 faceCombo.addItem("DialogInput"); 36 37 // 组合框侦听器将标签字体更改为选定的人脸名 38 39 faceCombo.addActionListener(event -> 40 label.setFont( 41 new Font(faceCombo.getItemAt(faceCombo.getSelectedIndex()), 42 Font.PLAIN, DEFAULT_SIZE))); 43 44 // 添加组合框到框架南部边框的面板 45 46 JPanel comboPanel = new JPanel(); 47 comboPanel.add(faceCombo); 48 add(comboPanel, BorderLayout.SOUTH); 49 pack(); 50 } 51 }
测试程序7
l 在elipse IDE中调试运行教材501页程序12-7,结合运行结果理解程序;
l 掌握滑动条组件的用法;
l 记录示例代码阅读理解中存在的问题与疑惑。
1 package Fifth; 2 3 import java.awt.*; 4 5 import javax.swing.*; 6 7 /** 8 * @version 1.15 2015-06-12 9 * @author Cay Horstmann 10 */ 11 public class SliderTest 12 { 13 public static void main(String[] args) 14 { 15 EventQueue.invokeLater(() -> { 16 SliderFrame frame = new SliderFrame(); 17 frame.setTitle("SliderTest"); 18 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 19 frame.setVisible(true); 20 }); 21 } 22 }
1 package Fifth; 2 3 import java.awt.*; 4 5 import java.util.*; 6 import javax.swing.*; 7 import javax.swing.event.*; 8 9 /** 10 * A frame with many sliders and a text field to show slider values. 11 */ 12 public class SliderFrame extends JFrame 13 { 14 private JPanel sliderPanel; 15 private JTextField textField; 16 private ChangeListener listener; 17 18 public SliderFrame() 19 { 20 sliderPanel = new JPanel(); 21 sliderPanel.setLayout(new GridBagLayout()); 22 23 // 所有滑动条的常见监听器 24 listener = event -> { 25 // update text field when the slider value changes 26 JSlider source = (JSlider) event.getSource(); 27 textField.setText("" + source.getValue()); 28 }; 29 30 //添加普通滑动条; 31 32 JSlider slider = new JSlider(); 33 addSlider(slider, "Plain"); 34 35 // 加入一个滑动条, 36 slider = new JSlider(); 37 slider.setPaintTicks(true); 38 slider.setMajorTickSpacing(20); 39 slider.setMinorTickSpacing(5); 40 addSlider(slider, "Ticks"); 41 42 //添加一个滑块,该滑块可以扣在滴答上 43 44 slider = new JSlider(); 45 slider.setPaintTicks(true); 46 slider.setSnapToTicks(true); 47 slider.setMajorTickSpacing(20); 48 slider.setMinorTickSpacing(5); 49 addSlider(slider, "Snap to ticks"); 50 51 // 添加无轨迹的滑块 52 53 slider = new JSlider(); 54 slider.setPaintTicks(true); 55 slider.setMajorTickSpacing(20); 56 slider.setMinorTickSpacing(5); 57 slider.setPaintTrack(false); 58 addSlider(slider, "No track"); 59 60 61 62 slider = new JSlider(); 63 slider.setPaintTicks(true); 64 slider.setMajorTickSpacing(20); 65 slider.setMinorTickSpacing(5); 66 slider.setInverted(true); 67 addSlider(slider, "Inverted"); 68 69 // add a slider with numeric labels 70 71 slider = new JSlider(); 72 slider.setPaintTicks(true); 73 slider.setPaintLabels(true); 74 slider.setMajorTickSpacing(20); 75 slider.setMinorTickSpacing(5); 76 addSlider(slider, "Labels"); 77 78 // add a slider with alphabetic labels 79 80 slider = new JSlider(); 81 slider.setPaintLabels(true); 82 slider.setPaintTicks(true); 83 slider.setMajorTickSpacing(20); 84 slider.setMinorTickSpacing(5); 85 86 DictionarylabelTable = new Hashtable<>(); 87 labelTable.put(0, new JLabel("A")); 88 labelTable.put(20, new JLabel("B")); 89 labelTable.put(40, new JLabel("C")); 90 labelTable.put(60, new JLabel("D")); 91 labelTable.put(80, new JLabel("E")); 92 labelTable.put(100, new JLabel("F")); 93 94 slider.setLabelTable(labelTable); 95 addSlider(slider, "Custom labels"); 96 97 // add a slider with icon labels 98 99 slider = new JSlider(); 100 slider.setPaintTicks(true); 101 slider.setPaintLabels(true); 102 slider.setSnapToTicks(true); 103 slider.setMajorTickSpacing(20); 104 slider.setMinorTickSpacing(20); 105 106 labelTable = new Hashtable (); 107 108 // add card images 109 110 labelTable.put(0, new JLabel(new ImageIcon("nine.gif"))); 111 labelTable.put(20, new JLabel(new ImageIcon("ten.gif"))); 112 labelTable.put(40, new JLabel(new ImageIcon("jack.gif"))); 113 labelTable.put(60, new JLabel(new ImageIcon("queen.gif"))); 114 labelTable.put(80, new JLabel(new ImageIcon("king.gif"))); 115 labelTable.put(100, new JLabel(new ImageIcon("ace.gif"))); 116 117 slider.setLabelTable(labelTable); 118 addSlider(slider, "Icon labels"); 119 120 // add the text field that displays the slider value 121 122 textField = new JTextField(); 123 add(sliderPanel, BorderLayout.CENTER); 124 add(textField, BorderLayout.SOUTH); 125 pack(); 126 } 127 128 /** 129 * Adds a slider to the slider panel and hooks up the listener 130 * @param s the slider 131 * @param description the slider description 132 */ 133 public void addSlider(JSlider s, String description) 134 { 135 s.addChangeListener(listener); 136 JPanel panel = new JPanel(); 137 panel.add(s); 138 panel.add(new JLabel(description)); 139 panel.setAlignmentX(Component.LEFT_ALIGNMENT); 140 GridBagConstraints gbc = new GridBagConstraints(); 141 gbc.gridy = sliderPanel.getComponentCount(); 142 gbc.anchor = GridBagConstraints.WEST; 143 sliderPanel.add(panel, gbc); 144 } 145 }
测试程序8
l 在elipse IDE中调试运行教材512页程序12-8,结合运行结果理解程序;
l 掌握菜单的创建、菜单事件监听器、复选框和单选按钮菜单项、弹出菜单以及快捷键和加速器的用法。
l 记录示例代码阅读理解中存在的问题与疑惑。
1 package Fifth; 2 3 import java.awt.*; 4 5 import javax.swing.*; 6 7 /** 8 * @version 1.24 2012-06-12 9 * @author Cay Horstmann 10 */ 11 public class MenuTest 12 { 13 public static void main(String[] args) 14 { 15 EventQueue.invokeLater(() -> { 16 JFrame frame = new MenuFrame(); 17 frame.setTitle("MenuTest"); 18 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 19 frame.setVisible(true); 20 }); 21 } 22 }
1 package Fifth; 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 * A sample action that prints the action name to System.out 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."); 31 } 32 } 33 34 public MenuFrame() 35 { 36 setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT); 37 38 JMenu fileMenu = new JMenu("File"); 39 fileMenu.add(new TestAction("New")); 40 41 // demonstrate accelerators 42 43 JMenuItem openItem = fileMenu.add(new TestAction("Open")); 44 openItem.setAccelerator(KeyStroke.getKeyStroke("ctrl O")); 45 46 fileMenu.addSeparator(); 47 48 saveAction = new TestAction("Save"); 49 JMenuItem saveItem = fileMenu.add(saveAction); 50 saveItem.setAccelerator(KeyStroke.getKeyStroke("ctrl S")); 51 52 saveAsAction = new TestAction("Save As"); 53 fileMenu.add(saveAsAction); 54 fileMenu.addSeparator(); 55 56 fileMenu.add(new AbstractAction("Exit") 57 { 58 public void actionPerformed(ActionEvent event) 59 { 60 System.exit(0); 61 } 62 }); 63 64 // demonstrate checkbox and radio button menus 65 66 readonlyItem = new JCheckBoxMenuItem("Read-only"); 67 readonlyItem.addActionListener(new ActionListener() 68 { 69 public void actionPerformed(ActionEvent event) 70 { 71 boolean saveOk = !readonlyItem.isSelected(); 72 saveAction.setEnabled(saveOk); 73 saveAsAction.setEnabled(saveOk); 74 } 75 }); 76 77 ButtonGroup group = new ButtonGroup(); 78 79 JRadioButtonMenuItem insertItem = new JRadioButtonMenuItem("Insert"); 80 insertItem.setSelected(true); 81 JRadioButtonMenuItem overtypeItem = new JRadioButtonMenuItem("Overtype"); 82 83 group.add(insertItem); 84 group.add(overtypeItem); 85 86 // demonstrate icons 87 88 Action cutAction = new TestAction("Cut"); 89 cutAction.putValue(Action.SMALL_ICON, new ImageIcon("cut.gif")); 90 Action copyAction = new TestAction("Copy"); 91 copyAction.putValue(Action.SMALL_ICON, new ImageIcon("copy.gif")); 92 Action pasteAction = new TestAction("Paste"); 93 pasteAction.putValue(Action.SMALL_ICON, new ImageIcon("paste.gif")); 94 95 JMenu editMenu = new JMenu("Edit"); 96 editMenu.add(cutAction); 97 editMenu.add(copyAction); 98 editMenu.add(pasteAction); 99 100 // demonstrate nested menus 101 102 JMenu optionMenu = new JMenu("Options"); 103 104 optionMenu.add(readonlyItem); 105 optionMenu.addSeparator(); 106 optionMenu.add(insertItem); 107 optionMenu.add(overtypeItem); 108 109 editMenu.addSeparator(); 110 editMenu.add(optionMenu); 111 112 // demonstrate mnemonics 113 114 JMenu helpMenu = new JMenu("Help"); 115 helpMenu.setMnemonic('H'); 116 117 JMenuItem indexItem = new JMenuItem("Index"); 118 indexItem.setMnemonic('I'); 119 helpMenu.add(indexItem); 120 121 // you can also add the mnemonic key to an action 122 Action aboutAction = new TestAction("About"); 123 aboutAction.putValue(Action.MNEMONIC_KEY, new Integer('A')); 124 helpMenu.add(aboutAction); 125 126 // add all top-level menus to menu bar 127 128 JMenuBar menuBar = new JMenuBar(); 129 setJMenuBar(menuBar); 130 131 menuBar.add(fileMenu); 132 menuBar.add(editMenu); 133 menuBar.add(helpMenu); 134 135 // demonstrate pop-ups 136 137 popup = new JPopupMenu(); 138 popup.add(cutAction); 139 popup.add(copyAction); 140 popup.add(pasteAction); 141 142 JPanel panel = new JPanel(); 143 panel.setComponentPopupMenu(popup); 144 add(panel); 145 } 146 }
测试程序9
l 在elipse IDE中调试运行教材517页程序12-9,结合运行结果理解程序;
l 掌握工具栏和工具提示的用法;
l 记录示例代码阅读理解中存在的问题与疑惑。
1 package First; 2 3 import java.awt.*; 4 5 import javax.swing.*; 6 7 /** 8 * @version 1.14 2015-06-12 9 * @author Cay Horstmann 10 */ 11 public class ToolBarTest 12 { 13 public static void main(String[] args) 14 { 15 EventQueue.invokeLater(() -> { 16 ToolBarFrame frame = new ToolBarFrame(); 17 frame.setTitle("ToolBarTest"); 18 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 19 frame.setVisible(true); 20 }); 21 } 22 }
1 package First; 2 3 import java.awt.*; 4 5 import java.awt.event.*; 6 import javax.swing.*; 7 8 /** 9 * A frame with a toolbar and menu for color changes. 10 */ 11 public class ToolBarFrame extends JFrame 12 { 13 private static final int DEFAULT_WIDTH = 300; 14 private static final int DEFAULT_HEIGHT = 200; 15 private JPanel panel; 16 17 public ToolBarFrame() 18 { 19 setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT); 20 21 // 添加颜色更改面板 22 23 panel = new JPanel(); 24 add(panel, BorderLayout.CENTER); 25 26 // 设定动作 27 28 Action blueAction = new ColorAction("Blue", new ImageIcon("blue.png"), Color.BLUE); 29 Action yellowAction = new ColorAction("Yellow", new ImageIcon("yellow.png"), 30 Color.YELLOW); 31 Action redAction = new ColorAction("Red", new ImageIcon("red.png"), Color.RED); 32 33 Action exitAction = new AbstractAction("Exit", new ImageIcon("exit.gif")) 34 { 35 public void actionPerformed(ActionEvent event) 36 { 37 System.exit(0); 38 } 39 }; 40 exitAction.putValue(Action.SHORT_DESCRIPTION, "Exit"); 41 42 // 填充工具栏 43 44 JToolBar bar = new JToolBar(); 45 bar.add(blueAction); 46 bar.add(yellowAction); 47 bar.add(redAction); 48 bar.addSeparator(); 49 bar.add(exitAction); 50 add(bar, BorderLayout.NORTH); 51 52 // 填充菜单 53 54 JMenu menu = new JMenu("Color"); 55 menu.add(yellowAction); 56 menu.add(blueAction); 57 menu.add(redAction); 58 menu.add(exitAction); 59 JMenuBar menuBar = new JMenuBar(); 60 menuBar.add(menu); 61 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) 70 { 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 }
测试程序10
l 在elipse IDE中调试运行教材524页程序12-10、12-11,结合运行结果理解程序,了解GridbagLayout的用法。
l 在elipse IDE中调试运行教材533页程序12-12,结合程序运行结果理解程序,了解GroupLayout的用法。
l 记录示例代码阅读理解中存在的问题与疑惑。
1 package Forth; 2 3 import java.awt.EventQueue; 4 5 import javax.swing.JFrame; 6 7 /** 8 * @version 1.35 2015-06-12 9 * @author Cay Horstmann 10 */ 11 public class GridBagLayoutTest 12 { 13 public static void main(String[] args) 14 { 15 EventQueue.invokeLater(() -> { 16 JFrame frame = new FontFrame(); 17 frame.setTitle("GridBagLayoutTest"); 18 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 19 frame.setVisible(true); 20 }); 21 } 22 }
1 package Forth; 2 3 import java.awt.*; 4 5 /** 6 * This class simplifies the use of the GridBagConstraints class. 7 * @version 1.01 2004-05-06 8 * @author Cay Horstmann 9 */ 10 public class GBC extends GridBagConstraints 11 { 12 /** 13 * Constructs a GBC with a given gridx and gridy position and all other grid 14 * bag constraint values set to the default. 15 * @param gridx the gridx position 16 * @param gridy the gridy position 17 */ 18 public GBC(int gridx, int gridy) 19 { 20 this.gridx = gridx; 21 this.gridy = gridy; 22 } 23 24 /** 25 * Constructs a GBC with given gridx, gridy, gridwidth, gridheight and all 26 * other grid bag constraint values set to the default. 27 * @param gridx the gridx position 28 * @param gridy the gridy position 29 * @param gridwidth the cell span in x-direction 30 * @param gridheight the cell span in y-direction 31 */ 32 public GBC(int gridx, int gridy, int gridwidth, int gridheight) 33 { 34 this.gridx = gridx; 35 this.gridy = gridy; 36 this.gridwidth = gridwidth; 37 this.gridheight = gridheight; 38 } 39 40 /** 41 * Sets the anchor. 42 * @param anchor the anchor value 43 * @return this object for further modification 44 */ 45 public GBC setAnchor(int anchor) 46 { 47 this.anchor = anchor; 48 return this; 49 } 50 51 /** 52 * Sets the fill direction. 53 * @param fill the fill direction 54 * @return this object for further modification 55 */ 56 public GBC setFill(int fill) 57 { 58 this.fill = fill; 59 return this; 60 } 61 62 /** 63 * Sets the cell weights. 64 * @param weightx the cell weight in x-direction 65 * @param weighty the cell weight in y-direction 66 * @return this object for further modification 67 */ 68 public GBC setWeight(double weightx, double weighty) 69 { 70 this.weightx = weightx; 71 this.weighty = weighty; 72 return this; 73 } 74 75 /** 76 * Sets the insets of this cell. 77 * @param distance the spacing to use in all directions 78 * @return this object for further modification 79 */ 80 public GBC setInsets(int distance) 81 { 82 this.insets = new Insets(distance, distance, distance, distance); 83 return this; 84 } 85 86 /** 87 * Sets the insets of this cell. 88 * @param top the spacing to use on top 89 * @param left the spacing to use to the left 90 * @param bottom the spacing to use on the bottom 91 * @param right the spacing to use to the right 92 * @return this object for further modification 93 */ 94 public GBC setInsets(int top, int left, int bottom, int right) 95 { 96 this.insets = new Insets(top, left, bottom, right); 97 return this; 98 } 99 100 /** 101 * Sets the internal padding 102 * @param ipadx the internal padding in x-direction 103 * @param ipady the internal padding in y-direction 104 * @return this object for further modification 105 */ 106 public GBC setIpad(int ipadx, int ipady) 107 { 108 this.ipadx = ipadx; 109 this.ipady = ipady; 110 return this; 111 } 112 }
1 package Forth; 2 3 import java.awt.Font; 4 import java.awt.GridBagLayout; 5 import java.awt.event.ActionListener; 6 7 import javax.swing.BorderFactory; 8 import javax.swing.JCheckBox; 9 import javax.swing.JComboBox; 10 import javax.swing.JFrame; 11 import javax.swing.JLabel; 12 import javax.swing.JTextArea; 13 14 /** 15 * A frame that uses a grid bag layout to arrange font selection components. 16 */ 17 public class FontFrame extends JFrame 18 { 19 public static final int TEXT_ROWS = 10; 20 public static final int TEXT_COLUMNS = 20; 21 22 private JComboBoxface; 23 private JComboBox size; 24 private JCheckBox bold; 25 private JCheckBox italic; 26 private JTextArea sample; 27 28 public FontFrame() 29 { 30 GridBagLayout layout = new GridBagLayout(); 31 setLayout(layout); 32 33 ActionListener listener = event -> updateSample(); 34 35 // 构造组件 36 37 JLabel faceLabel = new JLabel("Face: "); 38 39 face = new JComboBox<>(new String[] { "Serif", "SansSerif", "Monospaced", 40 "Dialog", "DialogInput" }); 41 42 face.addActionListener(listener); 43 44 JLabel sizeLabel = new JLabel("Size: "); 45 46 size = new JComboBox<>(new Integer[] { 8, 10, 12, 15, 18, 24, 36, 48 }); 47 48 size.addActionListener(listener); 49 50 bold = new JCheckBox("Bold"); 51 bold.addActionListener(listener); 52 53 italic = new JCheckBox("Italic"); 54 italic.addActionListener(listener); 55 56 sample = new JTextArea(TEXT_ROWS, TEXT_COLUMNS); 57 sample.setText("The quick brown fox jumps over the lazy dog"); 58 sample.setEditable(false); 59 sample.setLineWrap(true); 60 sample.setBorder(BorderFactory.createEtchedBorder()); 61 62 // 使用GBC方便类向网格中添加组件 63 64 add(faceLabel, new GBC(0, 0).setAnchor(GBC.EAST)); 65 add(face, new GBC(1, 0).setFill(GBC.HORIZONTAL).setWeight(100, 0) 66 .setInsets(1)); 67 add(sizeLabel, new GBC(0, 1).setAnchor(GBC.EAST)); 68 add(size, new GBC(1, 1).setFill(GBC.HORIZONTAL).setWeight(100, 0) 69 .setInsets(1)); 70 add(bold, new GBC(0, 2, 2, 1).setAnchor(GBC.CENTER).setWeight(100, 100)); 71 add(italic, new GBC(0, 3, 2, 1).setAnchor(GBC.CENTER).setWeight(100, 100)); 72 add(sample, new GBC(2, 0, 1, 4).setFill(GBC.BOTH).setWeight(100, 100)); 73 pack(); 74 updateSample(); 75 } 76 77 public void updateSample() 78 { 79 String fontFace = (String) face.getSelectedItem(); 80 int fontStyle = (bold.isSelected() ? Font.BOLD : 0) 81 + (italic.isSelected() ? Font.ITALIC : 0); 82 int fontSize = size.getItemAt(size.getSelectedIndex()); 83 Font font = new Font(fontFace, fontStyle, fontSize); 84 sample.setFont(font); 85 sample.repaint(); 86 } 87 }
测试程序11
l 在elipse IDE中调试运行教材539页程序12-13、12-14,结合运行结果理解程序;
l 掌握定制布局管理器的用法。
l 记录示例代码阅读理解中存在的问题与疑惑。
1 package Forth; 2 3 import java.awt.*; 4 5 import javax.swing.*; 6 7 /** 8 * @version 1.33 2015-06-12 9 * @author Cay Horstmann 10 */ 11 public class CircleLayoutTest 12 { 13 public static void main(String[] args) 14 { 15 EventQueue.invokeLater(() -> { 16 JFrame frame = new CircleLayoutFrame(); 17 frame.setTitle("CircleLayoutTest"); 18 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 19 frame.setVisible(true); 20 }); 21 } 22 }
1 package Forth; 2 3 import javax.swing.*; 4 5 /** 6 * A frame that shows buttons arranged along a circle. 7 */ 8 public class CircleLayoutFrame extends JFrame 9 { 10 public CircleLayoutFrame() 11 { 12 setLayout(new CircleLayout()); 13 add(new JButton("Yellow")); 14 add(new JButton("Blue")); 15 add(new JButton("Red")); 16 add(new JButton("Green")); 17 add(new JButton("Orange")); 18 add(new JButton("Fuchsia")); 19 add(new JButton("Indigo")); 20 pack(); 21 } 22 }
1 package Forth; 2 3 import java.awt.*; 4 5 /** 6 * A layout manager that lays out components along a circle. 7 */ 8 public class CircleLayout implements LayoutManager 9 { 10 private int minWidth = 0; 11 private int minHeight = 0; 12 private int preferredWidth = 0; 13 private int preferredHeight = 0; 14 private boolean sizesSet = false; 15 private int maxComponentWidth = 0; 16 private int maxComponentHeight = 0; 17 18 public void addLayoutComponent(String name, Component comp) 19 { 20 } 21 22 public void removeLayoutComponent(Component comp) 23 { 24 } 25 26 public void setSizes(Container parent) 27 { 28 if (sizesSet) return; 29 int n = parent.getComponentCount(); 30 31 preferredWidth = 0; 32 preferredHeight = 0; 33 minWidth = 0; 34 minHeight = 0; 35 maxComponentWidth = 0; 36 maxComponentHeight = 0; 37 38 // 计算最大组件宽度和高度 39 // 并根据组件大小之和设置首选大小。 40 for (int i = 0; i < n; i++) 41 { 42 Component c = parent.getComponent(i); 43 if (c.isVisible()) 44 { 45 Dimension d = c.getPreferredSize(); 46 maxComponentWidth = Math.max(maxComponentWidth, d.width); 47 maxComponentHeight = Math.max(maxComponentHeight, d.height); 48 preferredWidth += d.width; 49 preferredHeight += d.height; 50 } 51 } 52 minWidth = preferredWidth / 2; 53 minHeight = preferredHeight / 2; 54 sizesSet = true; 55 } 56 57 public Dimension preferredLayoutSize(Container parent) 58 { 59 setSizes(parent); 60 Insets insets = parent.getInsets(); 61 int width = preferredWidth + insets.left + insets.right; 62 int height = preferredHeight + insets.top + insets.bottom; 63 return new Dimension(width, height); 64 } 65 66 public Dimension minimumLayoutSize(Container parent) 67 { 68 setSizes(parent); 69 Insets insets = parent.getInsets(); 70 int width = minWidth + insets.left + insets.right; 71 int height = minHeight + insets.top + insets.bottom; 72 return new Dimension(width, height); 73 } 74 75 public void layoutContainer(Container parent) 76 { 77 setSizes(parent); 78 79 // 计算圆的中心 80 81 Insets insets = parent.getInsets(); 82 int containerWidth = parent.getSize().width - insets.left - insets.right; 83 int containerHeight = parent.getSize().height - insets.top - insets.bottom; 84 85 int xcenter = insets.left + containerWidth / 2; 86 int ycenter = insets.top + containerHeight / 2; 87 88 // 计算圆的半径 89 90 int xradius = (containerWidth - maxComponentWidth) / 2; 91 int yradius = (containerHeight - maxComponentHeight) / 2; 92 int radius = Math.min(xradius, yradius); 93 94 // 沿圆圈展开组件 95 96 int n = parent.getComponentCount(); 97 for (int i = 0; i < n; i++) 98 { 99 Component c = parent.getComponent(i); 100 if (c.isVisible()) 101 { 102 double angle = 2 * Math.PI * i / n; 103 104 // 组件的中心点 105 int x = xcenter + (int) (Math.cos(angle) * radius); 106 int y = ycenter + (int) (Math.sin(angle) * radius); 107 108 // 移动组件至(x,y) 109 // 它的大小时适合的大小; 110 Dimension d = c.getPreferredSize(); 111 c.setBounds(x - d.width / 2, y - d.height / 2, d.width, d.height); 112 } 113 } 114 } 115 }
测试程序13
l 在elipse IDE中调试运行教材552页程序12-17、12-18,结合运行结果理解程序;
l 掌握对话框的创建方法;
l 记录示例代码阅读理解中存在的问题与疑惑。
1 package First; 2 3 import java.awt.*; 4 5 import javax.swing.*; 6 7 /** 8 * @version 1.34 2012-06-12 9 * @author Cay Horstmann 10 */ 11 public class DialogTest 12 { 13 public static void main(String[] args) 14 { 15 EventQueue.invokeLater(() -> { 16 JFrame frame = new DialogFrame(); 17 frame.setTitle("DialogTest"); 18 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 19 frame.setVisible(true); 20 }); 21 } 22 }
1 package First; 2 3 import javax.swing.JFrame; 4 5 import javax.swing.JMenu; 6 import javax.swing.JMenuBar; 7 import javax.swing.JMenuItem; 8 9 /** 10 * A frame with a menu whose File->About action shows a dialog. 11 */ 12 public class DialogFrame extends JFrame 13 { 14 private static final int DEFAULT_WIDTH = 300; 15 private static final int DEFAULT_HEIGHT = 200; 16 private AboutDialog dialog; 17 18 public DialogFrame() 19 { 20 setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT); 21 22 // 构造一个文件菜单。 23 24 JMenuBar menuBar = new JMenuBar(); 25 setJMenuBar(menuBar); 26 JMenu fileMenu = new JMenu("File"); 27 menuBar.add(fileMenu); 28 29 // 添加和退出菜单项。 30 31 // 有关项目显示有关对话框. 32 33 JMenuItem aboutItem = new JMenuItem("About"); 34 aboutItem.addActionListener(event -> { 35 if (dialog == null) // first time 36 dialog = new AboutDialog(DialogFrame.this); 37 dialog.setVisible(true); // 弹出对话框 38 }); 39 fileMenu.add(aboutItem); 40 41 //退出项退出程序。 42 43 JMenuItem exitItem = new JMenuItem("Exit"); 44 exitItem.addActionListener(event -> System.exit(0)); 45 fileMenu.add(exitItem); 46 } 47 }
1 package First; 2 3 import java.awt.BorderLayout; 4 5 6 import javax.swing.JButton; 7 import javax.swing.JDialog; 8 import javax.swing.JFrame; 9 import javax.swing.JLabel; 10 import javax.swing.JPanel; 11 12 /** 13 * A sample modal dialog that displays a message and waits for the user to click 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 // 添加HTML标签到中心 22 23 add( 24 new JLabel( 25 "Core Java
By Cay Horstmann"), 26 BorderLayout.CENTER); 27 28 // OK按钮关闭对话框 29 30 JButton ok = new JButton("OK"); 31 ok.addActionListener(event -> setVisible(false)); 32 33 // 添加OK按钮到南部边框 34 35 JPanel panel = new JPanel(); 36 panel.add(ok); 37 add(panel, BorderLayout.SOUTH); 38 39 pack(); 40 } 41 }
测试程序14
l 在elipse IDE中调试运行教材556页程序12-19、12-20,结合运行结果理解程序;
l 掌握对话框的数据交换用法;
l 记录示例代码阅读理解中存在的问题与疑惑。
1 package First; 2 3 import java.awt.*; 4 5 import javax.swing.*; 6 7 /** 8 * @version 1.34 2015-06-12 9 * @author Cay Horstmann 10 */ 11 public class DataExchangeTest 12 { 13 public static void main(String[] args) 14 { 15 EventQueue.invokeLater(() -> { 16 JFrame frame = new DataExchangeFrame(); 17 frame.setTitle("DataExchangeTest"); 18 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 19 frame.setVisible(true); 20 }); 21 } 22 }
1 package First; 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 JMenuItem connectItem = new JMenuItem("Connect"); 28 connectItem.addActionListener(new ConnectAction()); 29 fileMenu.add(connectItem); 30 31 // 退出项退出程序 32 33 JMenuItem exitItem = new JMenuItem("Exit"); 34 exitItem.addActionListener(event -> System.exit(0)); 35 fileMenu.add(exitItem); 36 37 textArea = new JTextArea(TEXT_ROWS, TEXT_COLUMNS); 38 add(new JScrollPane(textArea), BorderLayout.CENTER); 39 pack(); 40 } 41 42 /** 43 * The Connect action pops up the password dialog. 44 */ 45 private class ConnectAction implements ActionListener 46 { 47 public void actionPerformed(ActionEvent event) 48 { 49 // 如果第一次,构造对话框 50 51 if (dialog == null) dialog = new PasswordChooser(); 52 53 //设定预设值 54 dialog.setUser(new User("yourname", null)); 55 56 // 弹出对话框 57 if (dialog.showDialog(DataExchangeFrame.this, "Connect")) 58 { 59 // 如果接受,则检索用户输入 60 User u = dialog.getUser(); 61 textArea.append("user name = " + u.getName() + ", password = " 62 + (new String(u.getPassword())) + "\n"); 63 } 64 } 65 } 66 }
1 package First; 2 3 import java.awt.BorderLayout; 4 5 import java.awt.Component; 6 import java.awt.Frame; 7 import java.awt.GridLayout; 8 9 import javax.swing.JButton; 10 import javax.swing.JDialog; 11 import javax.swing.JLabel; 12 import javax.swing.JPanel; 13 import javax.swing.JPasswordField; 14 import javax.swing.JTextField; 15 import javax.swing.SwingUtilities; 16 17 /** 18 * A password chooser that is shown inside a dialog 19 */ 20 public class PasswordChooser extends JPanel 21 { 22 private JTextField username; 23 private JPasswordField password; 24 private JButton okButton; 25 private boolean ok; 26 private JDialog dialog; 27 28 public PasswordChooser() 29 { 30 setLayout(new BorderLayout()); 31 32 // 构造带有用户名和密码字段的面板 33 34 JPanel panel = new JPanel(); 35 panel.setLayout(new GridLayout(2, 2)); 36 panel.add(new JLabel("User name:")); 37 panel.add(username = new JTextField("")); 38 panel.add(new JLabel("Password:")); 39 panel.add(password = new JPasswordField("")); 40 add(panel, BorderLayout.CENTER); 41 42 // 创建“确定”并取消终止对话框的按钮 43 44 okButton = new JButton("Ok"); 45 okButton.addActionListener(event -> { 46 ok = true; 47 dialog.setVisible(false); 48 }); 49 50 JButton cancelButton = new JButton("Cancel"); 51 cancelButton.addActionListener(event -> dialog.setVisible(false)); 52 53 // add buttons to southern border 54 55 JPanel buttonPanel = new JPanel(); 56 buttonPanel.add(okButton); 57 buttonPanel.add(cancelButton); 58 add(buttonPanel, BorderLayout.SOUTH); 59 } 60 61 /** 62 * Sets the dialog defaults. 63 * @param u the default user information 64 */ 65 public void setUser(User u) 66 { 67 username.setText(u.getName()); 68 } 69 70 /** 71 * Gets the dialog entries. 72 * @return a User object whose state represents the dialog entries 73 */ 74 public User getUser() 75 { 76 return new User(username.getText(), password.getPassword()); 77 } 78 79 /** 80 * Show the chooser panel in a dialog 81 * @param parent a component in the owner frame or null 82 * @param title the dialog window title 83 */ 84 public boolean showDialog(Component parent, String title) 85 { 86 ok = false; 87 88 // locate the owner frame 89 90 Frame owner = null; 91 if (parent instanceof Frame) 92 owner = (Frame) parent; 93 else 94 owner = (Frame) SwingUtilities.getAncestorOfClass(Frame.class, parent); 95 96 // if first time, or if owner has changed, make new dialog 97 98 if (dialog == null || dialog.getOwner() != owner) 99 { 100 dialog = new JDialog(owner, true); 101 dialog.add(this); 102 dialog.getRootPane().setDefaultButton(okButton); 103 dialog.pack(); 104 } 105 106 // set title and show dialog 107 108 dialog.setTitle(title); 109 dialog.setVisible(true); 110 return ok; 111 } 112 }
测试程序15
l 在elipse IDE中调试运行教材556页程序12-21、12-2212-23,结合程序运行结果理解程序;
l 掌握文件对话框的用法;
l 记录示例代码阅读理解中存在的问题与疑
1 package Third; 2 3 import java.awt.*; 4 5 import javax.swing.*; 6 7 /** 8 * @version 1.25 2015-06-12 9 * @author Cay Horstmann 10 */ 11 public class FileChooserTest 12 { 13 public static void main(String[] args) 14 { 15 EventQueue.invokeLater(() -> { 16 JFrame frame = new ImageViewerFrame(); 17 frame.setTitle("FileChooserTest"); 18 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 19 frame.setVisible(true); 20 }); 21 } 22 }
1 package Third; 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 Third; 2 3 import java.awt.*; 4 5 import java.io.*; 6 7 import javax.swing.*; 8 9 /** 10 * A file chooser accessory that previews images. 11 */ 12 public class ImagePreviewer extends JLabel 13 { 14 /** 15 * Constructs an ImagePreviewer. 16 * @param chooser the file chooser whose property changes trigger an image 17 * change in this previewer 18 */ 19 public ImagePreviewer(JFileChooser chooser) 20 { 21 setPreferredSize(new Dimension(100, 100)); 22 setBorder(BorderFactory.createEtchedBorder()); 23 24 chooser.addPropertyChangeListener(event -> { 25 if (event.getPropertyName() == JFileChooser.SELECTED_FILE_CHANGED_PROPERTY) 26 { 27 // 用户选择了一个新文件 28 File f = (File) event.getNewValue(); 29 if (f == null) 30 { 31 setIcon(null); 32 return; 33 } 34 35 // 将影像读取成图示 36 ImageIcon icon = new ImageIcon(f.getPath()); 37 38 // 如果图标太大,无法安装,请缩放 39 if (icon.getIconWidth() > getWidth()) 40 icon = new ImageIcon(icon.getImage().getScaledInstance( 41 getWidth(), -1, Image.SCALE_DEFAULT)); 42 43 setIcon(icon); 44 } 45 }); 46 } 47 }
1 package Third; 2 3 import java.io.*; 4 5 6 import javax.swing.*; 7 import javax.swing.filechooser.*; 8 import javax.swing.filechooser.FileFilter; 9 10 /** 11 * A frame that has a menu for loading an image and a display area for the 12 * loaded image. 13 */ 14 public class ImageViewerFrame extends JFrame 15 { 16 private static final int DEFAULT_WIDTH = 300; 17 private static final int DEFAULT_HEIGHT = 400; 18 private JLabel label; 19 private JFileChooser chooser; 20 21 public ImageViewerFrame() 22 { 23 setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT); 24 25 // set up menu bar 26 JMenuBar menuBar = new JMenuBar(); 27 setJMenuBar(menuBar); 28 29 JMenu menu = new JMenu("File"); 30 menuBar.add(menu); 31 32 JMenuItem openItem = new JMenuItem("Open"); 33 menu.add(openItem); 34 openItem.addActionListener(event -> { 35 chooser.setCurrentDirectory(new File(".")); 36 37 // show file chooser dialog 38 int result = chooser.showOpenDialog(ImageViewerFrame.this); 39 40 // if image file accepted, set it as icon of the label 41 if (result == JFileChooser.APPROVE_OPTION) 42 { 43 String name = chooser.getSelectedFile().getPath(); 44 label.setIcon(new ImageIcon(name)); 45 pack(); 46 } 47 }); 48 49 JMenuItem exitItem = new JMenuItem("Exit"); 50 menu.add(exitItem); 51 exitItem.addActionListener(event -> System.exit(0)); 52 53 // 使用标签显示影像 54 label = new JLabel(); 55 add(label); 56 57 // 设置文件选择器 58 chooser = new JFileChooser(); 59 60 // accept all image files ending with接受所有以之结尾的影像档案jpg, .jpeg, .gif图形交换格式 . 61 FileFilter filter = new FileNameExtensionFilter( 62 "Image files", "jpg", "jpeg", "gif"); 63 chooser.setFileFilter(filter); 64 65 chooser.setAccessory(new ImagePreviewer(chooser)); 66 67 chooser.setFileView(new FileIconView(filter, new ImageIcon("121.jpg"))); 68 } 69 }
测试程序16
l 在elipse IDE中调试运行教材570页程序12-24,结合运行结果理解程序;
l 了解颜色选择器的用法。
l 记录示例代码阅读理解中存在的问题与疑惑。
1 package Third; 2 3 import java.awt.*; 4 5 import javax.swing.*; 6 7 /** 8 * @version 1.04 2015-06-12 9 * @author Cay Horstmann 10 */ 11 public class ColorChooserTest 12 { 13 public static void main(String[] args) 14 { 15 EventQueue.invokeLater(() -> { 16 JFrame frame = new ColorChooserFrame(); 17 frame.setTitle("ColorChooserTest"); 18 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 19 frame.setVisible(true); 20 }); 21 } 22 }
1 package Third; 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 Third; 2 import java.awt.Color; 3 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 /* 非模态 */, chooser, 61 event -> setBackground(chooser.getColor()), 62 null /* 没有取消按钮侦听器 */); 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 /* 非模态 */); 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 }
实验2:组内讨论反思本组负责程序,理解程序总体结构,梳理程序GUI设计中应用的相关组件,整理相关组件的API,对程序中组件应用的相关代码添加注释。
测试程序12: 在elipse IDE中调试运行教材544页程序12-15、12-16,结合运行结果理解程序;l 掌握选项对话框的用法;l 记录示例代码阅读理解中存在的问题与疑惑。
1 package optionDialog; 2 3 import java.awt.*; 4 5 import javax.swing.*; 6 7 /** 8 * @version 1.34 2015-06-12 9 * @author Cay Horstmann 10 */ 11 public class OptionDialogTest 12 { 13 public static void main(String[] args) 14 { 15 EventQueue.invokeLater(() -> { 16 JFrame frame = new OptionDialogFrame(); 17 frame.setTitle("OptionDialogTest"); 18 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 19 frame.setVisible(true); 20 }); 21 } 22 }
1 package optionDialog; 2 import javax.swing.*; 3 4 /** 5 * A panel with radio buttons inside a titled border. 6 */ 7 public class ButtonPanel extends JPanel 8 { 9 private ButtonGroup group; 10 11 /** 12 * Constructs a button panel. 13 * @param title the title shown in the border 14 * @param options an array of radio button labels 15 */ 16 public ButtonPanel(String title, String... options)//该函数可以接收完第一个title后,还可以接受多个String类型的参数. 17 { 18 setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), title));//设置边框; 19 setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));//this表示的是BoxLayout t = new BoxLayout(this,BoxLayout.Y_AXIS)) 这个当前对象(即 t); 20 group = new ButtonGroup(); 21 22 // 为每个选项做一个单选按钮 23 for (String option : options) 24 { 25 JRadioButton b = new JRadioButton(option); 26 b.setActionCommand(option); 27 add(b); 28 group.add(b); 29 b.setSelected(option == options[0]); 30 } 31 } 32 33 /** 34 * Gets the currently selected option. 35 * @return the label of the currently selected radio button. 36 */ 37 public String getSelection() 38 { 39 return group.getSelection().getActionCommand(); 40 } 41 }
1 package optionDialog; 2 3 import java.awt.*; 4 5 import java.awt.event.*; 6 import java.awt.geom.*; 7 import java.util.*; 8 import javax.swing.*; 9 10 /** 11 * A frame that contains settings for selecting various option dialogs. 12 */ 13 public class OptionDialogFrame extends JFrame 14 { 15 //设置私有属性; 16 private ButtonPanel typePanel; 17 private ButtonPanel messagePanel; 18 private ButtonPanel messageTypePanel; 19 private ButtonPanel optionTypePanel; 20 private ButtonPanel optionsPanel; 21 private ButtonPanel inputPanel; 22 private String messageString = "Message"; 23 private Icon messageIcon = new ImageIcon("blue-ball.gif"); 24 private Object messageObject = new Date(); 25 private Component messageComponent = new SampleComponent(); 26 27 public OptionDialogFrame() 28 { 29 JPanel gridPanel = new JPanel(); 30 gridPanel.setLayout(new GridLayout(2, 3));////创建2行3列的网格布局; 31 //创建各个按钮; 32 typePanel = new ButtonPanel("Type", "Message", "Confirm", "Option", "Input"); 33 messageTypePanel = new ButtonPanel("Message Type", "ERROR_MESSAGE", "INFORMATION_MESSAGE", 34 "WARNING_MESSAGE", "QUESTION_MESSAGE", "PLAIN_MESSAGE"); 35 messagePanel = new ButtonPanel("Message", "String", "Icon", "Component", "Other", 36 "Object[]"); 37 optionTypePanel = new ButtonPanel("Confirm", "DEFAULT_OPTION", "YES_NO_OPTION", 38 "YES_NO_CANCEL_OPTION", "OK_CANCEL_OPTION"); 39 optionsPanel = new ButtonPanel("Option", "String[]", "Icon[]", "Object[]"); 40 inputPanel = new ButtonPanel("Input", "Text field", "Combo box"); 41 //将按钮添加到网格面板; 42 gridPanel.add(typePanel); 43 gridPanel.add(messageTypePanel); 44 gridPanel.add(messagePanel); 45 gridPanel.add(optionTypePanel); 46 gridPanel.add(optionsPanel); 47 gridPanel.add(inputPanel); 48 49 //添加带有"Show"按钮的面板 50 51 JPanel showPanel = new JPanel(); 52 JButton showButton = new JButton("Show"); 53 showButton.addActionListener(new ShowAction());//关联监听器; 54 showPanel.add(showButton);//将按钮添加到面板; 55 56 add(gridPanel, BorderLayout.CENTER);//设置位置; 57 add(showPanel, BorderLayout.SOUTH); 58 pack(); 59 } 60 61 /** 62 * Gets the currently selected message. 63 * @return a string, icon, component, or object array, depending on the Message panel selection 64 */ 65 public Object getMessage() 66 { 67 String s = messagePanel.getSelection(); 68 if (s.equals("String")) return messageString; 69 else if (s.equals("Icon")) return messageIcon; 70 else if (s.equals("Component")) return messageComponent; 71 else if (s.equals("Object[]")) return new Object[] { messageString, messageIcon, 72 messageComponent, messageObject }; 73 else if (s.equals("Other")) return messageObject; 74 else return null; 75 } 76 77 /** 78 * Gets the currently selected options. 79 * @return an array of strings, icons, or objects, depending on the Option panel selection 80 */ 81 public Object[] getOptions() 82 { 83 String s = optionsPanel.getSelection(); 84 if (s.equals("String[]")) return new String[] { "Yellow", "Blue", "Red" }; 85 else if (s.equals("Icon[]")) return new Icon[] { new ImageIcon("yellow-ball.gif"), 86 new ImageIcon("blue-ball.gif"), new ImageIcon("red-ball.gif") }; 87 else if (s.equals("Object[]")) return new Object[] { messageString, messageIcon, 88 messageComponent, messageObject }; 89 else return null; 90 } 91 92 /** 93 * Gets the selected message or option type 94 * @param panel the Message Type or Confirm panel 95 * @return the selected XXX_MESSAGE or XXX_OPTION constant from the JOptionPane class 96 */ 97 public int getType(ButtonPanel panel) 98 { 99 String s = panel.getSelection(); 100 try 101 { 102 return JOptionPane.class.getField(s).getInt(null); 103 } 104 catch (Exception e) 105 { 106 return -1; 107 } 108 } 109 110 /** 111 * The action listener for the Show button shows a Confirm, Input, Message, or Option dialog 112 * depending on the Type panel selection. 113 */ 114 private class ShowAction implements ActionListener 115 { 116 public void actionPerformed(ActionEvent event) 117 { 118 if (typePanel.getSelection().equals("Confirm")) JOptionPane.showConfirmDialog( 119 OptionDialogFrame.this, getMessage(), "Title", getType(optionTypePanel), 120 getType(messageTypePanel)); 121 else if (typePanel.getSelection().equals("Input")) 122 { 123 if (inputPanel.getSelection().equals("Text field")) JOptionPane.showInputDialog( 124 OptionDialogFrame.this, getMessage(), "Title", getType(messageTypePanel)); 125 else JOptionPane.showInputDialog(OptionDialogFrame.this, getMessage(), "Title", 126 getType(messageTypePanel), null, new String[] { "Yellow", "Blue", "Red" }, 127 "Blue"); 128 } 129 else if (typePanel.getSelection().equals("Message")) JOptionPane.showMessageDialog( 130 OptionDialogFrame.this, getMessage(), "Title", getType(messageTypePanel)); 131 else if (typePanel.getSelection().equals("Option")) JOptionPane.showOptionDialog( 132 OptionDialogFrame.this, getMessage(), "Title", getType(optionTypePanel), 133 getType(messageTypePanel), null, getOptions(), getOptions()[0]); 134 } 135 } 136 } 137 138 /** 139 * A component with a painted surface 140 */ 141 142 class SampleComponent extends JComponent 143 { 144 public void paintComponent(Graphics g) 145 { 146 Graphics2D g2 = (Graphics2D) g; 147 Rectangle2D rect = new Rectangle2D.Double(0, 0, getWidth() - 1, getHeight() - 1); 148 g2.setPaint(Color.YELLOW); 149 g2.fill(rect); 150 g2.setPaint(Color.BLUE); 151 g2.draw(rect); 152 } 153 154 public Dimension getPreferredSize() 155 { 156 return new Dimension(10, 10); 157 } 158 }
利用JOptionPane类中的各个static方法来生成各种标准的对话框,实现显示出信息、提出问题、警告、用户输入参数等功能。这些对话框都是模式对话框。
ConfirmDialog --- 确认对话框,提出问题,然后由用户自己来确认(按"Yes"或"No"按钮)
InputDialog --- 提示输入文本
MessageDialog --- 显示信息
OptionDialog -- 组合其它三个对话框类型。
这四个对话框可以采用showXXXDialog()来显示,如showConfirmDialog()显示确认对话框、showInputDialog()显示输入文本对话框、showMessageDialog()显示信息对话框、showOptionDialog()显示选择性的对话框。它们所使用的参数说明如下:
① ParentComponent:指示对话框的父窗口对象,一般为当前窗口。也可以为null即采用缺省的Frame作为父窗口,此时对话框将设置在屏幕的正中。
② message:指示要在对话框内显示的描述性的文字
③ String title:标题条文字串。
④ Component:在对话框内要显示的组件(如按钮)
⑤ Icon:在对话框内要显示的图标
⑥ messageType:一般可以为如下的值ERROR_MESSAGE、INFORMATION_MESSAGE、WARNING_MESSAGE、QUESTION_MESSAGE、PLAIN_MESSAGE、
⑦ optionType:它决定在对话框的底部所要显示的按钮选项。一般可以为DEFAULT_OPTION、YES_NO_OPTION、YES_NO_CANCEL_OPTION、OK_CANCEL_OPTION。
使用实例:
(1)显示MessageDialog
JOptionPane.showMessageDialog(null, "在对话框内显示的描述性的文字", "标题条文字串", JOptionPane.ERROR_MESSAGE);
(2)显示ConfirmDialog
JOptionPane.showConfirmDialog(null, "choose one", "choose one", JOptionPane.YES_NO_OPTION);
(3)显示OptionDialog:该种对话框可以由用户自己来设置各个按钮的个数并返回用户点击各个按钮的序号(从0开始计数)
Object[] options = {"确定","取消","帮助"};
int response=JOptionPane.showOptionDialog(this, "这是个选项对话框,用户可以选择自己的按钮的个数", "选项对话框标题",JOptionPane.YES_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options[0]);
if(response==0)
{ this.setTitle("您按下了第OK按钮 ");
}
else if(response==1)
{ this.setTitle("您按下了第Cancel按钮 ");
}
else if(response==2)
{ this.setTitle("您按下了第Help按钮 ");
}
(4)显示InputDialog 以便让用户进行输入
String inputValue = JOptionPane.showInputDialog("Please input a value");
(5)显示InputDialog 以便让用户进行选择地输入
Object[] possibleValues = { "First", "Second", "Third" }; //用户的选择项目
Object selectedValue = JOptionPane.showInputDialog(null, "Choose one", "Input",JOptionPane.INFORMATION_MESSAGE, null, possibleValues, possibleValues[0]);
setTitle("您按下了"+(String)selectedValue+"项目");
实验3:组间协同学习:在本班课程QQ群内,各位同学对实验1中存在的问题进行提问,提问时注明实验1中的测试程序编号,负责对应程序的小组需及时对群内提问进行回答。
第三部分:总结
本周继续学习Swing用户界面设计!