------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
GUI
1.什么是GUI?
通俗讲就是,原来没有GUI的时候,我们与计算机的交互就是通过那个黑框框,也就是DOS命令行,这种方式有很多弊端,比如不友好,不容易掌握,需要记住大量的命令等,这对普通用户来说是难以想象的,因为不可能每个人都花大量的时间去学习如何使用DOS。
因此出现了GUI,就像现在的计算机的操作系统基本都是图形界面的,当然了也有类似DOS命令行的,下面我们分析下这两种方式的区别。GUI的出现,无疑对计算机的普及起了难以想象的作用,我敢说如果没有GUI,那么就不可能像现在这样,计算机成为家电的一部分,而应该还是那些实验室,工作单位才有的工作用品。GUI使得人们操作计算机变得异常的简单,任何人都能使用计算机达到自己的目的。这就是GUI 的威力。
而DOS命令行则不然,我们可以想象一下,计算机的处理能力是有限的,对于人们来说GUI更适合绝大部分人的需求,但是我估计计算机更喜欢DOS这份“简单工作”吧,因为对于计算机来说,DOS命令行只占用很少一部分内存,而GUI不能,由于GUI需要大量描绘图形,也就需要占用大量的内存,对计算机来说,这可是个“重活”。因此GUI的电脑的速度要比DOS的要慢一些,这是无可厚非的。
2.Java中GUI涉及的包
javax.Swing:基于Awt,属轻量级组件,不依赖系统。(开发用)
Swing相对于Awt来说,更加的与平台无关,而Awt构建出的程序,在各个平台上的体现略有差别,这是因为它使用到了跟操作系统底层有关的东西,而Swing不同,Swing在每个系统下的表现都是一致的,因此开发中常用Swing。
3.Awt包体系
Component组件:
|--Container容器(通过add可以向自己内部添加组件):
|--Panel面板
|--Window窗口
|--Frame
|--Dialog
|--Button
|--Label
|--CheckBox
|--....
4.GUI基础知识点
流失布局:FlowLayout
边界布局:BorderLayout(Frame默认为此布局)
网格布局:GridLayout
网格包布局:GridBagLayout
卡片布局:CardLayout
创建窗体(每个窗体都在一个独立的线程中运行,因此只要有窗体未关,主线程不会结束):
1.创建frame对象
2.设置大小,位置,布局等
3.通过add添加组件
4.使用setVisible使窗口可见
重点:事件监听机制
特点:事件源,事件,监听器,事件处理
事件源:awt和swing那些组件。
事件:每一个事件源都有自己的对应事件和共性事件。
监听器:将可以触发某个事件的动作(不止一个)封装到监听器中。
监听器都是接口,通常它都有一个适配器来方便我们创建对象。
以上三者在java都已定义好了,只需使用其对象就可以了,我们要做的就是事件处理部分,也就是对产生的动作进行自定义处理。
当我们需要给组件添加监听器时,需要查阅组件类,看它支持哪种监听器。
共性事件(由于是组件共有的,因此定义在Component中):鼠标键盘事件,这些事件是每个组件都可以处理的。
当前持有焦点的组件才会响应事件,requestFocus()方法用于使组件获得焦点。
对话框:Dialog
菜单:MenuBar--Menu--MenuItem
jar包双击执行:
1.生成包,记得要Public一个主类
2.使用记事本写好配置信息(Main-Class:空格包名.main所在的class文件回车)
3.jar -cvfm jar包名 配置信息所在文件 包名
4.双击执行jar包
分析:当我们双击一个普通jar包时会报错,Main-Class错误,这是因为它要找到main方法在的class文件才能正确运行,因此需要使用配置信息告诉jar包main在哪里。
为什么可以双击执行呢?
这是因为jar后缀名文件与javaw程序相关联了,也就是说当我们打开一个jar时,系统就会使用javaw来打开,并运行。这个可以自己配置的,如果是安装版的java那么就已经配置好了。
5.GUI小练习
//创建GUI程序一般做法
//鼠标键盘事件测试
import java.awt.*;
import java.awt.event.*;
class FrameDemo
{
//定义所需组件引用
private Frame f;
private Button b,b2;
private Label l;
private TextField tf;
FrameDemo()
{
}
public void init()
{
//创建f,b并初始化
f=new Frame("窗体");
f.setBounds(100,100,300,300);
f.setLayout(new FlowLayout());
b=new Button("按钮");
b2=new Button("按钮2");
l=new Label("标签");
tf=new TextField(20);
//添加监听器方法
myEvent();
//将组件添加到窗体
f.add(b);
f.add(b2);
f.add(l);
f.add(tf);
f.setVisible(true);
}
private void myEvent()
{
//为窗口添加了一个对应事件
f.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
public void windowOpened(WindowEvent e)
{
System.out.println("window is open");
f.requestFocus();
}
});
//为按钮添加共性事件--鼠标事件
b.addMouseListener(new MouseAdapter(){
private int enterCount=1;
private int clickCount=1;
public void mouseEntered(MouseEvent e)
{
System.out.println("鼠标进入:"+enterCount++);
}
public void mouseClicked(MouseEvent e)
{
System.out.println("鼠标点击:"+clickCount++);
}
});
//鼠标移动事件
b.addMouseMotionListener(new MouseMotionAdapter(){
public void mouseDragged(MouseEvent e)//点击并拖动时触发
{
//得到鼠标的绝对坐标(相对屏幕左上角的坐标)减去窗体相对屏幕左上角的坐标
//就是鼠标相对窗体的坐标
b.setLocation(e.getXOnScreen()-f.getX(),e.getYOnScreen()-f.getY());
}
public void mouseMoved(MouseEvent e)
{
}
});
//鼠标滚轮事件
b.addMouseWheelListener(new MouseWheelListener(){
private int count=1;
public void mouseWheelMoved(MouseWheelEvent e)
{
count+=e.getWheelRotation();
b.setLabel(count+"");
}
});
//为按钮和Frame添加键盘事件,观察事件冒泡
b.addKeyListener(new KeyAdapter(){
public void keyPressed(KeyEvent e)
{
System.out.println("Button:"+e.getKeyChar()+".."+e.getKeyCode()+".."+e.getKeyText(e.getKeyCode())+
".."+e.getKeyLocation());
//alt+enter就关闭程序
if(e.getKeyCode()==KeyEvent.VK_ENTER&&e.isAltDown())
System.exit(0);
}
});
//窗口无法在有其他组件时获得焦点,因此无法响应动作
f.addKeyListener(new KeyAdapter(){
public void keyPressed(KeyEvent e)
{
System.out.println("Frame:"+e.getKeyChar()+".."+e.getKeyCode()+".."+e.getKeyText(e.getKeyCode())+
".."+e.getKeyLocation());
}
});
//为TestField添加键盘事件
tf.addKeyListener(new KeyAdapter(){
public void keyPressed(KeyEvent e)
{
int code=e.getKeyCode();
//这种写法无法作用于小键盘上的数字
//if(!(code>=KeyEvent.VK_0&&code<=KeyEvent.VK_9))
if(!((code>=KeyEvent.VK_0&&code<=KeyEvent.VK_9)||(code>=96&&code<=107)))
{
l.setText("非法字符");
e.consume();//这个是继承与InputEvent类,阻止事件的默认行为
}
else
l.setText("标签");
}
});
}
public static void main(String[] args)
{
new FrameDemo().init();
}
}
运行图:
/*
创建窗口:
1.创建Frame对象
2.设置其大小,位置,布局等。
3.使用add添加组件
4.setVisible使其可见
事件处理机制:
1.事件源
2.事件
3.监听器
4.事件处理
1,2,3均为java定义好的。
4为我们处理的内容。
*/
import java.awt.*;
import java.awt.event.*;//跟事件有关的awt子包
class MyBut extends Button
{
private int count=0;
MyBut(String label)
{
super(label);
}
public int getCount()
{
return count++;
}
}
class GUIDemo
{
public static void main(String[] args)
{
Frame f=new Frame("第一个java窗体");
f.setSize(300,300);//设置大小
f.setLocation(200,150);//设置位置,距离屏幕左边框和上边框的距离
f.setLayout(new GridLayout());//设置为流式布局
//向窗体中添加组件
/*
Button b=new Button("按钮");
b.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
System.out.println("点击按钮咯");
b.setLabel("点击");
}
});
f.add(b);
*/
//使用自定义button
MyBut b=new MyBut("按钮");
b.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
System.out.println("点击按钮咯");
b.setLabel("点击:"+b.getCount());
}
});
f.add(b);
f.add(new Label("标签"));
f.add(new TextArea());
//将事件源中添加监听器
//该方法需要传递一个实现了WindowListener接口的类对象
//但是该接口有7个方法,我们不是都想去实现,因此我们
//继承于WindowAdapter类,该类实现了7个方法,方法为空,
//我们只需覆盖该类中我们真正需要的方法即可
f.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e)
{
System.out.println("窗口正在关闭。。。。");
System.exit(0);
}
public void windowActivated(WindowEvent e)
{
System.out.println("窗口被激活。。。");
}
public void windowOpened(WindowEvent e)
{
System.out.println("窗口被打开。");
}
});
f.setVisible(true);//设置可见
}
}
运行图:
//GUI练习
import java.awt.*;
import java.awt.event.*;
import java.io.*;
class WindowTest
{
private Frame f;
private Button but;
private TextField tf;
private TextArea ta;
private Dialog dig;
private Label digLab;
private Button digBtn;
WindowTest(){}
public void init()
{
f=new Frame("列出指定目录内容");
f.setBounds(200,100,400,400);
f.setLayout(new FlowLayout());
tf=new TextField(20);
but=new Button("搜索");
ta=new TextArea(20,30);
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);
}
});
tf.addKeyListener(new KeyAdapter(){
public void keyPressed(KeyEvent e)
{
if(e.getKeyCode()==KeyEvent.VK_ENTER)
{
//用代码触发btn的被点击事件达到搜索效果,实现代码复用
but.click();
}
}
});
//按钮事件处理
//之所以使用动作监听器而不是鼠标监听器是因为我们使用键盘一样可以按下按钮
//因此使用动作监听器ActionListener
but.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
String dir=tf.getText();
File files=new File(dir);
if(files.isDirectory())
{
StringBuilder result=new StringBuilder();
for(String temp:files.list())
{
result.append(temp).append("\r\n");
}
//ta.setText(ta.getText()+result.toString());
ta.setText(result.toString());
}
else
{
dig=new Dialog(f,"路径错误",true);//true表示这是个模态对话框
digLab=new Label("路径错误:"+tf.getText());
digBtn=new Button("知道啦");
digBtn.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
dig.setVisible(false);
}
});
dig.add(digLab);
dig.add(digBtn);
dig.setBounds(300,300,150,100);
dig.setLayout(new FlowLayout());
dig.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e)
{
dig.setVisible(false);
}
});
dig.setVisible(true);
tf.setText("");
}
}
});
}
public static void main(String[] args)
{
new WindowTest().init();
}
}
运行图:
这里有个小问题:
为什么可以这样写?
fileDialog.setVisible(true);
String name=fielDialog.getFile();
我们知道,窗体运行于独立线程,那么当我们显示窗体后,立马就使用它的getFile方法此时能获取到该窗体的返回值吗?
如果是普通窗口,那是不可以的,但是对于模态窗口,它可以理解成阻塞式窗口,只要打开了它,必须操作完毕才能操作其他内容。
//测试菜单栏,菜单,菜单项的使用
//文件的打开和保存,另存为
//jar包双击执行
package mymenu;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
public class MenuDemo
{
private Frame f;
private MenuBar mb;
private TextArea ta;
private Menu file,edit;
private MenuItem open,save,saveAs,exit,cut,copy;
private Dialog dig,saveDig;
private Label digLab,saveLab;
private Button digBtn,sureBtn,cancelBtn;
private File tempFile;
private FileDialog openDia,saveAsDia;
MenuDemo()
{
init();
}
private void init()
{
f=new Frame("测试菜单");
mb=new MenuBar();
file=new Menu("file");
edit=new Menu("edit");
open=new MenuItem("open");
save=new MenuItem("save");
saveAs=new MenuItem("save as");
exit=new MenuItem("exit");
cut=new MenuItem("cut");
copy=new MenuItem("copy");
ta=new TextArea();
file.add(open);
file.add(save);
file.add(saveAs);
file.add(exit);
edit.add(cut);
edit.add(copy);
mb.add(file);
mb.add(edit);
f.setMenuBar(mb);
f.add(ta);
f.setBounds(200,20,900,700);
//f.setLayout(new FlowLayout());
//有文本区域设置为流式布局不合适,我们设为默认边界布局,让组件随着窗体大小而变化
myEvent();
f.setVisible(true);
}
private void myEvent()
{
f.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
});
exit.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
System.exit(0);
}
});
cut.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
showDig("cut","are you sure to cut?");
}
});
copy.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
showDig("copy","are you sure to copy?");
}
});
open.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
if(openDia==null)openDia=new FileDialog(f,"my open file",FileDialog.LOAD);//默认就是打开模式
openDia.setVisible(true);
//因为FileDialog为模态对话框,因此是阻塞式的,要想执行它后面的语句它肯定运行结束了。
String dir=openDia.getDirectory();
String fileName=openDia.getFile();
if(dir==null || fileName==null)return;
tempFile=new File(dir,fileName);
try
{
BufferedReader br=new BufferedReader(new FileReader(tempFile));
ta.setText("");
for(String line=br.readLine();line!=null;line=br.readLine())
{
ta.append(line);
ta.append("\r\n");
}
br.close();
}
catch (IOException ioe)
{
ioe.printStackTrace();
}
}
});
save.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
if(tempFile==null)return;
if(saveDig==null)
{
saveDig=new Dialog(f,"是否保存",true);
saveDig.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e)
{
saveDig.setVisible(false);
}
});
saveLab=new Label("are you sure to save this file?");
sureBtn=new Button("sure");
sureBtn.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
//点击确定按钮
try
{
BufferedWriter bw=new BufferedWriter(new FileWriter(tempFile));
bw.write(ta.getText());
bw.close();
}
catch (IOException ioe)
{
ioe.printStackTrace();
}
saveDig.setVisible(false);
}
});
cancelBtn=new Button("cancel");
cancelBtn.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
//点击取消按钮
saveDig.setVisible(false);
}
});
saveDig.add(saveLab);
saveDig.add(sureBtn);
saveDig.add(cancelBtn);
saveDig.setBounds(350,300,200,100);
saveDig.setLayout(new FlowLayout());
}
saveDig.setVisible(true);
}
});
saveAs.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
if(saveAsDia==null)saveAsDia=new FileDialog(f,"my save file",FileDialog.SAVE);//模式为保存
saveAsDia.setVisible(true);
String dir=saveAsDia.getDirectory();
String fileName=saveAsDia.getFile();
if(dir==null || fileName==null)return;
System.out.println(dir+"..."+fileName);
tempFile=new File(dir,fileName);
try
{
BufferedWriter bw=new BufferedWriter(new FileWriter(tempFile));
bw.write(ta.getText());
bw.close();
}
catch (IOException ioe)
{
ioe.printStackTrace();
}
}
});
}
private void showDig(String title,String labText)
{
if(dig==null)
{
dig=new Dialog(f,title);
dig.setBounds(300,200,150,100);
dig.setLayout(new FlowLayout());
dig.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e)
{
dig.setVisible(false);
}
});
}
else
dig.setTitle(title);
if(digLab==null)
{
digLab=new Label(labText);
dig.add(digLab);
}
else
digLab.setText(labText);
if(digBtn==null)
{
digBtn=new Button("知道啦");
digBtn.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
dig.setVisible(false);
}
});
dig.add(digBtn);
}
dig.setVisible(true);
}
public static void main(String[] args)
{
new MenuDemo();
}
}<strong>
</strong>
运行图:
6.GUI总结及心得
------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------