[置顶] JavaSE学习笔记_19:Java-GUI

Java-GUI

 

1、Java-GUI(概述)

什么是GUI?

GUI就是Graphic User Interface的缩写。它提供了一个标准的制作界面、制作外观的方法。我们知道人机交互有两种方式,一个是图形化界面,还有一个是命令行接口。因此对应的有CLI,即Command Line User Interface。综上所述:

GUI:图形用户接口

CLI:命令行用户接口

以上两种人机交互方式在之前的笔记中已有详细的叙述,再次不作阐述。

 

java.awt、javax.Swing、java.xwt

java为GUI提供的对象都存在java.awt和java.Swing两个包中。

java.awt:Abstract Windows ToolKit(抽象窗口工具包),需要调用本地系统方法实现功能,调用系统底层,依赖于平台。跨平台性、移植性差。就比方说,在windows 2000系统下,开发的图形化界面放到windows xp系统下,界面会有点不一样。因此我们说它属重量级控件。

java.Swing:在Awt的基础下,建立的一套图形界面系统,其中提供了更多的组件。而且完全有java实现,正好弥补了java.awt的不足之处,增强了移植性,属轻量级控件。

java.xwt:eclipse界面就是用它来开发的。纯java编写的。这也是一个外观包。

 

下面我们来看一下,java给GUI提供的两个包中到底有那些工具类呢?

继承关系图:(常用)

 [置顶] JavaSE学习笔记_19:Java-GUI_第1张图片

 

2、Java-GUI(布局)

做界面,我们玩的就是窗体,当我们new一个窗体之后,往里面添加其他组件,比如按钮等,怎么添加是个问题。但是java给我们提供了布局管理器。

 

容器中的组件的排放方式,就是布局。

常见的布局管理器:

FlowLayout(流式布局管理器)

从左到右的顺序排列。

Panel默认的布局管理器。

BoderLayout(边界布局管理器)

东、南、西、北、中

Frame默认的布局管理器。

GridLayout(网格布局管理器)

规则的矩阵

GridBagLayout(网格包布局管理器)

非规则的矩阵

CardLayout(卡片布局管理器)

选项卡

坐标式布局

通过指定坐标可以放在任意位置

混合式布局

通过面板,窗体中添加面板,面板中添加组件。窗体可以创建这些布局管理器的对象指定布局,面板亦是。不同面板中可以是不同的布局。

 

FlowLayout(流式布局管理器)

 [置顶] JavaSE学习笔记_19:Java-GUI_第2张图片

BoderLayout(边界布局管理器)

 [置顶] JavaSE学习笔记_19:Java-GUI_第3张图片

GridLayout(网格布局管理器)

 [置顶] JavaSE学习笔记_19:Java-GUI_第4张图片

GridBagLayout(网格包布局管理器)

 

CardLayout(卡片布局管理器)

坐标式布局

 [置顶] JavaSE学习笔记_19:Java-GUI_第5张图片

混合式布局

 [置顶] JavaSE学习笔记_19:Java-GUI_第6张图片

 

图形化界面最难的就是布局。因此,我们在开发的时候,尽量用一些高级的编辑器,比如JBuild,比如eclipse加上一个图形化界面插件,画布,画布中有很多组件。代码自动生成。VB,C++的开发就有画布。

 

 

3、Java-GUI(Frame)

下面我们首先通过一个小程序来进入主题:

import java.awt.*;

class AwtDemo

{

public static void main(String[] args)

{

Frame f=new Frame("my awt");//创建一个带名字的 //窗体,但是不可见。

System.out.println("hello world");

}

}

通过命令行进行编译运行,发现打印出hello world ,主线程结束。但是程序并没有结束。因此我们知道,所有图形化界面都是一个单独的前台线程。此时必须通过Ctrl C结束。

我们还可以对窗体进行设置:

public AwtDemo

{

poublic static void main(String[] args)

{

Frame f=new Frame("my awt");

f.setSize(500,400);

f.setLocation(300,200);

/*

这一步必须做,不然往窗体里边加组件时,组件会铺 满整个窗体,因为Frame的默认布局是边界布局。

*/

f.setLayout(new FlowLayout());

 

Button b=new Button("我是一个按钮");

 

f.add(b);

f.setVisible(true);

}

}

现在通过命令行进行编译运行,会出现效果,但是当你点击窗口中的按钮,没有什么效果,还有就是窗体没有关闭的特点,只有放大,缩小的特点,这会涉及后面讲到的监听事件(我们操作一个东西,会发生什么样的事情)。

 

总结:创建图形化界面:

1、创建Frame 窗体。

2、对窗体进行基本设置。比如大小,位置,布局。

3、定义组件。

4、将组件通过窗体的add方法添加到窗体中。

5、让窗体显示,通过setVisible(true);

 

 

 

 

4、Java-GUI(事件监听机制)

在上一次的学习当中,我们知道了如何监听窗体。但是我们是在main函数中做的,类中只有一个main函数,在这一次学习中,我们将图形化界面和事件监听分离。首先我们来看一下代码的实现:

import java.awt.*;

import java.awt.event.*;

class FrameDemo

{

private Frame f;

private Button b;

 

FrameDemo()

{

init();

}

 

public void init()

{

f=new Frame("my frame");

 

//对窗体进行一些基本的设置。

f.setBounds(300,400,500,600);

f.setLayout(new FlowLayout());

 

b=new Button("my button");

 

//把组件加到窗体中。

f.add(b);

//加载窗体上的一些事件。

myEvent();

 

//显示窗体。

f.setVisible(true);

}

public void myEvent()

{

f.addWindowListener(new WindowAdapter(){

public void windowClosing(WindowEvent e)

{

System.exit(0);

}

});

}

 

//窗体测试。

public static void main(String[] args)

{

new FrameDemo();

}

}

编译运行后,结果如下图所示:

 [置顶] JavaSE学习笔记_19:Java-GUI_第7张图片

当点击叉时,结果如下如所示:

 [置顶] JavaSE学习笔记_19:Java-GUI_第8张图片

 

接下来我们想通过点击按钮使窗口关闭的效果。因此,现在的事件源是按钮,我们现在应当在按钮上注册监听器,根据在窗体注册监听器的经验告诉我们需要查看该组件对象的功能,通过查阅Button的API,发现按钮支持一个特有的添加监听器的方法addActionListener(ActionListener l);同理,需要接收一个ActionListener类型的参数l,这个l就是监听器,这个ActionListener也是一个接口,但是它里边只有一个抽象方法,因此我们不需要在思考它有没有适配器来方便我们创建监听器对象,我们可以直接通过匿名内部类来创建子类对象。下面我们通过代码来看一下具体的实现:

import java.awt.*;

import java.awt.event.*;

class FrameDemo

{

private Frame f;

private Button b;

 

FrameDemo()

{

init();

}

 

public void init()

{

f=new Frame("my frame");

 

//对窗体进行一些基本的设置。

f.setBounds(300,400,500,600);

f.setLayout(new FlowLayout());

 

b=new Button("my button");

 

//把组件加到窗体中。

f.add(b);

//加载窗体上的一些事件。

myEvent();

 

//显示窗体。

f.setVisible(true);

}

public void myEvent()

{

f.addWindowListener(new WindowAdapter(){

public void windowClosing(WindowEvent e)

{

System.exit(0);

}

});

 

//

b.addActionListener(new ActionListener(){

public void actionPerformed(ActionEvent e)

{

//验证一下窗体被关闭是不是按钮干的。

System.out.println("按钮干的");

System.exit(0);

}

});

}

 

//窗体测试。

public static void main(String[] args)

{

new FrameDemo();

}

}

编译运行后,结果如下图所示:

 

当点击一下按钮,结果如下图所示:

 

 

 

5、Java-GUI(窗体事件)

上一次的学习当中,我们遇到了窗口不能关闭的问题,于是我们引入看事件监听机制的概念。在本次的学习中,我们将具体的学习窗口是如何被监听的?

 

首先,我们要在窗体上注册监听器:

f.addWindowListener(WindowListener l);该方法是Frame从它的父类Window继承而来。此时l就是监听器。

ps:我们知道监听器中有两部分内容,一个是监听的动作,一个是事件处理方式。根据面向对象的思想,l是WindowListener的一个实例,我们可以通过查看WindowListener就可以知道监听器l中是否包含这两部内容。查看之后,发现:有void windowActivated(WindowEvent e)、void windowClosing(WindowEvent e)等方法,确实体现出监听器中两部分内容。现在的问题是,WindowListener是一个接口,所以不能实例化,因此,该方法接收的一定是该接口子类的对象,而且该子类必须实现该接口中所有的方法,否则仍然是抽象类,不能实例化(但是如果现在只想监听关闭的动作,其他动作不监听,覆盖所有方法有些多余)。按照这个思路我们找到了它的一个实现类WindowAdapter,它实现了父接口WindowListener中所有的方法,但是方法体为空。因此仍然把它定义成抽象类,因为创建它的对象也毫无意义。这种情况就叫作没有一个抽象方法的抽象类。但是,它的存在是有意义的,它是一个接收窗口事件的抽象适配器类,方便创建监听器对象(正好解决了上述所讲的“多余”问题,我们只需要继承WindowAdapter(注意它所在的包是java.awt.event,所以开发时,要导包。),复写我们需要的方法,监听我们想监听的动作,如WindowClosing())。下面我们来看一下,它是如何方便的呢?

可以写出如下代码:

import java.awt.*;

import java.awt.event.*;

class AwtDemo

{

public static void main(String[] args)

{

Frame f=new Frame("窗体演示");

f.setSize(500,400);

f.setLocation(200,300);

f.setLayout(new FlowLayout());

 

Button b=new Button("我是一个按钮");

f.add(b);

 

f.addWindowListener(new MyWin());

 

f.setVisible(true);

}

}

class MyWin extends WindowAdapter

{

public void windowClosing(WindowEvent e)

{

System.out.println("关闭窗体");

System.exit(0);

}

}

将上述代码保存成一个.java文件,叫作:Awt.java。 打开命令行编译运行的结果如下图所示:

 [置顶] JavaSE学习笔记_19:Java-GUI_第9张图片

当我们点击串口的关闭按钮,则有如下变化:

 [置顶] JavaSE学习笔记_19:Java-GUI_第10张图片

 

现在我们在回过头来看看代码:我们可以用匿名内部类来做:

import java.awt.*;

import java.awt.event.*;

class AwtDemo

{

public static void main(String[] args)

{

Frame f=new Frame("窗体演示");

f.setSize(500,400);

f.setLocation(200,300);

f.setLayout(new FlowLayout());

 

Button b=new Button("我是一个按钮");

f.add(b);

 

f.addWindowListener(new WindowAdapter()

{

pubic void WindowClosing(WindowEvent e)

{

System.exit(0);

}

});

 

f.setVisible(true);

}

}

/*

class MyWin extends WindowAdapter

{

public void windowClosing(WindowEvent e)

{

System.out.println("关闭窗体");

System.exit(0);

}

}

*/

编译运行之后,也会出现同样的效果哦。以后开发中 会经常用到这种方法。我们还可以监听多个动作。

拓展:

import java.awt.*;

import java.awt.event.*;

class AwtDemo

{

public static void main(String[] args)

{

Frame f=new Frame("窗体演示");

f.setSize(500,400);

f.setLocation(200,300);

f.setLayout(new FlowLayout());

 

Button b=new Button("我是一个按钮");

f.add(b);

 

f.addWindowListener(new WindowAdapter()

{

public void windowClosing(WindowEvent e)

{

System.exit(0);

}

public void windowOpened(WindowEvent e)

{

System.out.println("我被打开了");

}

public void windowActivated(WindowEvent e)

{

System.out.println("我活了。");

}

});

 

f.setVisible(true);

}

}

编译运行后,结果如下图所示:

 

 

 

6、Java-GUI(Action事件)

在上一次的学习当中,我们知道了如何监听窗体。但是我们是在main函数中做的,类中只有一个main函数,在这一次学习中,我们将图形化界面和事件监听分离。首先我们来看一下代码的实现:

import java.awt.*;

import java.awt.event.*;

class FrameDemo

{

private Frame f;

private Button b;

 

FrameDemo()

{

init();

}

 

public void init()

{

f=new Frame("my frame");

 

//对窗体进行一些基本的设置。

f.setBounds(300,400,500,600);

f.setLayout(new FlowLayout());

 

b=new Button("my button");

 

//把组件加到窗体中。

f.add(b);

//加载窗体上的一些事件。

myEvent();

 

//显示窗体。

f.setVisible(true);

}

public void myEvent()

{

f.addWindowListener(new WindowAdapter(){

public void windowClosing(WindowEvent e)

{

System.exit(0);

}

});

}

 

//窗体测试。

public static void main(String[] args)

{

new FrameDemo();

}

}

编译运行后,结果如下图所示:

 [置顶] JavaSE学习笔记_19:Java-GUI_第11张图片

当点击叉时,结果如下如所示:

 [置顶] JavaSE学习笔记_19:Java-GUI_第12张图片

 

接下来我们想通过点击按钮使窗口关闭的效果。因此,现在的事件源是按钮,我们现在应当在按钮上注册监听器,根据在窗体注册监听器的经验告诉我们需要查看该组件对象的功能,通过查阅Button的API,发现按钮支持一个特有的添加监听器的方法addActionListener(ActionListener l);同理,需要接收一个ActionListener类型的参数l,这个l就是监听器,这个ActionListener也是一个接口,但是它里边只有一个抽象方法,因此我们不需要在思考它有没有适配器来方便我们创建监听器对象,我们可以直接通过匿名内部类来创建子类对象。下面我们通过代码来看一下具体的实现:

import java.awt.*;

import java.awt.event.*;

class FrameDemo

{

private Frame f;

private Button b;

 

FrameDemo()

{

init();

}

 

public void init()

{

f=new Frame("my frame");

 

//对窗体进行一些基本的设置。

f.setBounds(300,400,500,600);

f.setLayout(new FlowLayout());

 

b=new Button("my button");

 

//把组件加到窗体中。

f.add(b);

//加载窗体上的一些事件。

myEvent();

 

//显示窗体。

f.setVisible(true);

}

public void myEvent()

{

f.addWindowListener(new WindowAdapter(){

public void windowClosing(WindowEvent e)

{

System.exit(0);

}

});

 

//

b.addActionListener(new ActionListener(){

public void actionPerformed(ActionEvent e)

{

//验证一下窗体被关闭是不是按钮干的。

System.out.println("按钮干的");

System.exit(0);

}

});

}

 

//窗体测试。

public static void main(String[] args)

{

new FrameDemo();

}

}

编译运行后,结果如下图所示:

 [置顶] JavaSE学习笔记_19:Java-GUI_第13张图片

当点击一下按钮,结果如下图所示:

 [置顶] JavaSE学习笔记_19:Java-GUI_第14张图片[置顶] JavaSE学习笔记_19:Java-GUI_第15张图片

 

 

7、Java-GUI(鼠标事件)

在本次的学习中,我们将会知道鼠标事件是如何监听的。首先,我们应该知道鼠标事件是所有组件都应该有的事件。添加鼠标事件监听器的方法应该在Component类中,通过查找Component的api,我们找到了一个方法叫作:

addMouseListener(MouseListener l);显然,l就是在组件中所注册的监听器,这个监听器的类型是MouseListener,该接口中有mouseClicked()、mouseEntered()等抽象方法,因此它有适配器MouseAdapter。下面,以组件button以例来讲解。看下面代码:

import java.awt.*;

import java.awt.event.*;

class MouseAndKeyDemo

{

private Frame f;

private Button b;

 

MouseAndKeyDemo()

{

init();

}

 

public void init()

{

f=new Frame("my frame");

 

f.setBounds(200,300,400,500);

f.setLayout(new FlowLayout());

 

b=new Button("my button");

f.add(b);

 

myEvent();

 

f.setVisible(true);

}

 

public void myEvent()

{

f.addWindowListener(new WindowAdapter()

{

public void windowClosing(WindowEvent e)

{

System.exit(0);

}

});

 

b.addMouseListener(new MouseAdapter()

{

private int count;

public void mouseEntered(MouseEvent e)

{

System.out.println("鼠标进入到该组件"+count++);

}

});

}

 

public static void main(String[] args)

{

new MouseAndKeyDemo();

}

}

编译运行后,将鼠标放在按钮上,再拿出,再放入,再拿出就,结果如下如所示:

 [置顶] JavaSE学习笔记_19:Java-GUI_第16张图片

在原有的基础上,再来监听鼠标点击按钮的动作。则在myEvent()中代码如下所示:

public void myEvent()

{

f.addWindowListener(new WindowAdapter()

{

public void windowClosing(WindowEvent e)

{

System.exit(0);

}

});

 

b.addMouseListener(new MouseAdapter()

{

private int count;

private int clickCount;

public void mouseEntered(MouseEvent e)

{

System.out.println("鼠标进入到该组件"+count++);

}

public void mouseClicked(MouseEvent e)

{

System.out.println("点击动作"+clickCount++);

}

});

}

编译运行后的结果如下所示:

 [置顶] JavaSE学习笔记_19:Java-GUI_第17张图片

 

 

再想到之前我们在按钮上注册的监听器l它是监听活动的,它的类型是ActionListener。下面我们如果给按钮添加这个监听器,结果有如何呢?

代码如下:

import java.awt.*;

import java.awt.event.*;

class MouseAndKeyDemo

{

private Frame f;

private Button b;

 

MouseAndKeyDemo()

{

init();

}

 

public void init()

{

f=new Frame("my frame");

 

f.setBounds(200,300,400,500);

f.setLayout(new FlowLayout());

 

b=new Button("my button");

f.add(b);

 

myEvent();

 

f.setVisible(true);

}

 

public void myEvent()

{

f.addWindowListener(new WindowAdapter()

{

public void windowClosing(WindowEvent e)

{

System.exit(0);

}

});

 

b.addActionListener(new ActionListener()

{

public void actionPerformed(ActionEvent e)

{

System.out.println("action ok");

}

});

 

b.addMouseListener(new MouseAdapter()

{

private int count;

private int clickCount;

public void mouseEntered(MouseEvent e)

{

System.out.println("鼠标进入到该组件"+count++);

}

public void mouseClicked(MouseEvent e)

{

System.out.println("点击动作"+clickCount++);

}

});

}

 

public static void main(String[] args)

{

new MouseAndKeyDemo();

}

}

 

编译运行后结果如下所示:

 [置顶] JavaSE学习笔记_19:Java-GUI_第18张图片

 

发现:点击动作产生的事件对象被先处理。这里需要注意,按钮只要被活动,就会产生事件对象。而鼠标和键盘会使按钮活动的更具体,所以先处理。还有就是,鼠标不放在按钮上点击或者是敲击键盘都会显示出action ok。

 

拓展:

现在想监听双击按钮的动作,怎么做呢?通过查阅MouseListener接口,发现并没有对应的方法,而只有相关的mouseClicked(MouseEvent e)但是,我们想,监听器只负责接收动作产生的事件对象e,而这个对象里肯定封装了一些内容,因此,是什么样的点击动作,这个对象中肯定有封装。果不其然,当我们查阅MouseEvent时,里面有一个方法getClickCount();因此我们可以做一个判断,核心代码如下:

public void mouseClicked(MouseEvent e)

{

if(e.getClickCount==2)

System.out.println("点击动作"+clickCount++);

}

编译运行结果如下所示:

 [置顶] JavaSE学习笔记_19:Java-GUI_第19张图片

 

 

8、Java-GUI(键盘事件)

在学习鼠标事件之后,键盘事件也很简单,我们仍然在按钮组件上来完成。此时,添加监听器的方法是addKeyListener(KeyListener l)。还是一样的思路,我们查阅KeyListener接口里面封装的内容,发现,有keyPressed(KeyEvent e)、keyReleased(KeyEvent e)和keyTyped(KeyEvent e)方法,因此它一定有适配器类来方便我们建立监听器对象。还有就是当键盘监听器接收到事件对象e,这个e中也封装很多的内容,通过查阅KeyEvent类的api,我们知道里面有非静态的char getkeyChar()(返回的是按下的键所对应的字符)和int getKeyCode()(返回的是按下的键所对应字符的整数,这个不用记,KeyEvent已经将它们都封装好了,如整型字段static int VK_Y,它就是一个整型常量),还有静态的String getkeyText(int keyCode)。下面我们通过监听按下的动作来演示。代码如下:

import java.awt.*;

import java.awt.event.*;

class MouseAndKeyDemo1

{

private Frame f;

private Button but;

MouseAndKeyDemo1()

{

init();

}

 

public void init()

{

f=new Frame("my frame");

f.setBounds(100,200,300,400);

f.setLayout(new FlowLayout());

 

but=new Button("my button");

 

f.add(but);

 

myEvent();

 

f.setVisible(true);

}

public void myEvent()

{

f.addWindowListener(new WindowAdapter()

{

public void windowClosing(WindowEvent e)

{

System.exit(0);

}

});

 

but.addKeyListener(new KeyAdapter()

{

public void keyPressed(KeyEvent e)

{

System.out.println(e.getKeyChar()+"....."+e.getKeyCode());

}

});

}

 

public static void main(String[] args)

{

new MouseAndKeyDemo1();

}

}

编译运行后,结果如下图所示:

 

我们可以看到,在按钮周围有一个虚线框,这表示这个按钮是当前事件源。因此,这时我们不断敲击键盘,结果如下如所示:

 

可是当你按下shift键的时候,结果又是什么呢?看下图:

 [置顶] JavaSE学习笔记_19:Java-GUI_第20张图片

这个时候,我们通过运行结果,我们就不知道我们到底按下的是什么键了。因此如果我们想获取键的文本,可以通过调用getKeyText(int keyCode)方法,核心代码如下:

but.addKeyListener(new KeyAdapter()

{

public void keyPressed(KeyEvent e)

{

//System.out.println(e.getKeyChar()+"....."+e.get //KeyCode());

System.out.println(KeyEvent.getKeyText(e.getKeyCo de())+"....."+e.getkeyCode());

}

});

运行结果如下图所示:

 [置顶] JavaSE学习笔记_19:Java-GUI_第21张图片

 

接下来,我们想一按Enter键,程序就结束。核心代码如下:

but.addKeyListener(new KeyAdapter()

{

public void keyPressed(KeyEvent e)

{

//System.out.println(e.getKeyChar()+"....."+e.get //KeyCode());

//System.out.println(KeyEvent.getKeyText(e.getKey  //Code())+"....."+e.getkeyCode());

 

if(e.getKeyCode()==VK_ENTER)

System.exit(0);

}

});

现在我们想通过组合键(Ctr+Enter)来实现结束程序的功能,这时候,KeyEvent类中并没有对应的功能可以让我们调用,因此我们可以查找它的父类InputEvent,它里边有一个功能boolean isControlDown(),是用来判断ctl是否被按下。核心代码实现如下:

but.addKeyListener(new KeyAdapter()

{

public void keyPressed(KeyEvent e)

{

if(e.isControlDown()&&e.getKeyCode()==KeyEvent.VK_ENTER)

System.out.println("ctrl+Enter is run");

}

});

编译运行后,当按下Ctrl不放,再按Enter键后,结果如下图所示:

 [置顶] JavaSE学习笔记_19:Java-GUI_第22张图片[置顶] JavaSE学习笔记_19:Java-GUI_第23张图片

 

拓展:现在创建一个TextField对象。文本框中只能添加数字。完整代码如下:

import java.awt.*;

import java.awt.event.*;

class MouseAndKeyDemo1

{

private Frame f;

private Button but;

private TextField tf;

MouseAndKeyDemo1()

{

init();

}

 

public void init()

{

f=new Frame("my frame");

f.setBounds(100,200,300,400);

f.setLayout(new FlowLayout());

 

but=new Button("my button");

tf=new TextField(20);//文本框的长度为20列。

f.add(tf);

f.add(but);

 

myEvent();

 

f.setVisible(true);

}

public void myEvent()

{

f.addWindowListener(new WindowAdapter()

{

public void windowClosing(WindowEvent e)

{

System.exit(0);

}

});

 

but.addKeyListener(new KeyAdapter()

{

public void keyPressed(KeyEvent e)

{

if(e.isControlDown()&&e.getKeyCode()==KeyEvent.VK_ENTER)

System.out.println("ctrl+Enter is run");

}

});

/*

确定事件源,确定监听器,确定监听的动作,确定事 件处理方式。

这里要知道的就是,监听的组件和处理方式中处理的 对象可能不一样,就比如说,我们在文本框中填写内 容,我们要实现的是,当我们一点击按钮,文本框中 的内容被打印出来。

 

那么这里监听的组件是按钮,处理方式中处理的对象 就是文本框,两个不是同一个组件。

*/

tf.addKeyListener(new KeyAdapter()

{

public void keyPressed(KeyEvent e)

{

int code=e.getKeyCode();

if(!(code>=KeyEvent.VK_0&&code<=KeyEvent.VK_9))

System.out.println(code+"....非法的");

}

});

}

 

public static void main(String[] args)

{

new MouseAndKeyDemo1();

}

}

编译运行后,往文本框中输入一些字符,结果如下图所示:

 [置顶] JavaSE学习笔记_19:Java-GUI_第24张图片

通过结果图,我们发现,明明d是非法的,但还是进入到文本框中去了。我们的想法是:按可以,但是不让进。其实输入是一个连串事件,你按下和这个进入到文本框中是一个连续事件,而我判断的时候,如果不符合,可以不让它进入到文本框里边去,而直接把这个进入到文本框中的这个事件取消掉。这时,KeyEvent类里边没有相应的功能可以实现,这时找它的父类InputEvent,里边有一个consume(),使用此事件,以便不会按照默认的方式由产生此事件的源代码来处理事件。默认的话,即使不合法b也会进入,因为它们是连串事件,现在不按照默认,则不会进去。

核心代码如下:

tf.addKeyListener(new KeyAdapter()

{

public void keyPressed(KeyEvent e)

{

int code=e.getKeyCode();

if(!(code>=KeyEvent.VK_0&&code<=KeyEvent.VK_9))

{

System.out.println(code+"....非法的");

e.consume();

}

}

});

编译运行后,结果如下图所示:

 

再继续按合法的字符,结果如下:

[置顶] JavaSE学习笔记_19:Java-GUI_第25张图片 

 

 

9、Java-GUI(列出指定目录)

本次学习中,我们将要实现“列出指定目录内容”的功能,这个功能就好像我们windows中文件查找,我们在文本对话框中的地址栏输入指定的目录点击“转到”,将会列出该目录下的所有内容。现在我们将一步一步完成。

第一步:将文本框中内容填充到文本域中。代码如下:

import java.awt.*;

import java.awt.event.*;

class MyWindowDemo

{

private Frame f;

private Button b;

private TextField tf;

private TextArea ta;

 

MyWindowDemo()

{

init();

}

 

public void init()

{

f=new Frame("my frame");

b=new Button("转到");

tf=new TextField(40);

ta=new TextArea(25,70);

 

f.setBounds(200,300,600,700);

f.setLayout(new FlowLayout());

 

f.add(tf);

f.add(b);

f.add(ta);

 

myEvent();

 

f.setVisible(true);

}

 

private void myEvent()

{

f.addWindowListener(new WindowAdapter()

{

public void windowClosing(WindowEvent e)

{

System.exit(0);

}

});

 

b.addActionListener(new ActionListener()

{

public void actionPerformed(ActionEvent e)

{

/*

实现功能:在文本框中输入内容,让后点击按钮,

文本框中的内容就在文本域中出现,而文本框被 清空。

*/

 

/*

调用Textfield的父类TextCompon中的方法:

getText()来获取文本框组件tf中的内容。

*/

String text=tf.getText();

 

/*

调用TextArea的父类TextCompon中的方法:

setText()来将此文本域组件显示的文本

设置为指定文本。

*/

ta.setText(text);

 

/*清空文本框*/

tf.setText("");

 

}

});

}

public static void main(String[] args)

{

new MyWindowDemo();

}

}

编译运行后的逐步结果图如下:

 [置顶] JavaSE学习笔记_19:Java-GUI_第26张图片

 [置顶] JavaSE学习笔记_19:Java-GUI_第27张图片

 [置顶] JavaSE学习笔记_19:Java-GUI_第28张图片

 

 

 

第二步:现在实现功能:在文本框中输入指定的目录,文本域中出现目录下的对应内容。代码如下:

import java.awt.*;

import java.awt.event.*;

import java.io.*;

class MyWindowDemo

{

private Frame f;

private Button b;

private TextField tf;

private TextArea ta;

 

MyWindowDemo()

{

init();

}

 

public void init()

{

f=new Frame("my frame");

b=new Button("转到");

tf=new TextField(40);

ta=new TextArea(25,70);

 

f.setBounds(200,300,600,700);

f.setLayout(new FlowLayout());

 

f.add(tf);

f.add(b);

f.add(ta);

 

myEvent();

 

f.setVisible(true);

}

 

private void myEvent()

{

f.addWindowListener(new WindowAdapter()

{

public void windowClosing(WindowEvent e)

{

System.exit(0);

}

});

 

b.addActionListener(new ActionListener()

{

public void actionPerformed(ActionEvent e)

{

String dirPath=tf.getText();

 

/*

用到io流中的一个类:File。

文件和目录路径名的抽象表示形式。

*/

//将dirPath封装成一个文件对象,

//这样才可以list。

 

//通过将给定路径名字符串

//转换为抽象路径名来创建

//一个新 File 实例。

File dir=new File(dirPath);

if(dir.exists()&&dir.isDirectory())

{

String names[] =dir.list();

for(String name:names)

{

ta.setText(name+"\r\n");

}

}

}

});

}

public static void main(String[] args)

{

new MyWindowDemo();

}

}

编译运行后,发现,不论指定什么目录,文本域中都只有一条内容。这是因为,我们遍历一个写入一个,前一条内容被后面一条内容覆盖掉了。我们可以用一个容器先将它存起来。一起写入。给力的是,这个功能TextArea已经把我们完成了,在它里边已经有了一个对应方法append(),将给定文本追加到文本区的当前文本。核心代码如下:

for(String name:names)

{

ta.setText(name+"\r\n");

}

编译运行后结果如下:

 [置顶] JavaSE学习笔记_19:Java-GUI_第29张图片

 

这时我们将文本框中的内容指定为F:\,结果如下图所示:

 

我们发现,不同的f:\路径下的内容被添加在了c:\路径下内容的后面。因此,我们要记得清空,核心代码如下:

if(dir.exists()&&dir.isDirectory())

{

ta.setText("");

String names[] =dir.list();

  for(String name:names)

 {

ta.append(name+"\r\n");

 }

}

 

 

10、Java-GUI(对话框)

在上一次的“列出指定目录内容”的学习中,我们其实还有一个问题没有解决,那就是当我们在文本框中指定一个不存在的目录时,我们点击按钮并没有什么现象发生。这是因为我们只有了if语句,而没有考虑到else的情况。那么我们现在将提供几种方法。温馨提示:代码中加粗部分是解决问题的关键。

方法一:

import java.awt.*;

import java.awt.event.*;

import java.io.*;

class MyWindowDemo1

{

private Frame f;

private TextField tf;

private Button but;

private TextArea ta;

 

MyWindowDemo1()

{

init();

}

 

public void init()

{

f=new Frame("my frame");

but=new Button("转到");

tf=new TextField(60);

ta=new TextArea(40,80);

 

f.setBounds(100,200,500,600);

f.setLayout(new FlowLayout());

 

f.add(tf);

f.add(but);

f.add(ta);

 

myEvent();

 

f.setVisible(true);

}

 

private void myEvent()

{

f.addWindowListener(new WindowAdapter()

{

public void windowClosing(WindowEvent e)

{

System.exit(0);

}

});

 

but.addActionListener(new ActionListener()

{

public void actionPerformed(ActionEvent e)

{

String dirPath=tf.getText();

 

File dir=new File(dirPath);

 

if(dir.exists()&&dir.isDirectory())

{

ta.setText("");

 

String[] names=dir.list();

 

for(String name:names)

{

ta.append(name+"\r\n");

tf.setText("");

}

}

else

{

tf.setText("");

System.out.println("指定目录不存在,请重新输入!");

}

}

});

}

 

public static void main(String[] args)

{

new MyWindowDemo1();

}

}

编译运行后,结果图如下:

 [置顶] JavaSE学习笔记_19:Java-GUI_第30张图片

点击“转到”按钮:

 

 

但是,实际开发的软件,用户体验的时候,并没有什么控制台可以来显示。因此有:

 

方法二:

import java.awt.*;

import java.awt.event.*;

import java.io.*;

class MyWindowDemo1

{

private Frame f;

private TextField tf;

private Button but;

private TextArea ta;

 

MyWindowDemo1()

{

init();

}

 

public void init()

{

f=new Frame("my frame");

but=new Button("转到");

tf=new TextField(50);

ta=new TextArea(40,80);

 

f.setBounds(100,200,500,600);

f.setLayout(new FlowLayout());

 

f.add(tf);

f.add(but);

f.add(ta);

 

myEvent();

 

f.setVisible(true);

}

 

private void myEvent()

{

f.addWindowListener(new WindowAdapter()

{

public void windowClosing(WindowEvent e)

{

System.exit(0);

}

});

 

but.addActionListener(new ActionListener()

{

public void actionPerformed(ActionEvent e)

{

String dirPath=tf.getText();

 

File dir=new File(dirPath);

 

if(dir.exists()&&dir.isDirectory())

{

ta.setText("");

 

String[] names=dir.list();

 

for(String name:names)

{

ta.append(name+"\r\n");

tf.setText("");

}

}

else

{

ta.setText("指定路径不存在,请重新输入!");

tf.setText("");

}

}

});

}

 

public static void main(String[] args)

{

new MyWindowDemo1();

}

}

编译运行后,结果图如下:

 [置顶] JavaSE学习笔记_19:Java-GUI_第31张图片

点击“转到”按钮:

 [置顶] JavaSE学习笔记_19:Java-GUI_第32张图片

但是,这种方法还是不是很完善,我们想要windows中的一样,当指定路径不存在的时候,会出现一个提示对话框。因此有:

 

方法三:

用到Window类的子类Dialog。Dialog中一般有提示信息,但是文字是不能直接加在组件上的,想到Label,它可以封装文字,然后将Label对象加到Dialog中。注意Dialog的默认布局是边界布局,因此需指定为流式布局。看一下Dialog的构造函数:Dialog(Frame owner,String title, boolean modal) :构造一个最初不可见的 Dialog,它带有指定的所有者 Frame、标题和模式。模式是指:如果为true,表示一定要操作对话框,否则窗体不能操作,如果为false,表示可以不操作对话框,可以去操作窗体。

Dialog因为也是Window的子类,因此和Frame一样设置。也会用到父类Window中的setBounds()、setVisible()等方法来对自身进行一些基本设置。

Label的构造函数:Label() 构造一个空标签。还有类中的setText()方法也会用到。setText(String text) 将此标签的文本设置为指定的文本。

import java.awt.*;

import java.awt.event.*;

import java.io.*;

class MyWindowDemo1

{

private Frame f;

private TextField tf;

private Button but;

private TextArea ta;

 

private Dialog d;

private Label lab;

private Button but1;

 

MyWindowDemo1()

{

init();

}

 

public void init()

{

f=new Frame("my frame");

but=new Button("转到");

tf=new TextField(50);

ta=new TextArea(40,80);

 

f.setBounds(100,200,600,700);

f.setLayout(new FlowLayout());

 

f.add(tf);

f.add(but);

f.add(ta);

 

 

//对话框的初始化。

d=new Dialog(f,"提示信息",true);

d.setBounds(100,200,250,200);

d.setLayout(new FlowLayout());

 

lab=new Label();

d.add(lab);

but1=new Button("确定");

d.add(but1);

 

 

myEvent();

 

f.setVisible(true);

 

 

}

 

private void myEvent()

{

f.addWindowListener(new WindowAdapter()

{

public void windowClosing(WindowEvent e)

{

System.exit(0);

}

});

 

but.addActionListener(new ActionListener()

{

public void actionPerformed(ActionEvent e)

{

String dirPath=tf.getText();

 

File dir=new File(dirPath);

 

if(dir.exists()&&dir.isDirectory())

{

ta.setText("");

 

String[] names=dir.list();

 

for(String name:names)

{

ta.append(name+"\r\n");

tf.setText("");

}

}

else

{

/*

Dialog d;

d=new Dialog(f,"提示信息",true);

d.setBounds(100,200,250,200);

d.setLayout(new FlowLayout());

 

Button but1;

but1=new Button("确定");

d.add(but1);

 

Label lab;

lab=new Label();

lab.setText("您输入的信息"+dirPath+"错误,请重新输入!");

d.add(lab);

 

d.setVisible(true);

*/

lab.setText("您输入的信息"+dirPath+"错误,请重新输入!");

d.setVisible(true);

 

}

}

});

d.addWindowListener(new WindowAdapter()

{

public void windowClosing(WindowEvent e)

{

d.setVisible(false);

}

});

 

but1.addActionListener(new ActionListener()

{

public void actionPerformed(ActionEvent e)

{

d.setVisible(false);

}

});

}

 

public static void main(String[] args)

{

new MyWindowDemo1();

}

}

编译运行后,结果图如下所示:

 

点击“确定”按钮或者对话框的关闭按钮:

 [置顶] JavaSE学习笔记_19:Java-GUI_第33张图片

 

拓展:现在想实现我们在文本框这种指定目录,按“回车”键之后,如果路径存在,则文本域中会出现内容;如果路径不存在,则会弹出对话框。而不用在去点击“转到”按钮。

import java.awt.*;

import java.awt.event.*;

import java.io.*;

class MyWindowDemo1

{

private Frame f;

private TextField tf;

private Button but;

private TextArea ta;

 

private Dialog d;

private Label lab;

private Button but1;

 

MyWindowDemo1()

{

init();

}

 

public void init()

{

f=new Frame("my frame");

but=new Button("转到");

tf=new TextField(50);

ta=new TextArea(40,80);

 

f.setBounds(100,200,600,700);

f.setLayout(new FlowLayout());

 

f.add(tf);

f.add(but);

f.add(ta);

 

 

//对话框的初始化。

d=new Dialog(f,"提示信息",true);

d.setBounds(100,200,250,200);

d.setLayout(new FlowLayout());

 

lab=new Label();

d.add(lab);

but1=new Button("确定");

d.add(but1);

 

 

myEvent();

 

f.setVisible(true);

 

 

}

 

private void myEvent()

{

f.addWindowListener(new WindowAdapter()

{

public void windowClosing(WindowEvent e)

{

System.exit(0);

}

});

 

tf.addKeyListener(new KeyAdapter()

{

public void keyPressed(KeyEvent e)

{

if(e.getKeyCode()==KeyEvent.VK_ENTER)

{

String dirPath=tf.getText();

 

File dir=new File(dirPath);

 

if(dir.exists()&&dir.isDirectory())

{

ta.setText("");

 

String[] names=dir.list();

 

for(String name:names)

{

ta.append(name+"\r\n");

//tf.setText("");

}

}

else

{

tf.setText("");

lab.setText("您输入的信息"+dirPath+"错误,请重新输入!");

d.setVisible(true);

}

}

}

});

 

but.addActionListener(new ActionListener()

{

public void actionPerformed(ActionEvent e)

{

String dirPath=tf.getText();

 

File dir=new File(dirPath);

 

if(dir.exists()&&dir.isDirectory())

{

ta.setText("");

 

String[] names=dir.list();

 

for(String name:names)

{

ta.append(name+"\r\n");

//tf.setText("");

}

}

else

{

tf.setText("");

lab.setText("您输入的信息"+dirPath+"错误,请重新输入!");

d.setVisible(true);

}

}

});

d.addWindowListener(new WindowAdapter()

{

public void windowClosing(WindowEvent e)

{

d.setVisible(false);

}

});

 

but1.addActionListener(new ActionListener()

{

public void actionPerformed(ActionEvent e)

{

d.setVisible(false);

}

});

}

 

public static void main(String[] args)

{

new MyWindowDemo1();

}

}

代码优化:

import java.awt.*;

import java.awt.event.*;

import java.io.*;

class MyWindowDemo1

{

private Frame f;

private TextField tf;

private Button but;

private TextArea ta;

 

private Dialog d;

private Label lab;

private Button but1;

 

MyWindowDemo1()

{

init();

}

 

public void init()

{

f=new Frame("my frame");

but=new Button("转到");

tf=new TextField(50);

ta=new TextArea(40,80);

 

f.setBounds(100,200,600,700);

f.setLayout(new FlowLayout());

 

f.add(tf);

f.add(but);

f.add(ta);

 

 

//对话框的初始化。

d=new Dialog(f,"提示信息",true);

d.setBounds(100,200,250,200);

d.setLayout(new FlowLayout());

 

lab=new Label();

d.add(lab);

but1=new Button("确定");

d.add(but1);

 

 

myEvent();

 

f.setVisible(true);

 

 

}

 

private void myEvent()

{

f.addWindowListener(new WindowAdapter()

{

public void windowClosing(WindowEvent e)

{

System.exit(0);

}

});

 

tf.addKeyListener(new KeyAdapter()

{

public void keyPressed(KeyEvent e)

{

if(e.getKeyCode()==KeyEvent.VK_ENTER)

{

showDir();

}

}

});

 

but.addActionListener(new ActionListener()

{

public void actionPerformed(ActionEvent e)

{

showDir();

}

});

d.addWindowListener(new WindowAdapter()

{

public void windowClosing(WindowEvent e)

{

d.setVisible(false);

}

});

 

but1.addActionListener(new ActionListener()

{

public void actionPerformed(ActionEvent e)

{

d.setVisible(false);

}

});

}

 

private void showDir()

{

String dirPath=tf.getText();

 

File dir=new File(dirPath);

 

if(dir.exists()&&dir.isDirectory())

{

ta.setText("");

 

String[] names=dir.list();

 

for(String name:names)

{

ta.append(name+"\r\n");

}

}

else

{

tf.setText("");

lab.setText("您输入的信息"+dirPath+"错误,请重新输入!");

d.setVisible(true);

}

}

public static void main(String[] args)

{

new MyWindowDemo1();

}

}

 

11、Java-GUI(菜单)

什么是菜单:

 [置顶] JavaSE学习笔记_19:Java-GUI_第34张图片

一般步骤:

s1:新建一个窗口

Frame f=new Frame("演示");

s2:新建一个菜单栏

MenuBar mb=new MenuBar();

s3:新建一个菜单

Menu m=new Menu("文件");

s4:新建一个菜单项

MenuItem mi=new MenuItem("打开");

 

s5:将窗口和菜单栏关联

f.setMenuBar();

s6:将菜单项添加进菜单

m.add(mi);

s7:将菜单添加进菜单栏

mb.add(m);

 

 

 

子菜单的效果:

 [置顶] JavaSE学习笔记_19:Java-GUI_第35张图片

一般步骤:

s1:新建一个窗口

Frame f=new Frame("演示");

s2:新建一个菜单栏

MenuBar mb=new MenuBar();

s3:新建一个菜单

Menu m=new Menu("文件");

s4:新建一个子菜单

Menu subm=new Menu("打开");

 

s5:将窗口和菜单栏关联

f.setMenuBar();

s6:将子菜单添加进菜单

m.add(subm);

s7:将菜单添加进菜单栏

mb.add(m);

 

 

示例:

import java.awt.*;

import java.awt.event.*;

class MyMenuDemo

{

public static void main(String[] args)

{

new MyMenu();

}

}

class MyMenu

{

private Frame f;

private MenuBar mb;

private Menu m;

private MenuItem mi;

MyMenu()

{

init();

}

public void init()

{

f=new Frame();

mb=new MenuBar();

m=new Menu("文件");

mi=new MenuItem("退出");

 

f.setLayout(new FlowLayout());

f.setBounds(200,100,500,600);

 

m.add(mi);

mb.add(m);

f.setMenuBar(mb);

 

myEvent();

 

f.setVisible(true);

}

public void myEvent()

{

f.addWindowListener(new WindowAdapter()

{

public void windowClosing(WindowEvent e)

{

System.exit(0);

}

});

 

mi.addActionListener(new ActionListener()

{

public void actionPerformed(ActionEvent e)

{

System.exit(0);

}

});

}

 

}

 

 

 

12、Java-GUI(打开文件)

我们现在想要的一个效果就是像windows中的一样,我们点击文件菜单下面的打开菜单项,可以蹦出来一个文件对话框,我们可以选择文件打开,然后文件的内容在文本域中显

示出来。

 

ps:

① FileDialog(Dialog parent,String title,int mode):创建一个具有指定标题的文件对话框窗口,用于加载或保存文件。

 

mode可以取值:FileDialog.LOAD:表示打开文件

      FileDialog.SAVE:表示保存文件

② String getDirectory():获取选择的文件的所在路径。

③ String getFile():获取选择的文件的名字。

 

 

示例:

import java.awt.*;

import java.awt.event.*;

import java.io.*;

class MyMenu

{

private FileDialog openDia;

private TextArea ta;

private Frame f;

private MenuBar bar;

private Menu fileMenu ;

private MenuItem openItem ,saveItem,closeItem;

MyMenu()

{

init();

}

public void init()

{

f=new Frame();

bar=new MenuBar();

fileMenu=new Menu("文件");

openItem=new MenuItem("打开");

saveItem=new MenuItem("保存");

closeItem=new MenuItem("关闭");

 

openDia=new FileDialog(f,"我要打开",FileDialog.LOAD);

ta=new TextArea();

 

f.setBounds(100,200,600,700);

 

fileMenu.add(openItem);

fileMenu.add(saveItem);

fileMenu.add(closeItem);

bar.add(fileMenu);

 

f.setMenuBar(bar);

f.add(ta);

 

myEvent();

 

f.setVisible(true);

}

public void myEvent()

{

f.addWindowListener(new WindowAdapter()

{

public void windowClosing(WindowEvent e)

{

System.exit(0);

}

});

 

closeItem.addActionListener(new ActionListener()

{

public void actionPerformed(ActionEvent e)

{

System.exit(0);

}

});

 

openItem.addActionListener(new ActionListener()

{

public void actionPerformed(ActionEvent e)

{

openDia.setVisible(true);

String dirPath=openDia.getDirectory();

String fileName=openDia.getFile();

 

System.out.println(dirPath+"::"+fileName);

 

if(dirPath==null||fileName==null)

return;

ta.setText("");

 

File f=new File(dirPath,fileName);

 

try

{

BufferedReader bufr=new BufferedReader(new FileReader(f));

 

String line=null;

 

while((line=bufr.readLine())!=null)

{

ta.append(line+"\r\n");

}

 

bufr.close();

}

catch (IOException ex)

{

throw new RuntimeException("读取失败");

}

 

}

});

}

public static void main(String[] args)

{

new MyMenu();

}

}

 

13、Java-GUI(保存文件)

首先,我们得明白一点,在windows中,我们新建一个文件时,点击保存会弹出一个对话框;当我们对已存在的文件修改,点击保存不会弹出对话框。现在我们想用java语言来实现这个功能。

 

//需求:将文本域中内容保存成一个文本文件。

import java.awt.*;

import java.awt.event.*;

import java.io.*;

class MyMenu

{

private FileDialog openDia;

private FileDialog saveDia;

private File file;

private TextArea ta;

private Frame f;

private MenuBar bar;

private Menu fileMenu ;

private MenuItem openItem ,saveItem,closeItem;

MyMenu()

{

init();

}

public void init()

{

f=new Frame();

bar=new MenuBar();

fileMenu=new Menu("文件");

openItem=new MenuItem("打开");

saveItem=new MenuItem("保存");

closeItem=new MenuItem("关闭");

 

openDia=new FileDialog(f,"我要打开",FileDialog.LOAD);

saveDia=new FileDialog(f,"我要保存",FileDialog.SAVE);

ta=new TextArea();

 

f.setBounds(100,200,600,700);

 

fileMenu.add(openItem);

fileMenu.add(saveItem);

fileMenu.add(closeItem);

bar.add(fileMenu);

 

f.setMenuBar(bar);

f.add(ta);

 

myEvent();

 

f.setVisible(true);

}

public void myEvent()

{

f.addWindowListener(new WindowAdapter()

{

public void windowClosing(WindowEvent e)

{

System.exit(0);

}

});

 

closeItem.addActionListener(new ActionListener()

{

public void actionPerformed(ActionEvent e)

{

System.exit(0);

}

});

 

openItem.addActionListener(new ActionListener()

{

public void actionPerformed(ActionEvent e)

{

openDia.setVisible(true);

String dirPath=openDia.getDirectory();

String fileName=openDia.getFile();

 

System.out.println(dirPath+"::"+fileName);

 

if(dirPath==null||fileName==null)

return;

ta.setText("");

 

 file=new File(dirPath,fileName);

 

try

{

BufferedReader bufr=new BufferedReader(new FileReader(file));

 

String line=null;

 

while((line=bufr.readLine())!=null)

{

ta.append(line+"\r\n");

}

 

bufr.close();

}

catch (IOException ex)

{

throw new RuntimeException("读取失败");

}

 

}

});

 

saveItem.addActionListener(new ActionListener()

{

public void actionPerformed(ActionEvent e)

{

 

if(file==null)

{

saveDia.setVisible(true);

String dirPath=saveDia.getDirectory();

String fileName=saveDia.getFile();

 

System.out.println(dirPath+"::"+fileName);

 

file=new File(dirPath,fileName);

 

}

try

{

BufferedWriter bufw=new BufferedWriter(new FileWriter(file));

String text=ta.getText();

bufw.write(text);

bufw.flush();

bufw.close();

 

}

catch (IOException ex)

{

throw new RuntimeException("写入失败");

}

}

});

}

public static void main(String[] args)

{

new MyMenu();

}

}

 

14、Java-GUI(jar包双击执行)

之前,我们写的java程序,都需要在dos命令行中,输入

相关的命令才能执行,现在我们想把它变成一个类似于一个图标一样,双击就可以被执行。

 

图形化界面的另外一种执行方式:

就以下面程序为例:

package mymenu;

import java.awt.*;

import java.awt.event.*;

import java.io.*;

public class MyMenu

{

private FileDialog openDia;

private FileDialog saveDia;

private File file;

private TextArea ta;

private Frame f;

private MenuBar bar;

private Menu fileMenu ;

private MenuItem openItem ,saveItem,closeItem;

MyMenu()

{

init();

}

public void init()

{

f=new Frame();

bar=new MenuBar();

fileMenu=new Menu("文件");

openItem=new MenuItem("打开");

saveItem=new MenuItem("保存");

closeItem=new MenuItem("关闭");

 

openDia=new FileDialog(f,"我要打开",FileDialog.LOAD);

saveDia=new FileDialog(f,"我要保存",FileDialog.SAVE);

ta=new TextArea();

 

f.setBounds(100,200,600,700);

 

fileMenu.add(openItem);

fileMenu.add(saveItem);

fileMenu.add(closeItem);

bar.add(fileMenu);

 

f.setMenuBar(bar);

f.add(ta);

 

myEvent();

 

f.setVisible(true);

}

public void myEvent()

{

f.addWindowListener(new WindowAdapter()

{

public void windowClosing(WindowEvent e)

{

System.exit(0);

}

});

 

closeItem.addActionListener(new ActionListener()

{

public void actionPerformed(ActionEvent e)

{

System.exit(0);

}

});

 

openItem.addActionListener(new ActionListener()

{

public void actionPerformed(ActionEvent e)

{

openDia.setVisible(true);

String dirPath=openDia.getDirectory();

String fileName=openDia.getFile();

 

System.out.println(dirPath+"::"+fileName);

 

if(dirPath==null||fileName==null)

return;

ta.setText("");

 

 file=new File(dirPath,fileName);

 

try

{

BufferedReader bufr=new BufferedReader(new FileReader(file));

 

String line=null;

 

while((line=bufr.readLine())!=null)

{

ta.append(line+"\r\n");

}

 

bufr.close();

}

catch (IOException ex)

{

throw new RuntimeException("读取失败");

}

 

}

});

 

saveItem.addActionListener(new ActionListener()

{

public void actionPerformed(ActionEvent e)

{

 

if(file==null)

{

saveDia.setVisible(true);

String dirPath=saveDia.getDirectory();

String fileName=saveDia.getFile();

 

System.out.println(dirPath+"::"+fileName);

 

file=new File(dirPath,fileName);

 

}

try

{

BufferedWriter bufw=new BufferedWriter(new FileWriter(file));

String text=ta.getText();

bufw.write(text);

bufw.flush();

bufw.close();

 

}

catch (IOException ex)

{

throw new RuntimeException("写入失败");

}

}

});

}

public static void main(String[] args)

{

new MyMenu();

}

}

 

s1:打开dos命令行,切换到源文件目录下:

javac -d c:\myclass MyMenu.java(c:\myclass必须存在)

现象:在myclass文件中生成5个文件:MyMenu$1.class、

MyMenu$2.class、MyMenu$3.class、MyMenu$4.class、

MyMenu.class。

 

s2:切换到c:\myclass目录下:

jar -cvf my.jar mymenu

双击my.jar并不能执行。(原因jar包有很多个类文件,我们得告诉jar包那个类文件包含主函数,然后双击jar包,它才会自动去找告诉它的那个类文件去执行。)

 

s3:我们打开.jar,找到.MF文件,它里边都是一些配置信息,我们可以在里边添加Main-class,但是它不可以直接写,因此我们在C:\myclass目录下建立一个1.txt文件,在1.txt文件中写入:

Main-Class:空格+MyMenu.MyMenu+回车 (固定格式,英文)

然后在c:\myclass目录下:

jar -cvfm my.jar 1.txt mymenu

 

它有一个前提:必须在系统中注册过。

如果是xp:

工具-文件夹选项-文件类型-找到JAR类型-高级-有“open”操作(如果没有,可以自己新建一个)-编辑(让你填写“用于执行操作的应用程序”就是关联一下,比如:D:\jre6\bin\javaw.exe -jar,可能已经帮你填好了,是因为jdk的安装是双击安装的,而不是在别处拷过来的。)

 

如果是win7:

开始-运行-regedit:

|--HKEY_CLASSES_ROOT

|--Application

|--javaw.exe

|--shell

|--open

|--command

在右边的区域内选中,双击打开,编辑数值数据:D:\jre6\bin\javaw.exe -jar。

 

 

 

                                      2015-12-20至2015-12-25著

 

你可能感兴趣的:(GUI,事件监听,布局,监听适配器,Action事件)