JavaSE学习57:GUI编程之事件模型(二)

来源:互联网 发布:西瓜影音mac版 编辑:程序博客网 时间:2024/05/29 15:16

     一实现两个数求和并且输出结果

       利用所学的GUI编程实现上述的要求。

       TFMath.java源代码:

<span style="font-size:18px;">import java.awt.*;import java.awt.event.*;public class TFMath {public static void main(String[] args) {new TFFrame().launchFrame();}}class TFFrame extends Frame{TextField num1, num2, num3;public void launchFrame(){num1 = new TextField(10);num2 = new TextField(10);num3 = new TextField(15);Label lblPlus = new Label("+");Button btnEqual = new Button("=");//在等号对象上添加监听器btnEqual.addActionListener(new MyMonitor(num1.num2,num3));setLayout(new FlowLayout());add(num1);add(lblPlus);add(num2);add(btnEqual);add(num3);pack();setVisible(true);}}class MyMonitor implements ActionListener{TextField num1, num2, num3;public MyMonitor(TextField num1, TextField num2, TextField num3){this.num1 = num1;this.num2 = num2;                this.num3 = num3;}public void actionPerformed(ActionEvent e) {int n1 = Integer.parseInt(num1.getText());int n2 = Integer.parseInt(num2.getText());num3.setText("" + (n1+n2));}}</span>
       运行结果:


       对上面的代码进行优化,体现设计模式的门面模式以及调停这模式。

       优化后的代码:

<span style="font-size:18px;">import java.awt.*;import java.awt.event.*;public class TFMath {public static void main(String[] args) {new TFFrame().launchFrame();}}class TFFrame extends Frame{TextField num1, num2, num3;public void launchFrame(){num1 = new TextField(10);num2 = new TextField(10);num3 = new TextField(15);Label lblPlus = new Label("+");Button btnEqual = new Button("=");//在等号对象上添加监听器btnEqual.addActionListener(new MyMonitor(this));setLayout(new FlowLayout());add(num1);add(lblPlus);add(num2);add(btnEqual);add(num3);pack();setVisible(true);}}class MyMonitor implements ActionListener{TFFrame tf = null;public MyMonitor(TFFrame tf) {this.tf = tf;}public void actionPerformed(ActionEvent e) {int n1 = Integer.parseInt(tf.num1.getText());int n2 = Integer.parseInt(tf.num2.getText());tf.num3.setText("" + (n1+n2));}}</span>

       我们也可以使用内部类进行代码优化。

       优化后的代码:

<span style="font-size:18px;">import java.awt.*;import java.awt.event.*;public class TFMath {public static void main(String[] args) {new TFFrame().launchFrame();}}class TFFrame extends Frame{TextField num1, num2, num3;public void launchFrame(){num1 = new TextField(10);num2 = new TextField(10);num3 = new TextField(15);Label lblPlus = new Label("+");Button btnEqual = new Button("=");//在等号对象上添加监听器btnEqual.addActionListener(new MyMonitor());setLayout(new FlowLayout());add(num1);add(lblPlus);add(num2);add(btnEqual);add(num3);pack();setVisible(true);}//内部类MyMonitorprivate class MyMonitor implements ActionListener {public void actionPerformed(ActionEvent e) {int n1 = Integer.parseInt(num1.getText());int n2 = Integer.parseInt(num2.getText());num3.setText("" + (n1+n2));}}}</span>
       两个的结果都同第一个结果。

       有关于内部类的使用,详细参考:JavaSE入门学习14:Java面向对象之内部类。

       使用内部类好处:

       1)可以方便的访问包装类的成员。

       2)可以更清楚的组织逻辑,放置不应该被其它类访问的类进行访问。

       何时使用内部类?

       该类不允许或不需要其他类进行访问时。

       对于上面的代码,我们还可以再进行优化。

        TFMathTest.java源代码:

<span style="font-size:18px;">import java.awt.*;import java.awt.event.*;public class TFMathTest extends Frame{TextField num1;TextField num2;TextField sum;public static void main(String[] args){new TFMathTest().launchFrame();}public void launchFrame(){num1 = new TextField();num2 = new TextField();sum = new TextField();num1.setColumns(10);num2.setColumns(10);sum.setColumns(15);setLayout(new FlowLayout());//setSize(500, 30);                Label lblPlus = new Label("+");Button btnEqual = new Button("=");btnEqual.addActionListener(new MyListener(this));add(num1);add(lblPlus);add(num2);add(btnEqual);add(sum);pack();setVisible(true);}}class MyListener implements ActionListener{private TFMathTest tfmt;        public MyListener(TFMathTest tfmt){this.tfmt = tfmt;}public void actionPerformed(ActionEvent e){String s1 = tfmt.num1.getText();String s2 = tfmt.num2.getText();int i1 = Integer.parseInt(s1);int i2 = Integer.parseInt(s2);tfmt.sum.setText(String.valueOf(i1 + i2));}}</span>

        二Graphics类

        每个Component都有一个paint(Graphics g)用于实现绘图目的,每次重画该Component时都会自动调用paint()方法。

        Graphics类中提供了许多绘图方法,如:

        drawRect(int x,int y,int width,int height)

        fillRoundRect(int x,int y,int width,int height,int arcWidth,int arcHeight)

        更多的方法和用法请查看API文档。

        实例:

        TestPaint.java源代码:

<span style="font-size:18px;">import java.awt.*;public class TestPaint {public static void main(String[] args) {new PaintFrame().launchFrame();}}class PaintFrame extends Frame {public void launchFrame() {setBounds(200,200,640,480);setVisible(true);}public void paint(Graphics g) {Color c = g.getColor();g.setColor(Color.red);g.fillOval(50, 50, 30, 30);g.setColor(Color.green);g.fillRect(80,80,40,40);                //恢复原来画笔的颜色g.setColor(c);}}</span>

        运行结果:


        三鼠标事件适配器

        抽象类java.awt.event.MouseAdapter实现类MouseListener接口,可以使用其子类作为MouseEvent的监听器,

只要重写其相应的方法即可。

        对于其他的监听器,也有对应的适配器。使用适配器可以避免监听器类定义没有必要的空方法。

        机制:repaint()方法中调用了update()方法,而update()方法又调用了paint()方法。

        实例:

        MyMouseAdapter.java源代码:

<span style="font-size:18px;">import java.awt.*;import java.awt.event.*;import java.util.*;public class MyMouseAdapter{public static void main(String args[]){new MyFrame("drawing");    }}class MyFrame extends Frame{ArrayList<Point> points = null;//构造方法        MyFrame(String s){super(s);                points = new ArrayList<Point>();                 setLayout(null);                setBounds(300,300,400,300);                 this.setBackground(new Color(204,204,255));                setVisible(true);                this.addMouseListener(new Monitor());}//画圆public void paint(Graphics g){Iterator<Point> i = points.iterator();                while(i.hasNext()){Point p = (Point)i.next();                        g.setColor(Color.BLUE);                       g.fillOval(p.x,p.y,20,20);                }        }       public void addPoint(Point p){//向points对象中添加点对象points.add(p);       }}//MouseAdapter类实现了MouseListener接口class Monitor extends MouseAdapter{public void mousePressed(MouseEvent e){MyFrame f = (MyFrame)e.getSource();                f.addPoint(new Point(e.getX(),e.getY());//进行重画                f.repaint();    }}</span>

        运行结果:

        在窗口中点击会画出很多实心小圆


        四Window事件

        Window事件所对应的事件类为WindowEvent,所对应的事件监听接口为WindowListener。

        WindowListener接口定义的方法有:


        与WindowListener对应的适配器为WindowAdapter,下面的例子使用了适配器Adapter设计模式。

        TestWindowClose.java源代码:

<span style="font-size:18px;">import java.awt.*;import java.awt.event.*;public class TestWindowClose{public static void main(String args[]){new MyFrame55("Java窗口");    }}class MyFrame55 extends Frame{MyFrame55(String s){super(s);                setLayout(null);                setBounds(300, 300, 400, 300);                this.setBackground(new Color(204, 204, 255));                setVisible(true);                this.addWindowListener(new MyWindowMonitor());        }        //内部类MyWindowMonitor        //WindowAdapter类实现了WindowListener接口        class MyWindowMonitor extends WindowAdapter{public void windowClosing(WindowEvent e){setVisible(false);          System.exit(0);          }         }}</span>

        运行结果:


        使用匿名类优化后的代码:

<span style="font-size:18px;">import java.awt.*;import java.awt.event.*;public class TestWindowClose{public static void main(String args[]){new MyFrame55("Java窗口");    }}class MyFrame55 extends Frame{MyFrame55(String s){     super(s);             setLayout(null);             setBounds(300, 300, 400, 300);             this.setBackground(new Color(204, 204, 255));             setVisible(true);            //使用匿名方法内部类     //WindowAdapter类实现了WindowListener接口             this.addWindowListener(new WindowAdapter(){public void windowClosing(WindowEvent e){setVisible(false);                        System.exit(-1);                }             });    }}</span>

        匿名内部类

        实例

<span style="font-size:18px;">import java.awt.*;import java.awt.event.*;/*范例名称:匿名类在事件处理中的使用 * 源文件名称:TestAnonymous.java *要  点: *  1. 匿名类的性质和用法 *2. 将监听器类定义为匿名类的好处---- *在内部类的基础上进一步简化了代码 */public class TestAnonymous {Frame f = new Frame("匿名内部类测试");TextField tf = new TextField(30);public TestAnonymous(){f.add(new Label("请按下鼠标左键并拖动"), "North");f.add(tf, "South");//使用匿名类f.addMouseMotionListener(new MouseMotionAdapter(){public void mouseDragged(MouseEvent e) {               String s = "鼠标拖动到位置(" + e.getX() + "," + e.getY() + ")";               tf.setText(s);}public void mouseMoved(MouseEvent e) { }});f.setSize(300, 200);    f.setVisible(true);}public static void main(String args[]) {   TestAnonymous t = new TestAnonymous();}}</span>

        运行结果:


        TestAnonymous2.java源文件代码:

<span style="font-size:18px;">import java.awt.*;import java.awt.event.*;/*范例名称:匿名类在事件处理中的使用 * 源文件名称:TestAnonymous2.java *要  点: *1. 匿名类只能是内部类 *2. 匿名类的两种创建方式----既可以继承父类、也可以单重实现接口 */public class TestAnonymous2 {Frame f = new Frame("Test");TextField tf = new TextField(10);Button b1 = new Button("Start");public TestAnonymous2(){f.add(b1,"North");f.add(tf,"South");//使用匿名内部类b1.addActionListener(new ActionListener(){private int i;public void actionPerformed(ActionEvent e) { tf.setText(e.getActionCommand() + ++i);    }});//使用匿名内部类f.addWindowListener(new WindowAdapter(){public void windowClosing(WindowEvent e){System.exit(0);}});f.pack();        f.setVisible(true);}public static void main(String args[]) {new TestAnonymous2();}}</span>
        运行结果:


        适用场合:

       1)逻辑比较简单;

       2)代码比较少;

       五键盘事件处理

       实例:

<span style="font-size:18px;">import java.awt.*;import java.awt.event.*;public class TestKey {public static void main(String[] args) {new KeyFrame().launchFrame();}}class KeyFrame extends Frame {public void launchFrame() {setSize(400, 300);setLocation(300,300);addKeyListener(new MyKeyMonitor());setVisible(true);}//使用内部类//KeyAdapter类实现了KeyListener接口class MyKeyMonitor extends KeyAdapter {public void keyPressed(KeyEvent e) {int keyCode = e.getKeyCode();                                                //按下UP键if(keyCode == KeyEvent.VK_UP) {System.out.println("UP");}}}}</span>

       运行结果:

  

     



1 0
原创粉丝点击