4、组件的事件处理编程
Java利用事件监听机制来使组件响应用户发出的各种事件,如点击、按动键盘等。
4、1 基本方法
4、1、1 步骤简述
常见的基本做法为三个步骤:
1)编写一个事件监听器类
2)声明此事件监听器类的对象
3)给特定的组件添加此事件监听器类对象的引用
下面以给按钮的单击事件编程为例,说明一下处理步骤:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class exec
{
public static void main(String args[])
{
MyFrame m=new MyFrame("OK");
m.setSize(200,400);
m.setVisible(true);
}
}
class MyFrame extends JFrame
{
JButton b1=new JButton("Click Me");
public MyFrame(String title)
{
super(title);
getContentPane().setLayout(new FlowLayout());
getContentPane().add(b1);
Handel b=new Handel();
b1.addActionListener(b);
}
}
class Handel implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
javax.swing.JOptionPane.showMessageDialog(null,"Hello!");
}
}
这个程序能够响应用户的单击事件,显示一个对话框
说明:
1)Handel为自己定义的事件监听器类,实现了ActionListener接口的所有方法,即actionPerformed方法
2)在窗体的构造函数中声明了此事件监听器类的对象,如:Handel b=new Handel();
3)给按钮组件添加了此事件监听器类对象的引用,如b1.addActionListener(b);
这种处理方式的真实意义表现为:让按钮对象在不改变自己代码的情况下,能够以不同的行为方式来响应用户的事件。如果直接将程序代码编写进按钮的单击事件方法,将无法实现用户自定义按钮单击行为的效果。所以,在按钮的单击事件方法中,仅仅触发一个引用类型的属性指向的对象方法,而用户可以通过将不同的特定对象引用传给按钮的这个属性,就可以实现自定义按钮单击事件的效果。
这种由对象主动调用监听器类方法的行为,从表面看起来,确实很象事件监听器类在监听对象的事件行为,一旦对象发生具体的事件行为,事件监听器类就主动执行相应的代码。所以,人们通常称之为“事件监听”,严格说来,仅仅是个方法调用。
同时,为了防止用户无法确定按钮事件方法中究竟调用的是哪一个对象方法,所以,通过监听器接口就可以在按钮和事件监听器类间作出详细明确的规定:首先,按钮总是触发监听器接口中定义的方法;其次,用户自定义的事件监听器类可以通过继承事件监听器接口而实现指定的方法,从而确保此事件监听器类一定具有按钮能够调用的方法。
下面结合实际的按钮源代码来说明:
按钮JButton是AbstractButton的派生类,在AbstractButton类中,定义了一个引用数组类型的属性,即listenerList,并且在addActionListener方法中给它增添了新的ActionListener类型对象成员:
public void addActionListener(ActionListener l)
{
listenerList.add(ActionListener.class, l);
}
在按钮的单击事件方法(fireActionPerformed)中,有触发此引用类型属性指向的对象方法的代码:
protected void fireActionPerformed(ActionEvent event)
{
...
Object[] listeners = listenerList.getListenerList();
...
e = new ActionEvent(AbstractButton.this,ActionEvent.ACTION_PERFORMED,actionCommand,event.getWhen(),event.getModifiers());
((ActionListener)listeners[i+1]).actionPerformed(e);
...
}
此处的listeners是一个包含actionListener对象引用的数组,按钮确实触发了此方法,并且还将一个封装对象自己引用的ActionEvent对象作为参数传给了被调用方法。
这个参数意义很大,可以由此得到发生事件的事件源对象引用,从而利用它可以在事件监听器类中获取窗体上组件的引用,如将上述程序改写成单击按钮弹出一个显示按钮标签的对话框:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class exec
{
public static void main(String args[])
{
MyFrame m=new MyFrame("OK");
m.setSize(200,400);
m.setVisible(true);
}
}
class MyFrame extends JFrame
{
JButton b1=new JButton("Click Me");
public MyFrame(String title)
{
super(title);
getContentPane().setLayout(new FlowLayout());
getContentPane().add(b1);
Handel b=new Handel();
b1.addActionListener(b);
}
}
class Handel implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
JButton be=(JButton)e.getSource();
javax.swing.JOptionPane.showMessageDialog(null,be.getText());
}
}
4、1、2 将事件监听器类和窗体合而为一的写法
将两者合而为一,代码更加简单,并且事件监听器类就是窗体自己,从而可以更加灵活的访问窗体的各种组件,而不仅仅限于事件源组件,如:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class exec
{
public static void main(String args[])
{
MyFrame m=new MyFrame("OK");
m.setSize(200,400);
m.setVisible(true);
}
}
class MyFrame extends JFrame implements ActionListener
{
JButton b1=new JButton("Click Me");
public MyFrame(String title)
{
super(title);
getContentPane().setLayout(new FlowLayout());
getContentPane().add(b1);
b1.addActionListener(this);
}
public void actionPerformed(ActionEvent e)
{
JButton be=(JButton)e.getSource();
javax.swing.JOptionPane.showMessageDialog(null,be.getText());
this.setTitle(be.getText());
}
}
4、1、3 事件监听器的匿名类
使用匿名类是种较为简单的设计方法,具有和单独建立事件监听器类相似的效果,然而无需显式的声明此类,如:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class exec
{
public static void main(String args[])
{
MyFrame m=new MyFrame("OK");
m.setSize(200,400);
m.setVisible(true);
}
}
class MyFrame extends JFrame
{
JButton b1=new JButton("Click Me");
public MyFrame(String title)
{
super(title);
getContentPane().setLayout(new FlowLayout());
getContentPane().add(b1);
b1.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
JButton be=(JButton)e.getSource();
javax.swing.JOptionPane.showMessageDialog(null,be.getText());
}
});
}
}
通过编译可以发现,此匿名类在最终编译后,其实是由系统生成的一个名称为MyFrame$1.class的事件监听器类。
4、1、4 另外一种监听器类的实现方法
可以直接将主函数所在类作为监听器类,如:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class exec implements ActionListener
{
public static void main(String args[])
{
JFrame m=new JFrame("OK");
m.setSize(200,400);
JButton b1=new JButton("Click Me");
m.getContentPane().setLayout(new FlowLayout());
m.getContentPane().add(b1);
b1.addActionListener(new exec());
m.setVisible(true);
}
public void actionPerformed(ActionEvent e)
{
JButton be=(JButton)e.getSource();
javax.swing.JOptionPane.showMessageDialog(null,be.getText());
}
}
4、1、5 一些利用按钮事件编程的例子
4、1、5、1 具有多个按钮的程序
要想使得不同按钮具有不同的功能,可以采用生成不同的事件监听器类来处理不同按钮对象的事件监听。
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class exec
{
public static void main(String args[])
{
MyFrame m=new MyFrame("OK");
m.setSize(200,400);
m.setVisible(true);
}
}
class MyFrame extends JFrame
{
JButton b1=new JButton("Click Me");
JButton b2=new JButton("Click Here");
public MyFrame(String title)
{
super(title);
getContentPane().setLayout(new FlowLayout());
getContentPane().add(b1);
getContentPane().add(b2);
Handel1 h1=new Handel1();
b1.addActionListener(h1);
Handel2 h2=new Handel2();
b2.addActionListener(h2);
}
}
class Handel1 implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
JButton be=(JButton)e.getSource();
javax.swing.JOptionPane.showMessageDialog(null,be.getText());
}
}
class Handel2 implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
JButton be=(JButton)e.getSource();
javax.swing.JOptionPane.showMessageDialog(null,be.getText());
}
}
显然,上述程序是相当臃肿的,其实两个监听器类行为非常相似,所以,完全可以只建立一个监听器类,同时赋给两个不同的按钮作为它们的事件监听器,如:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class exec
{
public static void main(String args[])
{
MyFrame m=new MyFrame("OK");
m.setSize(200,400);
m.setVisible(true);
}
}
class MyFrame extends JFrame
{
JButton b1=new JButton("Click Me");
JButton b2=new JButton("Click Here");
public MyFrame(String title)
{
super(title);
getContentPane().setLayout(new FlowLayout());
getContentPane().add(b1);
getContentPane().add(b2);
Handel h=new Handel();
b1.addActionListener(h);
b2.addActionListener(h);
}
}
class Handel implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
JButton be=(JButton)e.getSource();
javax.swing.JOptionPane.showMessageDialog(null,be.getText());
}
}
也可以使用将窗体和监听器合而为一的做法来做:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class exec
{
public static void main(String args[])
{
MyFrame m=new MyFrame("OK");
m.setSize(200,400);
m.setVisible(true);
}
}
class MyFrame extends JFrame implements ActionListener
{
JButton b1=new JButton("Click Me");
JButton b2=new JButton("Click Here");
public MyFrame(String title)
{
getContentPane().setLayout(new FlowLayout(0,0,0));
getContentPane().add(b1);
getContentPane().add(b2);
b1.addActionListener(this);
b2.addActionListener(this);
pack();
}
public void actionPerformed(ActionEvent e)
{
JButton be=(JButton)e.getSource();
javax.swing.JOptionPane.showMessageDialog(null,be.getText());
}
}
4、1、5、2 求和计算器程序之一
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class exec
{
public static void main(String args[])
{
MyFrame m=new MyFrame("OK");
m.setSize(200,400);
m.setVisible(true);
m.pack();
}
}
class MyFrame extends JFrame implements ActionListener
{
JLabel l1=new JLabel("****计算器****",JLabel.CENTER);
JTextField t1=new JTextField(5);
JTextField t2=new JTextField(5);
JTextField t3=new JTextField(10);
JButton b1=new JButton("Sum");
public MyFrame(String title)
{
getContentPane().setLayout(new GridLayout(5,1));
getContentPane().add(l1);
getContentPane().add(t1);
getContentPane().add(t2);
getContentPane().add(t3);
getContentPane().add(b1);
t3.setBackground(Color.green);
b1.addActionListener(this);
}
public void actionPerformed(ActionEvent e)
{
String s;
int a=Integer.parseInt(t1.getText());
int b=Integer.parseInt(t2.getText());
int c=a+b;
s=String.valueOf(c);
t3.setText(s);
}
}
4、1、5、3 求和计算器程序之二
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class exec
{
public static void main(String args[])
{
MyFrame m=new MyFrame("OK");
Toolkit theKit = m.getToolkit();
Dimension wndSize = theKit.getScreenSize();
m.setBounds(wndSize.width/4, wndSize.height/4, wndSize.width/2, wndSize.height/2);
m.setVisible(true);
m.pack();
}
}
class MyFrame extends JFrame implements ActionListener
{
JTextField jtf;
JPanel jp;
JButton[] jb;
JButton jb1,jb2;
int num1,num2;
public MyFrame(String title)
{
super(title);
getContentPane().setLayout(new BorderLayout(10,10));
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jtf=new JTextField();
jp=new JPanel();
jp.setLayout(new GridLayout(4,3));
jb=new JButton[10];
jb1=new JButton("=");
jb2=new JButton("+");
for(int i=0;i<jb.length;i++)
{
jb=new JButton(String.valueOf(i));
jb.addActionListener(this);
jp.add(jb);
}
jb1.addActionListener(this);
jb2.addActionListener(this);
jp.add(jb1);
jp.add(jb2);
getContentPane().add(jtf,BorderLayout.NORTH);
getContentPane().add(jp,BorderLayout.CENTER);
}
public void actionPerformed(ActionEvent e)
{
JButton be=(JButton)e.getSource();
String bt=be.getText();
if(bt.equals("+"))
{
num1=Integer.parseInt(jtf.getText());
jtf.setText("");
}
else if(bt.equals("="))
{
num2=Integer.parseInt(jtf.getText());
jtf.setText(String.valueOf(num1+num2));
}
else
{
jtf.setText(jtf.getText()+bt);
}
}
}
注意:
1)此程序使用对象数组来做,方便数字按钮的事件处理
2)此程序通过自动获取当前屏幕的大小,动态设置窗体的位置,代码为:
Toolkit theKit = m.getToolkit();
Dimension wndSize = theKit.getScreenSize();
4、2 其他常用的事件监听器
4、2、1 窗体事件监听器
窗体事件监听器可以对窗体的很多行为(如打开、最小化、关闭等)进行事件编程。下面的程序能够在点击窗体关闭按钮时候退出应用程序,如:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class exec
{
public static void main(String args[])
{
MyFrame m=new MyFrame("OK");
m.setSize(200,400);
m.setVisible(true);
}
}
class MyFrame extends JFrame
{
JButton b1=new JButton("Click Me");
public MyFrame(String title)
{
super(title);
getContentPane().setLayout(new FlowLayout());
getContentPane().add(b1);
handel b=new handel();
this.addWindowListener(b);
}
}
class handel implements WindowListener
{
public void windowOpened(WindowEvent e)
{
}
public void windowClosed(WindowEvent e)
{
}
public void windowClosing(WindowEvent e)
{
e.getWindow().dispose();
System.exit(0);
}
public void windowIconified(WindowEvent e)
{
}
public void windowDeiconified(WindowEvent e)
{
}
public void windowActivated(WindowEvent e)
{
}
public void windowDeactivated(WindowEvent e)
{
}
}
注意:
1)此时的监听器接口为WindowListener,此接口中方法较多,不同的方法分别在不同的窗体事件情况下被调用,如窗体打开时调用windowOpened,窗体已经关闭时调用windowClosed,窗体正在关闭时调用windowClosing,窗体最小化时调用windowIconified,窗体还原时调用windowDeiconified,窗体得到焦点时调用windowActivated,窗体失去焦点时调用windowDeactivated。下面的程序更加清晰的表明了窗体各种事件的调用情况,如:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class exec
{
public static void main(String args[])
{
MyFrame m=new MyFrame("OK");
m.setSize(200,400);
m.setVisible(true);
}
}
class MyFrame extends JFrame
{
JButton b1=new JButton("Click Me");
public MyFrame(String title)
{
super(title);
getContentPane().setLayout(new FlowLayout());
getContentPane().add(b1);
handel b=new handel();
this.addWindowListener(b);
}
}
class handel implements WindowListener
{
public void windowOpened(WindowEvent e)
{
System.out.println("Opened");
}
public void windowClosed(WindowEvent e)
{
System.out.println("Closed");
System.exit(0);
}
public void windowClosing(WindowEvent e)
{
System.out.println("Closing");
e.getWindow().dispose();
}
public void windowIconified(WindowEvent e)
{
System.out.println("Iconified");
}
public void windowDeiconified(WindowEvent e)
{
System.out.println("Deiconified");
}
public void windowActivated(WindowEvent e)
{
System.out.println("Activated");
}
public void windowDeactivated(WindowEvent e)
{
System.out.println("Deactivated");
}
}
注意观察命令提示符的文字输出
2)可以使用将窗体和事件监听器合而为一的写法,如:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class exec
{
public static void main(String args[])
{
MyFrame m=new MyFrame("OK");
m.setSize(200,400);
m.setVisible(true);
}
}
class MyFrame extends JFrame implements WindowListener
{
JButton b1=new JButton("Click Me");
public MyFrame(String title)
{
super(title);
getContentPane().setLayout(new FlowLayout());
getContentPane().add(b1);
this.addWindowListener(this);
}
public void windowOpened(WindowEvent e)
{
}
public void windowClosed(WindowEvent e)
{
}
public void windowClosing(WindowEvent e)
{
e.getWindow().dispose();
System.exit(0);
}
public void windowIconified(WindowEvent e)
{
}
public void windowDeiconified(WindowEvent e)
{
}
public void windowActivated(WindowEvent e)
{
}
public void windowDeactivated(WindowEvent e)
{
}
}
3)虽然不准备对所有事件进行编程,但是必须实现所有的接口方法,即使语句为空。显然,做法很是烦琐。较为简单的做法是利用事件适配器类简化编程。事件适配器类是系统已经实现好的事件监听器接口的类,只不过所有的实现方法都是没有语句的空方法,所以,只需继承事件适配器类,通过重写的方式将自己实现的特定方法替换原有父类方法即可,如:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class exec
{
public static void main(String args[])
{
MyFrame m=new MyFrame("OK");
m.setSize(200,400);
m.setVisible(true);
}
}
class MyFrame extends JFrame
{
JButton b1=new JButton("Click Me");
public MyFrame(String title)
{
super(title);
getContentPane().setLayout(new FlowLayout());
getContentPane().add(b1);
handel b=new handel();
this.addWindowListener(b);
}
}
class handel extends WindowAdapter
{
public void windowClosing(WindowEvent e)
{
e.getWindow().dispose();
System.exit(0);
}
}
4)更为常见的简单做法是直接使用swing窗体的setDefaultCloseOperation方法来设置窗体的关闭行为,如:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class exec
{
public static void main(String args[])
{
MyFrame m=new MyFrame("OK");
m.setSize(200,400);
m.setVisible(true);
m.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
class MyFrame extends JFrame
{
JButton b1=new JButton("Click Me");
public MyFrame(String title)
{
super(title);
getContentPane().setLayout(new FlowLayout());
getContentPane().add(b1);
}
}
4、2、2 鼠标事件监听器
鼠标事件监听器可以给很多组件(如标签、窗体等)提供基于鼠标的诸多事件编程能力。下面的程序能够点击标签产生不同的行为,用到了鼠标事件监听器类,如:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class exec
{
public static void main(String args[])
{
MyFrame m=new MyFrame("OK");
m.setSize(200,400);
m.setVisible(true);
m.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
m.pack();
}
}
class MyFrame extends JFrame implements MouseListener//注意此处
{
JLabel l1=new JLabel("left",JLabel.LEFT);
JLabel l2=new JLabel("center",JLabel.CENTER);
JLabel l3=new JLabel("right",JLabel.RIGHT);
JTextField t=new JTextField(10);
public MyFrame(String title)
{
getContentPane().setLayout(new GridLayout(4,1));
getContentPane().add(l1);
getContentPane().add(l1);
getContentPane().add(l2);
getContentPane().add(l3);
getContentPane().add(t);
l1.addMouseListener(this);
l2.addMouseListener(this);
l3.addMouseListener(this);
}
public void mousePressed(MouseEvent e)
{
JLabel j=(JLabel)e.getSource();
t.setText(j.getText());
}
//下面不可少
public void mouseClicked(MouseEvent e)
{;}
public void mouseEntered(MouseEvent e)
{;}
public void mouseExited(MouseEvent e)
{;}
public void mouseReleased(MouseEvent e)
{;}
}
4、2、3 项目事件监听器
项目事件监听器可以给很多组件(如复选框、单选钮等)提供点选事件的编程能力,如:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class exec
{
public static void main(String args[])
{
MyFrame m=new MyFrame("OK");
m.setSize(200,400);
m.setVisible(true);
m.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
class MyFrame extends JFrame implements ItemListener//注意此处
{
int a=0;
JCheckBox c1=new JCheckBox("Visual J++");
JCheckBox c2=new JCheckBox("Visual Foxpro");
JCheckBox c3=new JCheckBox("Visual Basic");
JCheckBox c4=new JCheckBox("Visual C++");
JTextField t=new JTextField(5);
public MyFrame(String title)
{
getContentPane().setLayout(new GridLayout(5,1));
getContentPane().add(c1);
getContentPane().add(c2);
getContentPane().add(c3);
getContentPane().add(c4);
getContentPane().add(t);
c1.setActionCommand("30");
c2.setActionCommand("40");
c3.setActionCommand("50");
c4.setActionCommand("80");
c1.addItemListener(this);
c2.addItemListener(this);
c3.addItemListener(this);
c4.addItemListener(this);
}
public void itemStateChanged(ItemEvent e)//注意此处
{
JCheckBox c=(JCheckBox)e.getItem();
if(c.isSelected()==true)
{
a+=Integer.parseInt(c.getActionCommand());
}
else
{
a-=Integer.parseInt(c.getActionCommand());
}
t.setText(String.valueOf(a));
}
}
说明:
1)此程序是利用复选框的isSelected方法来判断复选框是否被选中
2)此程序是利用复选框的setActionCommand方法和getActionCommand方法来设置和读取相关的价格信息
4、2、4 调节事件监听器
调节事件监听器可以给很多组件(如滚动条等)提供调节大小的事件编程能力,如:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class exec
{
public static void main(String args[])
{
MyFrame m=new MyFrame("OK");
m.setSize(200,400);
m.setVisible(true);
m.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
class MyFrame extends JFrame implements AdjustmentListener//注意此处
{
int a=0;
int x=0,y=0,z=0;
JScrollBar s1=new JScrollBar(Scrollbar.HORIZONTAL,0,1,0,256);
JScrollBar s2=new JScrollBar(Scrollbar.HORIZONTAL,0,1,0,256);
JScrollBar s3=new JScrollBar(Scrollbar.HORIZONTAL,0,1,0,256);
JPanel jp=new JPanel();
public MyFrame(String title)
{
getContentPane().setLayout(new BorderLayout(0,0));
jp.setLayout(new GridLayout(3,1));
jp.add(s1);
jp.add(s2);
jp.add(s3);
getContentPane().setBackground(new Color(x,y,z));
getContentPane().add(jp,BorderLayout.NORTH);
s1.addAdjustmentListener(this);
s2.addAdjustmentListener(this);
s3.addAdjustmentListener(this);
}
public void adjustmentValueChanged(AdjustmentEvent e)//注意此处
{
if(e.getAdjustable()==s1)x=s1.getValue();//有选择的设置
if(e.getAdjustable()==s2)y=s2.getValue();
if(e.getAdjustable()==s3)z=s3.getValue();
getContentPane().setBackground(new Color(x,y,z));
}
}
4、2、5 其他的一些例子
4、2、5、1 菜单程序
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class exec
{
public static void main(String args[])
{
MyFrame m=new MyFrame("OK");
m.setSize(200,400);
m.setVisible(true);
}
}
class MyFrame extends JFrame implements ActionListener
{
JMenuBar mb;
JMenu m;
JMenuItem m1,m2,m3;
JTextField t=new JTextField(10);
public MyFrame(String title)
{
super(title);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
getContentPane().setLayout(new GridLayout(1,1));
getContentPane().add(t);
mb=new JMenuBar();
m=new JMenu("文件");
m1=new JMenuItem("新建");
m.add(m1);
m2=new JMenuItem("打开");
m.add(m2);
m3=new JMenuItem("关闭");
m.add(m3);
mb.add(m);
setJMenuBar(mb);
m1.addActionListener(this);
m2.addActionListener(this);
m3.addActionListener(this);
}
public void actionPerformed(ActionEvent e)
{
if(e.getSource()==m1)
{
t.setText("");
}
if(e.getSource()==m2)
{
JFileChooser jfc=new JFileChooser();
int returnVal=jfc.showOpenDialog(this);
if(returnVal == JFileChooser.APPROVE_OPTION)
{
t.setText(jfc.getSelectedFile().getName());
}
}
if(e.getSource()==m3)
{
System.exit(0);
}
}
}
说明:JFileChooser类为系统提供的能够显示“打开文件对话框”的类,诸如此类的还有很多,如JColorChooser类能够显示“颜色选择对话框”等
4、2、5、2 基于窗体的鼠标绘图程序
1)较为简单的绘制直线的程序
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class exec
{
public static void main(String args[])
{
MyFrame m=new MyFrame("OK");
Toolkit theKit = m.getToolkit();
Dimension wndSize = theKit.getScreenSize();
m.setBounds(wndSize.width/4, wndSize.height/4, wndSize.width/2, wndSize.height/2);
m.setVisible(true);
}
}
class MyFrame extends JFrame implements MouseListener
{
Point anchor=new Point();
Point drawto=new Point();
public MyFrame(String title)
{
super(title);
setBackground(Color.white);
addMouseListener(this);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void paint(Graphics g)
{
g.setColor(Color.black);
g.drawLine(anchor.x,anchor.y,drawto.x,drawto.y);
}
public void mousePressed(MouseEvent e)
{
anchor=new Point(e.getX(),e.getY());
drawto=new Point(e.getX(),e.getY());
}
public void mouseReleased(MouseEvent e)
{
drawto=new Point(e.getX(),e.getY());
repaint();
}
public void mouseClicked(MouseEvent e)
{;}
public void mouseEntered(MouseEvent e)
{;}
public void mouseExited(MouseEvent e)
{;}
}
2)能够绘制痕迹的直线程序
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class exec
{
public static void main(String args[])
{
MyFrame m=new MyFrame("OK");
Toolkit theKit = m.getToolkit();
Dimension wndSize = theKit.getScreenSize();
m.setBounds(wndSize.width/4, wndSize.height/4, wndSize.width/2, wndSize.height/2);
m.setVisible(true);
}
}
class MyFrame extends JFrame implements MouseListener,MouseMotionListener
{
Point anchor=new Point();
Point drawto=new Point();
public MyFrame(String title)
{
super(title);
setBackground(Color.white);
addMouseListener(this);
addMouseMotionListener(this);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void paint(Graphics g)
{
g.setColor(Color.black);
g.drawLine(anchor.x,anchor.y,drawto.x,drawto.y);
}
public void mousePressed(MouseEvent e)
{
anchor=new Point(e.getX(),e.getY());
drawto=new Point(e.getX(),e.getY());
}
public void mouseReleased(MouseEvent e)
{
drawto=new Point(e.getX(),e.getY());
repaint();
}
public void mouseClicked(MouseEvent e)
{;}
public void mouseEntered(MouseEvent e)
{;}
public void mouseExited(MouseEvent e)
{;}
public void mouseDragged(MouseEvent e)
{
drawto=new Point(e.getX(),e.getY());
repaint();
}
public void mouseMoved(MouseEvent e)
{;}
}
3)使用背景色覆盖方法绘制“橡皮筋”直线的程序(当直线相交时有问题,会擦除以前的直线)
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class exec
{
public static void main(String args[])
{
MyFrame m=new MyFrame("OK");
Toolkit theKit = m.getToolkit();
Dimension wndSize = theKit.getScreenSize();
m.setBounds(wndSize.width/4, wndSize.height/4, wndSize.width/2, wndSize.height/2);
m.setVisible(true);
}
}
class MyFrame extends JFrame implements MouseListener,MouseMotionListener
{
Point anchor=new Point();
Point drawto=new Point();
Point olddrawto=new Point();
public MyFrame(String title)
{
super(title);
setBackground(Color.white);
addMouseListener(this);
addMouseMotionListener(this);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void paint(Graphics g)
{
g.setColor(this.getBackground());
g.drawLine(anchor.x,anchor.y,olddrawto.x,olddrawto.y);
g.setColor(Color.black);
g.drawLine(anchor.x,anchor.y,drawto.x,drawto.y);
}
public void mousePressed(MouseEvent e)
{
anchor=new Point(e.getX(),e.getY());
olddrawto=new Point(e.getX(),e.getY());
drawto=new Point(e.getX(),e.getY());
}
public void mouseReleased(MouseEvent e)
{
drawto=new Point(e.getX(),e.getY());
repaint();
}
public void mouseClicked(MouseEvent e)
{;}
public void mouseEntered(MouseEvent e)
{;}
public void mouseExited(MouseEvent e)
{;}
public void mouseDragged(MouseEvent e)
{
olddrawto=drawto;
drawto=new Point(e.getX(),e.getY());
repaint();
}
public void mouseMoved(MouseEvent e)
{;}
}
4)使用异或方法绘制“橡皮筋”直线的程序(正确、有效的程序)
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class exec
{
public static void main(String args[])
{
MyFrame m=new MyFrame("OK");
Toolkit theKit = m.getToolkit();
Dimension wndSize = theKit.getScreenSize();
m.setBounds(wndSize.width/4, wndSize.height/4, wndSize.width/2, wndSize.height/2);
m.setVisible(true);
}
}
class MyFrame extends JFrame implements MouseListener,MouseMotionListener
{
Point anchor=new Point();
Point drawto=new Point();
Point olddrawto=new Point();
public MyFrame(String title)
{
super(title);
setBackground(Color.white);
addMouseListener(this);
addMouseMotionListener(this);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void paint(Graphics g)
{
g.setColor(Color.black);
g.setXORMode(getBackground());//将背景色、前景色和此处参数的背景色进行三色异或,意味着在前景色上画图时,将成为背景色
g.drawLine(anchor.x,anchor.y,olddrawto.x,olddrawto.y);
g.drawLine(anchor.x,anchor.y,drawto.x,drawto.y);
}
public void mousePressed(MouseEvent e)
{
anchor=new Point(e.getX(),e.getY());
olddrawto=new Point(e.getX(),e.getY());
drawto=new Point(e.getX(),e.getY());
}
public void mouseReleased(MouseEvent e)
{
drawto=new Point(e.getX(),e.getY());
repaint();
}
public void mouseClicked(MouseEvent e)
{;}
public void mouseEntered(MouseEvent e)
{;}
public void mouseExited(MouseEvent e)
{;}
public void mouseDragged(MouseEvent e)
{
olddrawto=drawto;
drawto=new Point(e.getX(),e.getY());
repaint();
}
public void mouseMoved(MouseEvent e)
{;}
}
[此贴子已经被作者于2010-12-12 08:01:53编辑过]