一、实验预热
1、请解释什么是事件,什么是事件源,什么是事件监听接口,并各举出例子。
事件:一般继承自java.util.EventObject类,封装了事件源对象及跟事件相关的信息。
事件源:事件发生的地方,由于事件源的某项属性或状态发生了改变(比如button被单击、textbox的值发生改变等等)导致某项事件发生,换句话说就是生成了相应的事件对象。因为事件监听器要注册在事件源上,所以事件源类中应该要有包含监听器的容器(List、Set等等)。
事件监听器:实现java.util.EventListener接口,注册在事件源上,当事件源的属性或状态改变时,取得相应的监听器调用其内部的回调方法。
2、Swing编程中处理事件的一般流程是什么?
实现事件监听接口
实例化接口对象
将监听器与事件源绑定
复写接口的抽象方法
二、实验内容
1、请用java编写一个计算器,外观布局设计没有特殊要求,计算器功能必须至少要包含加、减、乘、除四种运算。运算结果要显示在GUI结果文本框中,计算器数字和运算符按键必须在GUI上显示,用户可以直接通过按键进行输入而得到计算结果。
代码:
package leif.tests;
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class ExperimentalReport extends JFrame implements ActionListener {
private static final long serialVersionUID = 1L;
private class WindowCloser extends WindowAdapter {
@Override
public void windowClosing(WindowEvent we) {
System.exit(0);
}
}
private static final String[] CALCULATOR = {"7", "8", "9", "/", "4", "5", "6", "*", "1", "2", "3", "-", ".", "0", "=", "+"};
JButton[] buttons = new JButton[CALCULATOR.length];
JButton reset = new JButton("CE");
JTextField display = new JTextField("0");
public ExperimentalReport() {
super("Calculator");
JPanel button = new JPanel(new GridLayout(4, 4));
for (int i = 0; i < CALCULATOR.length; i++) {
buttons[i] = new JButton(CALCULATOR[i]);
button.add(buttons[i]);
}
JPanel dial = new JPanel(new BorderLayout());
dial.add("Center", display);
dial.add("East", reset);
getContentPane().setLayout(new BorderLayout());
getContentPane().add("North", dial);
getContentPane().add("Center", button);
for (int i = 0; i < CALCULATOR.length; i++) {
buttons[i].addActionListener(this);
}
reset.addActionListener(this);
display.addActionListener(this);
addWindowListener(new WindowCloser());
setSize(800, 800);
setVisible(true);
pack();
}
@Override
public void actionPerformed(ActionEvent e) {
Object target = e.getSource();
String label = e.getActionCommand();
if (target == reset) {
handleReset();
} else if ("0123456789.".indexOf(label) > 0) {
handleNumber(label);
} else {
handleOperator(label);
}
}
boolean isFirstDigit = true;
public void handleNumber(String key) {
if (isFirstDigit) {
display.setText(key);
} else if ((key.equals(".")) && (display.getText().indexOf(".") < 0)) {
display.setText(display.getText() + ".");
} else if (!key.equals(".")) {
display.setText(display.getText() + key);
}
isFirstDigit = false;
}
public void handleReset() {
display.setText("0");
isFirstDigit = true;
operator = "=";
}
double number = 0.0;
String operator = "=";
public void handleOperator(String key) {
if (operator.equals("+")) {
number += Double.valueOf(display.getText());
} else if (operator.equals("-")) {
number -= Double.valueOf(display.getText());
} else if (operator.equals("*")) {
number *= Double.valueOf(display.getText());
} else if (operator.equals("/")) {
number /= Double.valueOf(display.getText());
} else if (operator.equals("=")) {
number = Double.valueOf(display.getText());
}
display.setText(String.valueOf(number));
operator = key;
isFirstDigit = true;
}
public static void main(String[] args) {
new ExperimentalReport();
}
}
结果截图:
image.png
2、请编写一个进度条程序,界面包含一个拷贝进度条,和一个拷贝开始按钮,当拷贝结束时在UI上显示拷贝完成字样,同时要求进度条和拷贝实际速度基本同步。
代码:
package leif.tests;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JProgressBar;
import javax.swing.WindowConstants;
public class ExperimentalReport extends JFrame {
private static final long serialVersionUID = 1L;
JProgressBar jProgressBar = new JProgressBar();
private static Thread thread;
private int flag = 1;
public ExperimentalReport() {
setSize(300, 200);
setLayout(null);
setTitle("拷贝进度条");
setVisible(true);
setLocationRelativeTo(null);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
jProgressBar.setOrientation(JProgressBar.HORIZONTAL);
jProgressBar.setSize(150, 50);
jProgressBar.setMinimum(0);
jProgressBar.setMaximum(100);
jProgressBar.setBorderPainted(true);
jProgressBar.setBounds(50, 50, 200, 20);
jProgressBar.setStringPainted(true);
jProgressBar.setIndeterminate(false);
jProgressBar.setForeground(Color.green);
JButton jButton = new JButton("开始");
jButton.setBounds(110, 100, 70, 30);
add(jProgressBar);
add(jButton);
jButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (flag == 1) {
thread.start();
flag++;
}
}
});
thread = new Thread(new Runnable() {
@Override
public void run() {
File file1 = new File("C:\\Users\\Administrator\\Desktop\\user.sql");
if (!file1.exists()) {
System.out.println("源文件不存在");
System.exit(0);
}
File file2 = new File("C:\\Users\\Administrator\\Desktop\\user1.sql");
long Length = file1.length();
int progress = 1;
byte[] bytes = new byte[(int)(Length / 100)];
FileInputStream fileInputStream = null;
FileOutputStream fileOutputStream = null;
try {
fileInputStream = new FileInputStream(file1);
fileOutputStream = new FileOutputStream(file2);
while (fileInputStream.read(bytes) != -1) {
fileOutputStream.write(bytes);
jProgressBar.setValue(progress);
progress++;
Thread.sleep(100);
}
jProgressBar.setString("拷贝完成!");
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
try {
fileInputStream.close();
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
});
}
public static void main(String args[]) {
new ExperimentalReport();
}
}
结果截图:
image.png