Java语言程序设计--实验2:文本框、文本区和布局的设计
目的:
通过编写一个Java GUI应用程序,进一步熟悉Java GUI应用程序的结构和开发过程;熟悉窗口、组件的创建、布局管理器的使用以及事件处理机制。
题目:
根据教材关于Java GUI的介绍,编写一个具有如上基本布局的应用程序,要求当在上面的文本区中输入若干数后(输入的多个数据之间以逗号分隔),并点击按钮,就可以在下面的文本框中分别显示出输入数据的“和”以及“平均数”。
在完成上述要求的情况下,考虑改进该应用程序,从界面上去掉按钮,并且随着输入数据的变化,其“和”以及“平均数”能够立刻显示在下面的相应文本框中。
要求考虑异常处理,使得程序正常运行
1.使用按钮的情况代码(支持double数字):
package swingDemo;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.text.DecimalFormat;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
/**
* @author 陌意随影
TODO :使用swing实现求和和均值
*2020年10月29日 下午5:33:23
*/
public class SwingDemo extends JFrame {
private static final long serialVersionUID = 1L;
//内容面板
private JPanel contentPanel = null;
//输入的文本输入框
private JTextArea textArea = null;
//显示和值文本域
private JTextField sumTextField = null;
//显示均值文本域
private JTextField avgTextField = null;
//存放组件的面板
private JPanel mainPanel = null;
//计算按钮
private JButton calculateBtn = null;
@SuppressWarnings("javadoc")
public SwingDemo(int width,int height) {
//设置窗口的起始坐标以及宽和高
this.setBounds(200, 200, width, height);
//设置标题
this.setTitle("和与平均值");
//获取根面板
this.contentPanel = (JPanel) this.getContentPane();
//实例化主面板以边框布局方式
this.mainPanel = new JPanel(new BorderLayout());
//初始化组件
initConponents();
//初始化点击事件
iniEvent();
//设置可见
this.setVisible(true);
}
private void iniEvent() {
//给计算按钮添加点击事件
this.calculateBtn.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
//判定是否是鼠标左键点击
if(e.getButton() == MouseEvent.BUTTON1) {
//获取输入文本域的内容
String valueText = textArea.getText();
if(valueText == null || valueText.trim().length() == 0) {
//没有内容
JOptionPane.showMessageDialog(null, "输入为空!!!!");
//设置sumTextField的值为空
sumTextField.setText("");
//设置avgTextField的值为空
avgTextField.setText("");
}else {
//有内容,以逗号切分得到一个字符串数组
String [] valuesStr =valueText.split(",");
//将字符串转换为double数组
double[] doubleValues = strValuesToDoubleValues(valuesStr);
//求和值
double sum = sum(doubleValues);
//求均值
double avg = avg(doubleValues);
//格式化后的和值字符串
String sumStr = fomatDouble(sum);
//格式化后的均值字符串
String avgStr = fomatDouble(avg);
//设置sumTextField的值
sumTextField.setText(sumStr);
//设置avgTextField的值
avgTextField.setText(avgStr);
}
}
}
});
}
/**
* 格式化double数字并返回保留的小数的字符串
* @param value 需要格式化的double数字
* @return 返回保留的小数的字符串
*/
private String fomatDouble(double value) {
// 格式化保留两位小数
DecimalFormat df = new DecimalFormat("#.##");
// 将和格式化
String valueStr = df.format(value);
// 将字符串的和转为double类型
return valueStr;
}
/**
* 将一个double数组求和
* @param doubleValues 需要求和的数组
* @return 返回数组的和
*/
private double sum(double[] doubleValues) {
if ( doubleValues == null || doubleValues.length == 0) {
return 0;
}
double sum = 0;
for(double value:doubleValues ) {
//逐个累加
sum += value;
}
return sum;
}
/**
* 将一个double数组求均值
* @param doubleValues 需要求和的数组
* @return 返回数组的均值
*/
private double avg(double[] doubleValues) {
if ( doubleValues == null || doubleValues.length == 0) {
return 0;
}
//获取和值
double sum = sum(doubleValues) ;
//获取均值
double avg = sum / doubleValues.length ;
return avg;
}
/**
* 判断该字符串数组转换为double数组,如果转化失败返回null
* @param valueStr 需要转换的字符串数组
* @return double[]
*/
private double[] strValuesToDoubleValues(String[] valueStr) {
//数组为空或者个数为零直接返回false
if (valueStr == null || valueStr.length == 0) {
return null;
}
double[] doubleValues = new double[valueStr.length];
try {
for(int i = 0;i < valueStr.length; i++) {
//去掉每个值中的空格
String str = valueStr[i].trim();
//逐个转换
doubleValues[i] = Double.parseDouble(str);
}
} catch (NumberFormatException e) {
//转换出现异常
e.printStackTrace();
doubleValues = null;
JOptionPane.showMessageDialog(null, "输入有误,请以英文逗号分开每个数字!!");
}
return doubleValues;
}
private void initConponents() {
Font font = new Font("微软雅黑", Font.BOLD, 16);
// 实例化文本输入框
this.textArea = new JTextArea();
//强制设置大小尺寸为宽350,高100
this.textArea.setPreferredSize(new Dimension(300,100));
//设置输入框文本域的字体
this.textArea.setFont(font);
// 实例化显示和值文本域
this.sumTextField = new JTextField();
//设置字体大小样式
this.sumTextField.setFont(font);
//设置不可编辑,true为可编辑,false为不可编辑
this.sumTextField.setEditable(false);
//强制设置和值的文本大小
this.sumTextField.setPreferredSize(new Dimension(300,30));
// 实例化
this.avgTextField = new JTextField();
//设置字体大小样式
this.avgTextField.setFont(font);
//设置不可编辑,true为可编辑,false为不可编辑
this.avgTextField.setEditable(false);
//强制设置均值的文本大小
this.avgTextField.setPreferredSize(new Dimension(300, 30));
// 实例化计算按钮
this.calculateBtn = new JButton("计算");
// 强制设置按钮的大小
calculateBtn.setPreferredSize(new Dimension(60, 30));
// 实例化一个面板用于展示textArea
JPanel texAreaPanel = new JPanel();
// 强制设置该面板的大小
texAreaPanel.setPreferredSize(new Dimension(350,150));
//将输入框文本域添加到面板
texAreaPanel.add(this.textArea);
// 将框文本域面添加到主面板上方
this.mainPanel.add(texAreaPanel, BorderLayout.NORTH);
// 实例化一个面板用于展示sumTextField
JPanel sumTextFieldPanel = new JPanel();
// 强制设置该面板的大小
sumTextFieldPanel.setPreferredSize(new Dimension(350, 50));
//实例化一个提示表情
JLabel sumTextLable = new JLabel("和值");
//将该标签加入到sumTextFieldPanel
sumTextFieldPanel.add(sumTextLable);
// 将输入框文本域添加到面板
sumTextFieldPanel.add(this.sumTextField);
// 实例化一个面板用于展示sumTextField
JPanel avgTextFieldPanel = new JPanel();
// 强制设置该面板的大小
avgTextFieldPanel.setPreferredSize(new Dimension(350, 50));
// 实例化一个提示表情
JLabel avgTextFieldLable = new JLabel("均值");
// 将该标签加入到sumTextFieldPanel
avgTextFieldPanel.add(avgTextFieldLable);
// 将输入框文本域添加到面板
avgTextFieldPanel.add(this.avgTextField);
//计算面板
JPanel btnPanel = new JPanel();
//将按钮添加到面板中
btnPanel.add(calculateBtn);
JPanel centerPanel = new JPanel();
//将求和面板添加到中间面板
centerPanel.add(sumTextFieldPanel);
//将均值面板添加到中间面板
centerPanel.add(avgTextFieldPanel);
//将按钮面板添加到中间面板
centerPanel.add(btnPanel);
// 将中央面板添加到主面板中央
this.mainPanel.add(centerPanel, BorderLayout.CENTER);
//将主面板添加到本面板
this.contentPanel.add(mainPanel);
}
public static void main(String[] args) {
new SwingDemo(400, 400);
}
}
运行实例图片:
输入: 1 2 4.5 中间以英文逗号隔开,结果为:和值:7.5,均值:2.5
没有按钮,实时更新输入时的均值和和值(支持double数字)
package swingDemo;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.text.DecimalFormat;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
/**
* @author 陌意随影
TODO :使用swing实现求和和均值
*2020年10月29日 下午5:33:23
*/
public class SwingDemo2 extends JFrame {
private static final long serialVersionUID = 1L;
//内容面板
private JPanel contentPanel = null;
//输入的文本输入框
private JTextArea textArea = null;
//显示和值文本域
private JTextField sumTextField = null;
//显示均值文本域
private JTextField avgTextField = null;
//存放组件的面板
private JPanel mainPanel = null;
@SuppressWarnings("javadoc")
public SwingDemo2(int width,int height) {
//设置窗口的起始坐标以及宽和高
this.setBounds(200, 200, width, height);
//设置标题
this.setTitle("和与平均值");
//获取根面板
this.contentPanel = (JPanel) this.getContentPane();
//实例化主面板以边框布局方式
this.mainPanel = new JPanel(new BorderLayout());
//初始化组件
initConponents();
//初始化点击事件
iniEvent();
//设置可见
this.setVisible(true);
}
private void iniEvent() {
this.textArea.getDocument().addDocumentListener(new DocumentListener() {
@Override
public void removeUpdate(DocumentEvent e) {
textAreaAction();
}
@Override
public void insertUpdate(DocumentEvent e) {
textAreaAction();
}
@Override
public void changedUpdate(DocumentEvent e) {
textAreaAction();
}
});
}
/**
* 更改文本域时的操作
*/
private void textAreaAction() {
// 获取输入文本域的内容
String valueText = textArea.getText();
if (valueText == null || valueText.trim().length() == 0) {
// 设置sumTextField的值为空
sumTextField.setText("");
// 设置avgTextField的值为空
avgTextField.setText("");
} else {
// 有内容,以逗号切分得到一个字符串数组
String[] valuesStr = valueText.split(",");
// 将字符串转换为double数组
double[] doubleValues = strValuesToDoubleValues(valuesStr);
// 求和值
double sum = sum(doubleValues);
// 求均值
double avg = avg(doubleValues);
// 格式化后的和值字符串
String sumStr = fomatDouble(sum);
// 格式化后的均值字符串
String avgStr = fomatDouble(avg);
// 设置sumTextField的值
sumTextField.setText(sumStr);
// 设置avgTextField的值
avgTextField.setText(avgStr);
}
}
/**
* 格式化double数字并返回保留的小数的字符串
* @param value 需要格式化的double数字
* @return 返回保留的小数的字符串
*/
private String fomatDouble(double value) {
// 格式化保留两位小数
DecimalFormat df = new DecimalFormat("#.##");
// 将和格式化
String valueStr = df.format(value);
// 将字符串的和转为double类型
return valueStr;
}
/**
* 将一个double数组求和
* @param doubleValues 需要求和的数组
* @return 返回数组的和
*/
private double sum(double[] doubleValues) {
if ( doubleValues == null || doubleValues.length == 0) {
return 0;
}
double sum = 0;
for(double value:doubleValues ) {
//逐个累加
sum += value;
}
return sum;
}
/**
* 将一个double数组求均值
* @param doubleValues 需要求和的数组
* @return 返回数组的均值
*/
private double avg(double[] doubleValues) {
if ( doubleValues == null || doubleValues.length == 0) {
return 0;
}
//获取和值
double sum = sum(doubleValues) ;
//获取均值
double avg = sum / doubleValues.length ;
return avg;
}
/**
* 判断该字符串数组转换为double数组,如果转化失败返回null
* @param valueStr 需要转换的字符串数组
* @return double[]
*/
private double[] strValuesToDoubleValues(String[] valueStr) {
//数组为空或者个数为零直接返回false
if (valueStr == null || valueStr.length == 0) {
return null;
}
double[] doubleValues = new double[valueStr.length];
try {
for(int i = 0;i < valueStr.length; i++) {
//去掉每个值中的空格
String str = valueStr[i].trim();
//逐个转换
doubleValues[i] = Double.parseDouble(str);
}
} catch (NumberFormatException e) {
//转换出现异常
doubleValues = null;
}
return doubleValues;
}
private void initConponents() {
Font font = new Font("微软雅黑", Font.BOLD, 16);
// 实例化文本输入框
this.textArea = new JTextArea();
//强制设置大小尺寸为宽350,高100
this.textArea.setPreferredSize(new Dimension(300,100));
//添加提示词
this.textArea.setToolTipText("请以英文逗号隔开每个数");
//设置输入框文本域的字体
this.textArea.setFont(font);
// 实例化显示和值文本域
this.sumTextField = new JTextField();
//设置字体大小样式
this.sumTextField.setFont(font);
//设置不可编辑,true为可编辑,false为不可编辑
this.sumTextField.setEditable(false);
//强制设置和值的文本大小
this.sumTextField.setPreferredSize(new Dimension(300,30));
// 实例化
this.avgTextField = new JTextField();
//设置字体大小样式
this.avgTextField.setFont(font);
//设置不可编辑,true为可编辑,false为不可编辑
this.avgTextField.setEditable(false);
//强制设置均值的文本大小
this.avgTextField.setPreferredSize(new Dimension(300, 30));
// 实例化一个面板用于展示textArea
JPanel texAreaPanel = new JPanel();
// 强制设置该面板的大小
texAreaPanel.setPreferredSize(new Dimension(350,150));
//将输入框文本域添加到面板
texAreaPanel.add(this.textArea);
// 将框文本域面添加到主面板上方
this.mainPanel.add(texAreaPanel, BorderLayout.NORTH);
// 实例化一个面板用于展示sumTextField
JPanel sumTextFieldPanel = new JPanel();
// 强制设置该面板的大小
sumTextFieldPanel.setPreferredSize(new Dimension(350, 50));
//实例化一个提示表情
JLabel sumTextLable = new JLabel("和值");
//将该标签加入到sumTextFieldPanel
sumTextFieldPanel.add(sumTextLable);
// 将输入框文本域添加到面板
sumTextFieldPanel.add(this.sumTextField);
// 实例化一个面板用于展示sumTextField
JPanel avgTextFieldPanel = new JPanel();
// 强制设置该面板的大小
avgTextFieldPanel.setPreferredSize(new Dimension(350, 50));
// 实例化一个提示表情
JLabel avgTextFieldLable = new JLabel("均值");
// 将该标签加入到sumTextFieldPanel
avgTextFieldPanel.add(avgTextFieldLable);
// 将输入框文本域添加到面板
avgTextFieldPanel.add(this.avgTextField);
JPanel centerPanel = new JPanel();
//将求和面板添加到中间面板
centerPanel.add(sumTextFieldPanel);
//将均值面板添加到中间面板
centerPanel.add(avgTextFieldPanel);
// 将中央面板添加到主面板中央
this.mainPanel.add(centerPanel, BorderLayout.CENTER);
//将主面板添加到本面板
this.contentPanel.add(mainPanel);
}
public static void main(String[] args) {
new SwingDemo2(400, 400);
}
}
ps:要想实时监听输入文本域JextArea的变化,只需要添加Document监听即可:
this.textArea.getDocument().addDocumentListener(new DocumentListener() {
@Override
public void removeUpdate(DocumentEvent e) {
//删除文本域内容时触发
}
@Override
public void insertUpdate(DocumentEvent e) {
//插入文本域内容时触发
}
@Override
public void changedUpdate(DocumentEvent e) {
//更新文本域内容时触发
}
});
运行结果: