项目 | 内容 |
这个作业属于哪个课程 | https://www.cnblogs.com/nwnu-daizh/ |
这个作业的要求在哪里 | https://www.cnblogs.com/nwnu-daizh/p/11953993.html |
作业学习目标 | (1)掌握GUI布局管理器用法; (2)掌握Java Swing文本输入组件用途及常用API; (3)掌握Java Swing选择输入组件用途及常用API。 |
第一部分:总结第十二章本周理论知识
1.Swing和MVC设计模式
a.设计模式(Design pattern)是设计者一种流行的思考设计问题的方法,是一套被反复使用,多数人知晓的,经过分类编目的,代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。
b.每一个模式描述了一个不断重复发生的设计问题,以及该问题的核心解决方案
c.模型-视图-控制器设计模式(Model –ViewController )是Java EE平台下创建 Web 应用程序的重要设计模式。
MVC设计模式
– Model(模型):是程序中用于处理程序数据逻辑的部分,通常模型负责在数据库中存取数据。
– View(视图):是程序中处理数据显示的部分,通常视图依据模型存取的数据创建。
– Controller(控制器):是程序中处理用户交互的部分。通常控制器负责从视图读取数据,控制用户输入,并向模型发送数据。
2.布局管理器
1.为了设计美观合理的GUI界面,需要考虑组件在容器组件中的位置和相互关系,就需要学习布局设计的知识。
2.在java的GUI应用程序界面设计中,布局控制通过为容器设置布局管理器来实现的
5种布局管理器
(1)FlowLayout: 流布局(Applet和Panel的默认布局管理器)
JPanel对象的默认布局管理器为FlowLayout,组件加入JPanel中总是处于中央,一行可以排列多个组件,如果一行的空间容纳不下所有的组件则换行。当顶层窗口缩放时,JPanel中组件的大小不会随之缩放。
(2)BorderLayout:边框布局( Window、Frame和Dialog的默认布局管理器)
是JFrame的内容窗格的默认布局管理器,可以选择将空间放在内容窗格的东、南、西、北、中。 且将组件加入其中时,组件会充满其对应的整个区域,如果在这个方位再加入一个组件,会覆盖原本存在的组件。当顶层窗口缩放时,东南西北的组件不会随之变化,中部的组件会等比例变化。
如果要在某方法并排加入几个组件,则可以先将组件加入JPanel中,再放入边框布局管理器。
BorderLayout的常量定义为字符串
frame.add(new JButton("Yes"),BorderLayout.SOUTH);
(3)GridLayout: 网格布局
①GridLayout():生成一个单行单列的网格布局
②GridLayout(int rows,int cols):生成一个设定行数和列数的网格布局
③GridLayout(int rows,int columns,int hgap,int vgap):可设置组件之间的水平和垂直间隔
(4)GridBagLayout: 网格组布局
(5)CardLayout :卡片布局 通过setLayout( )方法为容器设置新的布局。
容器组件名.setLayout( 布局类对象名)。
3.文本输入
1)扩展于JTextComponent的JTextField和JTextArea
JTextField和JTextArea都用于文本输入,其中JTextField接收单行文本的输入,而JTextArea可接收多行文本的输入。
列数为文本域的宽度,如果希望文本域最多能输入N个字符,则将宽度设置为N
JTextField text = new JTextField("Input Here",20);
第二个构造函数可以指定文本区显示的行数和列数。如果需要设置滚动条,则需要将文本区加入JScrollPane中,再讲JScrollPane插入容器。
JTextArea area = new TextArea(4,10);
JScrollPane pane = new JScrollPane(area);
panel.add(pane);
2)扩展于JTextField的JPasswordField
接受单行输入,输入字符被特殊字符掩盖
3)JLabel
没有任何修饰,不能响应用户输入,只是容纳文本的组件。可以设置标签的显示文字、图标以及对齐方式
其中对齐方式是SwingConstants里的常量,如LEFT/RIGHT/CENTER等
JLabel label = new JLabel("User Name:",SwingConstants.RIGHT);
4.选择组件
1)JCheckBox
复选框自动带有标签和图标,在构造时可以提供,当用户选中复选框时会触发动作事件。
JCheckBox box = new JCheckBox("Bold");
自带标签和图标。单选钮只能多选其一,要打到这种效果需要把所有的单选钮加入ButtonGroup的对象里,从而使得新按钮被按下时,取消前一个选中的按钮的状态。ButtonGroup直接扩展于Object类,所以单选钮需加入容器中进行布局,ButtonGroup和容器(如JPanel)是相互独立的。 选中时触发动作事件。
2)边框(Border)
任何继承自JComponent的组件都可以使用边框(void setBorder(Border b))。常用的方法是将组件放入容器中,然后容器使用边框。是通过调用BorderFactory的静态方法构建边框。 同时可以为边框设置标题:
Border etch = BorderFactory.createEtchedBorder();
Border title = BorderFactory.createTitleBorder(etch,"Title");
panel.setBorder(title);
3)组合框
JComboBox< T>是泛型类,构建时需注意。
组合框不仅有下拉选择的功能,还具有文本框编辑的功能。
获得当前选中内容:
combo.getItemAt(combo.getSelectedIndex());
//Object getItemAt(int index)
当用户从组合框中选中一个选项时,组合框就会产生一个动作事件。
4)滑动条(JSlider)
滑动条在构造时默认是横向,如果需要纵向滑动条:
JSlider s = new JSlider(SwingConstants.VERTICAL,min,max,initialValue);
当滑动条滑动时,会触发ChangeEvent,需要调用addChangeListener()并且安装一个实现了ChangeListener接口的对象。这个接口只有一个StateChanged方法
如果需要显示滑动条的刻度,则setPaintTicks(true);
如果要将滑动条强制对准刻度,则setSnapToTicks(true);
如果要为滑动条设置标签,则需要先构建一个Hashtable< Integer,Component>,将数字与标签对应起来,再调用setLabelTable(Dictionary label);
5.菜单
分为JMenuBar/JMenu/JMenuItem,当选择菜单项时会触发一个动作事件,需要注册监听器监听
6.对话框
对话框是一种大小不能变化、不能有菜单的容器窗口; 对话框不能作为一个应用程序的主框架,而必须包含在其他的容器中。
对话框分为模式对话框和无模对话框,模式对话框就是未处理此对话框之前不允许与其他窗口交互。
文件对话框(JFileChooser类)
颜色对话框(JColorChooser类)
第二部分:实验部分
实验1: 导入第12章示例程序,测试程序并进行组内讨论。
测试程序1
1) 在elipse IDE中运行教材479页程序12-1,结合运行结果理解程序;
2)掌握布局管理器的用法;
3)理解GUI界面中事件处理技术的用途。
4) 在布局管理应用代码处添加注释;
程序代码如下:
package calculator; import java.awt.*; import javax.swing.*; /** * @version 1.35 2018-04-10 * @author Cay Horstmann */ public class Calculator { public static void main(String[] args) { EventQueue.invokeLater(() -> { var frame = new CalculatorFrame(); frame.setTitle("Calculator"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); }); } }
package calculator; import javax.swing.*; /** * A frame with a calculator panel. */ public class CalculatorFrame extends JFrame { public CalculatorFrame() { add(new CalculatorPanel()); pack(); } }
package calculator; import java.awt.*; import java.awt.event.*; import javax.swing.*; /** * 带有计算器按钮和结果显示的面板。 */ public class CalculatorPanel extends JPanel { private JButton display; private JPanel panel; private double result; private String lastCommand; private boolean start; public CalculatorPanel() { //为容器设置布局管理器,为边框布局管理器 setLayout(new BorderLayout()); result = 0; lastCommand = "="; start = true; // 添加页面显示 display = new JButton("0"); display.setEnabled(false); add(display, BorderLayout.NORTH); var insert = new InsertAction(); var command = new CommandAction(); // 在4*4的网格中添加按钮 panel = new JPanel(); panel.setLayout(new GridLayout(4, 4)); //网格布局管理器:4行4列 addButton("7", insert); addButton("8", insert); addButton("9", insert); addButton("/", command); addButton("4", insert); addButton("5", insert); addButton("6", insert); addButton("*", command); addButton("1", insert); addButton("2", insert); addButton("3", insert); addButton("-", command); addButton("0", insert); addButton(".", insert); addButton("=", command); addButton("+", command); add(panel, BorderLayout.CENTER); //显示在窗口中心位置 } /** * 向中心面板添加一个按钮。 * @param label the button label * @param listener the button listener */ private void addButton(String label, ActionListener listener) { var button = new JButton(label); button.addActionListener(listener); panel.add(button); } /** * 此操作将按钮操作的字符串插入到显示文本的末尾。 */ private class InsertAction implements ActionListener { public void actionPerformed(ActionEvent event) { String input = event.getActionCommand(); if (start) { display.setText(""); start = false; } display.setText(display.getText() + input); } } /** * 该操作执行按钮操作的字符串表示的命令。 */ private class CommandAction implements ActionListener { public void actionPerformed(ActionEvent event) { String command = event.getActionCommand(); if (start) { if (command.equals("-")) { display.setText(command); start = false; } else lastCommand = command; } else { calculate(Double.parseDouble(display.getText())); lastCommand = command; start = true; } } } /** * 具体的计算 * @param x与先前结果累积的值。 */ public void calculate(double x) { if (lastCommand.equals("+")) result += x; else if (lastCommand.equals("-")) result -= x; else if (lastCommand.equals("*")) result *= x; else if (lastCommand.equals("/")) result /= x; else if (lastCommand.equals("=")) result = x; //将结果转化成字符串显示 display.setText("" + result); } }
运行结果:
测试程序2
1) 在elipse IDE中调试运行教材486页程序12-2,结合运行结果理解程序;
2)掌握文本组件的用法;
记录示例代码阅读理解中存在的问题与疑惑
程序代码如下:
package text; import java.awt.*; import javax.swing.*; /** * @version 1.42 2018-04-10 * @author Cay Horstmann */ public class TextComponentTest { public static void main(String[] args) { EventQueue.invokeLater(() -> { var frame = new TextComponentFrame(); frame.setTitle("TextComponentTest"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); }); } }
package text; import java.awt.BorderLayout; import java.awt.GridLayout; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JPasswordField; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.JTextField; import javax.swing.SwingConstants; /** * 带有输入文本框组件的框架。 */ public class TextComponentFrame extends JFrame { public static final int TEXTAREA_ROWS = 8; public static final int TEXTAREA_COLUMNS = 20; public TextComponentFrame() { var textField = new JTextField(); var passwordField = new JPasswordField(); var northPanel = new JPanel(); northPanel.setLayout(new GridLayout(2, 2)); //SwingConstants通常用于在屏幕上定位或定向组件的常量的集合 northPanel.add(new JLabel("User name: ", SwingConstants.RIGHT)); northPanel.add(textField); northPanel.add(new JLabel("Password: ", SwingConstants.RIGHT)); northPanel.add(passwordField); add(northPanel, BorderLayout.NORTH); //构造具有指定行数和列数的新的空 TextArea。 var textArea = new JTextArea(TEXTAREA_ROWS, TEXTAREA_COLUMNS); //创建一个显示指定组件内容的 JScrollPane对象,只要组件的内容超过视图大小就会显示水平和垂直滚动条。 var scrollPane = new JScrollPane(textArea); add(scrollPane, BorderLayout.CENTER); // add button to append text into the text area var southPanel = new JPanel(); var insertButton = new JButton("Insert"); southPanel.add(insertButton); //将给定文本追加到文档结尾。 insertButton.addActionListener(event -> textArea.append("User name: " + textField.getText() + " Password: " + new String(passwordField.getPassword()) + "\n")); add(southPanel, BorderLayout.SOUTH); pack(); } }
运行结果:
测试程序3
1) 在elipse IDE中调试运行教材489页程序12-3,结合运行结果理解程序;
2)掌握复选框组件的用法;
记录示例代码阅读理解中存在的问题与疑惑。
程序代码如下:
package checkBox; import java.awt.*; import javax.swing.*; /** * @version 1.35 2018-04-10 * @author Cay Horstmann */ public class CheckBoxTest { public static void main(String[] args) { EventQueue.invokeLater(() -> { var frame = new CheckBoxFrame(); frame.setTitle("CheckBoxTest"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); }); } }
运行结果:
测试程序4
1) 在elipse IDE中调试运行教材491页程序12-4,运行结果理解程序;
2)掌握单选按钮组件的用法;
3)记录示例代码阅读理解中存在的问题与疑惑。
程序代码如下:
package radioButton; import java.awt.*; import javax.swing.*; /** * @version 1.35 2018-04-10 * @author Cay Horstmann */ public class RadioButtonTest { public static void main(String[] args) { EventQueue.invokeLater(() -> { var frame = new RadioButtonFrame(); frame.setTitle("RadioButtonTest"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); }); } }
package radioButton; import java.awt.*; import java.awt.event.*; import javax.swing.*; /** * 带有示例文本标签和用于选择字体大小的单选按钮的框架。 */ public class RadioButtonFrame extends JFrame { private JPanel buttonPanel; private ButtonGroup group; private JLabel label; private static final int DEFAULT_SIZE = 36; public RadioButtonFrame() { // add the sample text label label = new JLabel("The quick brown fox jumps over the lazy dog."); label.setFont(new Font("Serif", Font.PLAIN, DEFAULT_SIZE)); add(label, BorderLayout.CENTER); // add the radio buttons buttonPanel = new JPanel(); group = new ButtonGroup(); addRadioButton("Small", 8); addRadioButton("Medium", 12); addRadioButton("Large", 18); addRadioButton("Extra large", 36); add(buttonPanel, BorderLayout.SOUTH); pack(); } /** * 添加一个单选按钮,用于设置示例文本的字体大小。 * @param 大小的规格要出现在按钮上的字符串 * @param 按钮设置的字体大小 */ public void addRadioButton(String name, int size) { boolean selected = size == DEFAULT_SIZE; var button = new JRadioButton(name, selected); group.add(button); buttonPanel.add(button); // 此监听器设置标签字体大小 ActionListener listener = event -> label.setFont(new Font("Serif", Font.PLAIN, size)); button.addActionListener(listener); } }
运行结果:
测试程序5
1) 在elipse IDE中调试运行教材494页程序12-5,结合运行结果理解程序;
2)掌握边框的用法;
记录示例代码阅读理解中存在的问题与疑惑。
程序代码如下:
package border; import java.awt.*; import javax.swing.*; /** * @version 1.35 2018-04-10 * @author Cay Horstmann */ public class BorderTest { public static void main(String[] args) { EventQueue.invokeLater(() -> { var frame = new BorderFrame(); frame.setTitle("BorderTest"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); }); } }
package border; import java.awt.*; import javax.swing.*; import javax.swing.border.*; /** * A frame with radio buttons to pick a border style. */ public class BorderFrame extends JFrame { private JPanel demoPanel; private JPanel buttonPanel; private ButtonGroup group; public BorderFrame() { demoPanel = new JPanel(); buttonPanel = new JPanel(); group = new ButtonGroup(); //设置不同的边框类型按钮,共六种(提供标准 Border 对象的工厂类) addRadioButton("Lowered bevel", BorderFactory.createLoweredBevelBorder()); addRadioButton("Raised bevel", BorderFactory.createRaisedBevelBorder()); addRadioButton("Etched", BorderFactory.createEtchedBorder()); addRadioButton("Line", BorderFactory.createLineBorder(Color.BLUE)); addRadioButton("Matte", BorderFactory.createMatteBorder(10, 10, 10, 10, Color.BLUE)); addRadioButton("Empty", BorderFactory.createEmptyBorder()); Border etched = BorderFactory.createEtchedBorder(); Border titled = BorderFactory.createTitledBorder(etched, "Border types"); buttonPanel.setBorder(titled); setLayout(new GridLayout(2, 1)); add(buttonPanel); add(demoPanel); pack(); } public void addRadioButton(String buttonName, Border b) { var button = new JRadioButton(buttonName); button.addActionListener(event -> demoPanel.setBorder(b)); group.add(button); buttonPanel.add(button); } }
运行结果: