简述
刚刚的文本框获得焦点时回车和按钮单击,都属于ActionEvent事件,也就是说文本框和按钮可以作为ActionEvent事件的事件源。
而选择框的选中,和下拉列表的选中,都是在触发ItemEvent事件。
不同类型的事件的监听器要实现的接口不同,对于ActionEvent事件,这个接口是ActionListener,实现其中的actionPerformed方法,方法传入的也是ActionEvent对象。
而对于ItemEvent事件,则要实现的是ItemListener接口,实现其中的itemStateChanged方法,方法传入的是ItemEvent对象。
这个例子中,并没有像上节的ActionEvent事件处理时的例子那样:自己写一个接口去继承ActionListener接口,然后往接口里添加获得需要的资源的方法,然后让监视器去继承这个接口来间接继承ActionListener接口。
而是直接继承了ItemListener接口,我猜作者这样做是为了图方便,其实没有什么区别。然后在监视器中直接添加了获取必要资源的方法。
而且,这个例子里ItemEvent事件的监视器还拥有获取ActionEvent事件监视器引用的方法,这是为了将自己获取的“用户选择了下拉列表的哪一项”的信息传递给ActionEvent事件监视器,这样才能进一步的监听ActionEvent事件。
程序
还是书上的程序,一点小修改。
ComputerListener.java
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JTextArea;
import javax.swing.JTextField;
//这个监听器直接实现了ActionListener接口
//将组件的引用传进来的方法,也直接加就行了
//没有去建立继承ActionListener接口的接口
public class ComputerListener implements ActionListener{
JTextField jtf1,jtf2;
JTextArea jta;
String sign;
/*传入三个组件引用的三个方法*/
public void setJTTF1(JTextField t) {
this.jtf1=t;
}
public void setJTTF2(JTextField t) {
this.jtf2=t;
}
public void setJTA(JTextArea t) {
this.jta=t;
}
/*传入加减乘除具体选了哪个的方法*/
public void setSign(String s) {
this.sign=s;
}
//处理ActionEvent事件
@Override
public void actionPerformed(ActionEvent e) {
try {
//文本框内的文本转double类型数
double num1=Double.parseDouble(jtf1.getText());
double num2=Double.parseDouble(jtf2.getText());
double rslt=0;
//要对运算符做判断,以决定作什么运算
if(sign.equals("+"))
rslt=num1+num2;
else if(sign.equals("-"))
rslt=num1-num2;
else if(sign.equals("*"))
rslt=num1*num2;
else if(sign.equals("/"))
rslt=num1/num2;
//用""以保证是字符串连接,而不是值得运算
jta.append(num1+""+sign+""+num2+"="+rslt+"\n");
}catch(Exception exp) {
//当没有输入或者输入的文本不能转换成double时,有异常
jta.append("****错误!请输入数字字符!****\n");
}
}
}
OperatorListener.java
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import javax.swing.JComboBox;
//这个监听器直接实现了ItemListener接口
//将组件的引用传进来的方法,也直接加就行了
//没有去建立继承ItemListener接口的接口
public class OperatorListener implements ItemListener{
JComboBox jcb;//下拉列表
ComputerListener cl;//用来监听ActionEvent事件的监听器
//传入下拉列表组件引用的方法
public void setJComboBox(JComboBox box) {
this.jcb=box;
}
//传入ActionEvent事件监听器的方法
public void setWorkTogeter(ComputerListener c) {
this.cl=c;
}
//处理ItemEvent事件
@Override
public void itemStateChanged(ItemEvent e) {
//用getSelectedItem()获取选中的那项,再转成字符串
String s=jcb.getSelectedItem().toString();
//然后传给事件监听器
//也就是说,先监听到了ItemEvent事件,知道了选中哪一项
//然后给了事件监听器,再去监听有没有要开始计算
cl.setSign(s);
}
}
WindowOperation.java
import java.awt.FlowLayout;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
//底层容器
public class WindowOperation extends JFrame{
JTextField jtf1,jtf2;
JComboBox jcb;//下拉列表
JTextArea jta;
JButton jb;
OperatorListener ol;//ItemEvent事件监听器
ComputerListener cl;//ActionEvent事件监听器
WindowOperation() {
init();
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
private void init() {
this.setLayout(new FlowLayout());
jtf1=new JTextField(5);
jtf2=new JTextField(5);
jcb=new JComboBox();
jb=new JButton("=");
jta=new JTextArea(9,30);
ol=new OperatorListener();
cl=new ComputerListener();
//为下拉列表添加列表项
jcb.addItem("选择运算符号:");
String[] a= {"+","-","*","/"};
for(String s:a) {
jcb.addItem(s);
}
//先把必要的资源或资源引用传递给监听器
ol.setJComboBox(jcb);
ol.setWorkTogeter(cl);
cl.setJTA(jta);
cl.setJTTF1(jtf1);
cl.setJTTF2(jtf2);
//然后再为事件源注册监听器
jcb.addItemListener(ol);
jb.addActionListener(cl);
//把组件部署到这个底层容器上
this.add(jtf1);
this.add(jcb);
this.add(jtf2);
this.add(jb);
this.add(new JScrollPane(jta));
}
}
Main.java
import com.sun.java.swing.plaf.windows.WindowsOptionPaneUI;
public class Main {
public static void main(String[] args) {
WindowOperation wo=new WindowOperation();
wo.setBounds(100,100,390,290);
wo.setTitle("对ItemEvent事件的处理");
}
}
运行