代码改变世界

java Gui初识

2012-04-21 10:12  youxin  阅读(616)  评论(0编辑  收藏  举报

java Gui初识

 
     主要有两类:AWT 和Swing类库  AWT 在java.awt包,swing 在javax.swing包中
AWT是早期的,可以提供基本的gui,swing则更加全面。包括了awt中具有的所有组件。并且提供了更加丰富的功能和部件。
但swing会用到许多awt中的许知识。swing组件都以J开头.
 
     组件:文本框,按钮,列表框,对话框等。我们称之为gui组件。java都提供了对应的java组件类。这些组件类都是
java.awt.Component的直接或间接子类。
 
     对于众多的gui组件,根据其作用分为两大类:基本组件(下面就全部简称为组件)和容器。
组件又被称为构件。在上面不能容纳其他的组件,容器其实也是一种组件,是一种比较特殊的组件,它可以用来容纳其他组件,如窗口,对话框等。所有的容器类都是java.awt.Container的直接或间接子类。container类是Component类的一个子类。由此可见容器本身也具有组件的功能和特点。也可以被当为基本组件一样使用。
 
java中的事件处理机制由3部分构成
1,事件(event object)
2.事件源(event source)
3.事件监听器(event listener):当事件发生时被通知到接受事件的事件监听对象,然后调用事件监听对象中对应的方法响应该事件。
 
有许多书将事件分为两大类:低级事件和语义事件(又叫高级事件); 很难记住哪些属于哪一类。有种
简单的方法区分,如果某个事件的监听器接口中只有一种方法法,那么这个事件就是语义事件。如
ActionListener中只有一个方法,ActionEvent就是一种语义事件。反之,则为低级事件。另外。从字面上,
我们也能理解:语义事件关心的是一个具有特殊作用的gui组件对应的动作发生了,而不关心这个动作是
怎样发生的。
 
对组件的响应和处理:
1)为组件注册实现规定接口的事件监听器
2)实现事件监听器接口中声明的事件处理抽象方法。
如:
JButton button=new JButton("Press");
buttton.addActionListener(new ButtonHandler());
鼠标单击,触发事件ActionEvent,将调用方法actionPerformed
Class ButtonHandler implements ActionListener{ //实现事件监听接口的类
     public void actionPerformed(ActionEvent event) // 实现事件处理方法
{
   、、、//事件处理代码
}
 
 
java对事件进行处理的方法是放在一个类对象中,这个类对象就是事件监听器,我们必须将一个事监听器对象同某个事件源的某种事件进行关联,这样,当这个事件源上方生了,关联的事件监听器对象中有关代码才会被执行。这个过程称为想事件源注册事件监听器对象。

 
从图中可以看到,事件处理器(事件监听器)首先与组件(事件源)建立关联,当组件接受外部作用(事件)时,
组件就会尝试一个相应的事件对象,并把此对象传给与之关联的事件处理器,事件处理器就是被启动并执行相关的的代码
来处理该事件
 
 
public class TestFrame {
 
      public static void main(String[] args) {
            // TODO Auto-generated method stub
            Frame f=new Frame("IT jiao liu");
            f.add(new Button("ok"));
            f.setSize(300,300);
            f.setVisible(true);
      
      }
 
}
窗口不会关闭。
程序运行结束后窗口不会关闭。 main线程结束后,但程序兵马没有结束。窗口还显示在桌面上。
对java来说,只要还有一个前台线程在运行,整个进程就不会结束。这说明程序还有其他线程在运行,那么其他线程是谁创建的。
可以简单的理解,程序在产生frame对象时,创建了一个新的线程,称之为AWT线程,
在上面的程序中,可以调用Frame.dispose()方法关闭框架窗口.
 
java语法规定必须实现接口的所有方法。(只写自己想要实现的方法,别的方法体留空)
 
import java.awt.Button;
import java.awt.Frame;
import java.awt.Window;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;

public class TestFrame {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Frame f=new Frame("IT jiao liu");
        f.add(new Button("ok"));
        f.setSize(300,300);
        f.setVisible(true);
        //f.dispose();
        f.addWindowListener(new MyWindowListener());
        
    }
     class MyWindowListener implements  WindowListener {

        @Override
        public void windowOpened(WindowEvent e) {
            // TODO Auto-generated method stub
            
        }

        @Override
        public void windowClosing(WindowEvent e) {
            // TODO Auto-generated method stub
            e.getWindow().setVisible(false);
            ((Window)e.getComponent()).dispose();
            System.exit(0);
            
        }

        @Override
        public void windowClosed(WindowEvent e) {
            // TODO Auto-generated method stub
            
        }

        @Override
        public void windowIconified(WindowEvent e) {
            // TODO Auto-generated method stub
            
        }

        @Override
        public void windowDeiconified(WindowEvent e) {
            // TODO Auto-generated method stub
            
        }

        @Override
        public void windowActivated(WindowEvent e) {
            // TODO Auto-generated method stub
            
        }

        @Override
        public void windowDeactivated(WindowEvent e) {
            // TODO Auto-generated method stub
            
        }
        
    }

}

但是上面的程序会报错,No enclosing instance of type TestFrame is accessible. Must qualify the allocation with an enclosing instance of type TestFrame (e.g. x.new A() where x is an instance of TestFrame).参考下一篇文章

class MyWindowListener 加上static;

上面用来2中方法来获取事件源对象。区别在哪里?
 
在上面的例子中,事件监听器的类MyWindoListener和产生gui组件的类TestFrame是两个完全分开的类,事件监听器的类中的
代码中访问其他的非事件源的gui组件,程序就得想别的办法了,如果我们想单击ok按钮来关闭框架窗口并退出程序,这要求
程序在按钮的事件监听器代码中要访问框架窗口,

事件监听器的类代码访问其它非事件源的gui组件,一个简单的方法是将事件监听器和产生gui的最近的代码放在同一个类中实现。

 

import java.awt.Button;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class TestFrame implements ActionListener
{
        Frame f=new Frame("IT资讯交流网");
        public static void main(String [] args)
        {
            TestFrame tf=new TestFrame();
            tf.init();
        }
        public void init()
        {
            Button btn=new Button("退出");
            btn.addActionListener(new TestFrame());
            f.add(btn);
            f.setSize(300,300);
            f.setVisible(true);
        }
        public void actionPerformed(ActionEvent e)
        {
            f.setVisible(false);
            f.dispose();
            System.exit(0);
        }
}

 

将在main 方法中调用gui初始化代码 全部放在了init方法中,在main方法中只要调用这个init方法就可以了,init是非静态的,可以直接方法非静态的成员变量。

上面的代码按button按钮不能关闭。

程序创建了2个TestFrame对象,桌面上先生的是第一个TestFrame的f对象,而退出按钮的花四溅处理代码中关闭的是第二个TestFrame中的f对象。
所以我们看到窗口没有关闭。将init方法中的btn.addActionListener(new TestFrame());改为btn.add(ActionListener(this)); 就可以了

如果一个事件监听器类只用于在一个组件上注册监听器事件对象,为了让程序代码更紧凑,我们可以用匿名内置类的语法来产生这个事件监听器对象,。

import java.awt.*;
import java.awt.event.*;
class TestFrame
{
    Frame f=new Frame("IT资讯交流网");
    public static void main(String [] args)
    {
        new TestFrame().init();
    }
    public void init()
    {
        Button btn=new Button("退出");
        btn.addActionListener(new ActionListener()
        {
                public void actionPerformed(ActionEvent e)
                {
                    f.setVisible(false);
                    f.dispose();
                    //不要加System.exit(0);

} }); f.add(btn); f.setSize(300,300); f.setVisible(true); } }