GUI(图形化界面)
JAVA为GUI提供的对象都存在java.Awt和java.Swing的两个包中。
这里主要说Awt包中的内容。
Awt包
布局管理器
创建图形化界面的流程
2,对窗体进行基本设置。
比如大小——setSize(横,高);位置——setLocation(x,y);
3,定义组件。
4,将组件通过窗体的add方法添加到窗体中。
5,让窗体显示,通过setVisible(true)
/*
简单的实现图形化界面
Frame 是带有标题和边框的顶层窗口。
*/
import java.awt.*;
class AwtDemo
{
public static void main(String[] args)
{
//创建一个Frame窗口
Frame f=new Frame("测试窗口");
//设置窗口界面
f.setBounds(500,400,500,300);
f.setLayout(new FlowLayout());
f.add(new Button("关闭"));
//让窗口显示
f.setVisible(true);
}
}
事件处理
事件监听机制的特点:
1,事件源:就是awt包或者swing包中的那些图形界面组件。
2,事件:每一个事件源都有自己特有的对应事件和共性事件。
3,监听器:将可以触发某一个事件的动作(不只一个动作)都已经封装到了监听器中。。
4,事件处理。
2,通过事件源对象的addXXXListener()方法将监听器注册到该事件源上(注意监听器在java.awt.event包中)。
该方法中接收XXXListener(接口)的子类对象,或者XXXListener的子类XXXAdapter的子类对象。
一般用匿名内部类来表示,然后覆盖方法。
3,在覆盖方法的时候,方法的参数一般是XXXEvent类型的变量接收。
例子:
/*
简单的实现图形化界面并实现功能
*/
import java.awt.*;
import java.awt.event.*;
class AwtDemo
{
public static void main(String[] args)
{
//创建一个Frame窗口
Frame f=new Frame("测试窗口");
//设置窗口界面
f.setBounds(500,400,500,300);
f.setLayout(new FlowLayout());
Button b=new Button("关闭");
f.add(b);
//实现功能
f.addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
});
b.addMouseListener(new MouseAdapter()
{
public void mouseClicked(MouseEvent e)
{
System.exit(0);
}
});
//让窗口显示
f.setVisible(true);
}
}
一般把这种图形化界面封装成一个类,例:
import java.awt.*;
import java.awt.event.*;
class FrameClass
{
private Frame frame;
private Button button;
FrameClass()
{
init();
}
public void init()
{
frame=new Frame("我的窗口");
frame.setBounds(500,400,500,400);
frame.setLayout(new FlowLayout());
button=new Button("点我关闭");
frame.add(button);
//加载自定义事件
myEvent();
frame.setVisible(true);
}
//自定义事件
private void myEvent()
{
frame.addWindowListener(new WindowAdapter()
{
//覆盖方法
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
});
button.addMouseListener(new MouseAdapter()
{
public void mouseClicked(MouseEvent e)
{
System.exit(0);
}
});
button.addKeyListener(new KeyAdapter()
{
public void keyPressed(KeyEvent e)
{
//对着按钮按enter键则关闭
if(e.getKeyCode()==KeyEvent.VK_ENTER)
System.exit(0);
}
});
}
}
class FrameDemo
{
public static void main(String[] args)
{
new FrameClass();
}
}
注意:Frame可以添加addWindowListener,因为可以在Frame类中找的这个方法,Button类中也有自己的添加监听器方法:addActionListener(ActionListener l)
添加指定的动作侦听器,以接收发自此按钮的动作事件。之所以可以addKeyListener和addMouseListener是因为这两个方法是共性方法,放在父类Component类中的。
例:利用Button的addActionListener来实现关闭按钮,由于ActionListener方法比较少所以没有子类ActionAdapter。
button.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
System.exit(0);
}
});
练习:
/*
写一个类似我的电脑的地址栏的工具,可以输入路径,并列出路径下的文件
用到IO流技术
*/
import java.awt.*;
import java.awt.event.*;
import java.io.*;
class MyComputer
{
private Frame f;
private Button but,qd;//后面一个位弹出对话框的确定按钮
private TextField tf;
private TextArea ta;
//如果路径输入错误,弹出对话框
private Dialog log;
//对话框需要有一个标签,一个标签只显示一行只读文本。
private Label lab;
MyComputer()
{
init();
}
private void init()
{
f=new Frame("我的电脑");
f.setBounds(300,100,600,500);
f.setLayout(new FlowLayout());
qd=new Button("确定");
//参见dialog类构造函数(所属Frame,标题,是否锁定窗口不能切换)
//默认dialog不显示
log = new Dialog(f,"提示信息-self",true);
log.setBounds(500,400,300,200);
log.setLayout(new FlowLayout());
lab=new Label();
but=new Button("转到");
//构造具有指定列数的新空文本字段,用于输入地址栏。
tf=new TextField(60);
//构造一片文本区域,用于显示文件
ta = new TextArea(25,70);
f.add(tf);
f.add(but);
f.add(ta);
log.add(lab);
log.add(qd);
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)
{
showDir();
}
});
//此处要保证按回车就会显示路径下的文件,事件源不是按钮“转到”,而是TextField
tf.addKeyListener(new KeyAdapter()
{
public void keyPressed(KeyEvent e)
{
if(e.getKeyCode()==KeyEvent.VK_ENTER)
showDir();
}
});
//让dialog的叉有效,此方法是其父类Window的
log.addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
log.setVisible(false);
}
});
//让dialog的确定按键有效
qd.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
log.setVisible(false);
}
});
qd.addKeyListener(new KeyAdapter()
{
public void keyPressed(KeyEvent e)
{
if(e.getKeyCode()==KeyEvent.VK_ENTER)
log.setVisible(false);
}
});
}
//显示文件
private void showDir()
{
//TextField的父类有getText方法
String path=tf.getText();
File dir=new File(path);
if(dir.exists()&&dir.isDirectory())
{
//将TextArea清空
ta.setText("");
String[] names=dir.list();
for(String name:names)
ta.append(name+"\r\n");
}
else
{
String info="输入的路径:"+path+"错误";
lab.setText(info);
log.setVisible(true);
}
}
}
class MyComputerDemo
{
public static void main(String[] args)
{
new MyComputer();
}
}
菜单栏
从大到小分:MenuBar-->Menu-->MenuItem
创建菜单gui的例子(未实现按键):
/*
文件菜单(menu)
操作(menu)
打开(menuitem)
保存(menuitem)
关闭(menu)
*/
import java.awt.*;
import java.awt.event.*;
class MyMenu
{
private Frame f;
private MenuBar mb;
private Menu opFile,fileTool;
private MenuItem open,close,save;
MyMenu()
{
init();
}
private void init()
{
f=new Frame("我的窗口");
f.setBounds(300,100,500,400);
f.setLayout(new FlowLayout());
mb=new MenuBar();
fileTool=new Menu("文件");
opFile=new Menu("操作");
open=new MenuItem("打开");
save=new MenuItem("保存");
close=new MenuItem("关闭");
//MenuBar不是用add方法,而是用frame的setMenuBar方法
f.setMenuBar(mb);
mb.add(fileTool);
fileTool.add(opFile);
fileTool.add(close);
opFile.add(open);
opFile.add(save);
myEvent();
f.setVisible(true);
}
private void myEvent()
{
//待实现
}
}
class MenuDemo
{
public static void main(String[] args)
{
new MyMenu();
}
}
利用io技术完成上述例子的功能实现,达到类似记事本的功能。
/*
文件菜单(menu)
操作(menu)
打开(menuitem)
保存(menuitem)
关闭(menu)
完成所用功能,类似记事本。
注意:FileDialog 类显示一个对话框窗口,用户可以从中选择文件。
构造函数:FileDialog(Frame parent,String title,int mode)
parent - 对话框的所有者,mode - 对话框的模式,可以是 FileDialog.LOAD 或 FileDialog.SAVE
*/
import java.io.*;
import java.awt.*;
import java.awt.event.*;
class MyMenu
{
private Frame f;
private MenuBar mb;
private Menu opFile,fileTool;
private MenuItem open,close,save;
private FileDialog openDia,saveDia;
private TextArea ta;
private File file;
MyMenu()
{
init();
}
private void init()
{
f=new Frame("我的窗口");
f.setBounds(300,100,500,400);
//此处为了让文本框合适大小,不需要流式布局
//f.setLayout(new FlowLayout());
mb=new MenuBar();
fileTool=new Menu("文件");
opFile=new Menu("操作");
open=new MenuItem("打开");
save=new MenuItem("保存");
close=new MenuItem("关闭");
openDia=new FileDialog(f,"打开",FileDialog.LOAD);
saveDia=new FileDialog(f,"保存",FileDialog.SAVE);
ta=new TextArea();
//MenuBar不是用add方法,而是用frame的setMenuBar方法
f.setMenuBar(mb);
//添加组件
mb.add(fileTool);
fileTool.add(opFile);
fileTool.add(close);
opFile.add(open);
opFile.add(save);
f.add(ta);
myEvent();
f.setVisible(true);
}
private void myEvent()
{
f.addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
});
close.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
System.exit(0);
}
});
//完成打开功能
open.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
openDia.setVisible(true);
String path=openDia.getDirectory();
String FileName=openDia.getFile();
//接下来利用io技术读取并append到TextArea
//先判断路径与文件名是否存在,一定要判断。
//否则不选文件点取消会报空指针异常
if(path==null||FileName==null)
return;
ta.setText("");
file=new File(path,FileName);
//源:文件,目的:TextArea
BufferedReader bufr=null;
try
{
bufr=new BufferedReader(new FileReader(file));
String line=null;
while(null!=(line=bufr.readLine()))
{
ta.append(line+"\r\n");
}
}
catch (IOException ex)
{
throw new RuntimeException ("读取失败");
}
finally
{
try
{
bufr.close();
}
catch (IOException ex)
{
throw new RuntimeException ("关闭读取流失败");
}
}
}
});
//完成保存功能
save.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
//如果没有文件 才显示保存窗体
//比如之前保存过一次了,file已经new过了则不需要再new了
if(file==null||file.exists()==false)
{
saveDia.setVisible(true);
String path=saveDia.getDirectory();
String fileName=saveDia.getFile();
if(path==null || fileName==null)
return ;
file=new File(path,fileName);
}
//源:TextArea,目的:文件
BufferedWriter bufw=null;
try
{
bufw=new BufferedWriter(new FileWriter(file));
String text=ta.getText();
bufw.write(text);
bufw.flush();
}
catch (IOException ex)
{
throw new RuntimeException ("写入失败");
}
finally
{
try
{
bufw.close();
}
catch (IOException ex)
{
throw new RuntimeException ("关闭写入流失败");
}
}
}
});
}
}
class MenuDemo
{
public static void main(String[] args)
{
new MyMenu();
}
}
制作可以双击执行的jar包
1,将多个类封装到了一个包(package)中。(在文件头写上package XXXX)
带着包编译:javac -d 存放位置 java文件名,可将带主函数的类public,具体看需求。
2,定义一个jar包的配置信息。
定义一个文件a.txt 。文件内容内容为:
Main-Class:(空格)包名.类名(回车)
3,打jar包。
jar -cvfm my.jar a.txt 包名
4,通过winrar程序进行验证,查看该jar的配置文件中是否有自定义的配置信息。
5,通过工具--文件夹选项--文件类型--jar类型文件,通过高级,定义该jar类型文件的打开动作的关联程序。
jdk\bin\javaw.exe -jar