您的位置:首页 > 产品设计 > UI/UE

奋斗黑马程序员----Java GUI基础讲解

2013-04-12 15:25 218 查看
----------android培训java培训、期待与您交流! ----------

/**
* Java GUI基础讲解:
* 1 :GUI(图形用户界面)
* 2 :GUI之布局
* 3 :GUI之Frame
* 4 :列出制定目录的内容。
* 5 :菜单制作
* 6 :打开文件与保存文件
*/

/** 1 :GUI(图形用户界面)
*
* 两种和用户进行交互的界面:
*	  GUI:Graphical User Interface(图形用户接口),用图形的方式,来显示计算机
* 操作的界面,这样更方便更直观。
*	  CLI:Commend Line User Interface(命令行用户接口)。就是常见的DOS命令行操
* 作。需要记忆一些常用的命令,操作不直观。
*
* 举例:如创建文件夹,删除文件夹等。
*
* Java为GUI提供的对象都存在java.Awt和javax.Swing两个包中。
* Awt和Swing:
* 	java.Awt:Abstract Window ToolKit(抽象窗口工具包),需要调用本地系统方法实现功能。
* 属重量级控件。(有点依赖于平台,跨平台性不太好)
* 	java.Swing:在AWT的基础上,建立的一套图形界面系统,其中提供了更多的组件,
* 而且完全由Java实现。增强了移植性,属轻量级控件。 (用的多)
* 	eclipse用的不是二者,而是一个叫做SWT的包。
*
* 体系构成(常用的)
*component:组件
*|---Button:按钮
*|---Label:标签(组件需要文字支持,但是不能直接把文字放到组件上,就用了标签。用来封装文字。)
*|---Checkbox:复选框
*|---TextComponent:文本组件
*	|---TextArea:
*	|---TestField:
*
*|---Contianer:容器
*	|---Window:窗口
*		|---Frame:框架
*		|---Dialog:对话框
*			|---FileDialog:文件对话框。如,上传文件的。
*	|---Panel:面板
*
* Container:(有点特殊,作为一个组件,里面能添加组件。其他的不行)为容器,是一个特殊的组件,
*该组件中可以通过add方法添加其他组件进来。如,可以把button添加到Container里,反之不行。
*/

/** 2 :GUI之布局。
*
* 容器中组件的排序方式,就是布局。
* 常见的布局管理器:
* 	Flow Layout(流式布局管理器):默认是居中的。
* 		1.从左到右的顺序排列
* 		2.Panel默认的布局管理器
* 	BorderLayout(边界布局管理器)
* 		1.东。南,西,北,中
* 		2.Frame默认的布局管理器
* 	GridLayout(网格布局管理器)
* 		1.规则的矩阵
* 	GardLayout(卡片布局管理器)
* 		1.选项卡
* 	GridBahLayout(网络包布局管理器)
* 		1.非规则的矩阵。
*
* 窗体的默认布局为 BorderLayout。
*/

/** 3 :GUI之Frame
*
* 创建图形化界面思路:
* 	1.创建Frame窗体。
* 	2.对窗体进行基本设置。比如,大小,位置,布局==
* 	3.定义组件
* 	4.将组件通过窗体的add方法添加到窗体中。
* 	5.让窗体显示。setVisible(true). 最后一步。这样一个窗体就显现了。
*
* 此时创建的窗体还存在很多的问题:
* 	1.点击按钮,没有反应。
* 	2.可以最大化,和最小化,但是点击“关闭”,却不管用。
* 	==
*
*
**事件监听机制。
*
* dos命令行:
* 	delete删除的是文件夹下所有的内容。
* 	而rd删除的是文件夹
*
* 鼠标右键有许多操作,很方便,但是实现起来却很难。
*
* 做出的窗口无法关闭。是怎么回事呢?这里面涉及到一个问题:事件监听机制:
* 事件监听机制组成:
* 	事件源(组件)
* 	事件(event)
* 	监听器(Listener)
* 	事件处理(引发事件后处理方式)
*
* 事件源:就是awt包或者swing包中的哪些图形界面组件。
* 事件:每一个事件源都有自己的特有的对应事件和共性事件。
* 监听器:将可以触发某一个事件的动作(不止一个动作)都已经封装到了监听器中。
*
* 以上三者:在java中都已经定义好了。直接获取其对象来用就好了。
*    我们要做的是,就是对产生的动作进行处理就行了。(前三者开发的过程中,实例代
* 码是不需要写的。通过画布来完成)
*
* 理解案例:
*    1.金库密码锁:当有外部非正常的操作(如,撬,砸等)时,报警器(监听装置)就会
* 采取相应的处理方式。
*
*
*
**窗体事件--关闭动作
*
* 经查手册可知:WindowListener接口中有我们需要的方法,但是。
* class MyWin implements WindowListener
* {
*	 //如果要实现这个类,必须要覆盖里面的7个方法,可是我们只用到了其中的关闭动作。
*	 //其他的动作都没有用到,可是却必须复写。如此一来就显得很麻烦。
*	 //因此我们又找到了其子类WindowAdapter(抽象的,但是其方法却不是抽象的,防止其创建子类).
* }
*
* 因为WindowListener的子类WindowAdapter已经实现了WindowListener接口,
* 并覆盖了其中的所有方法,那么我们只要继承自WindowAdapter,覆盖我们需要的方法即可。
*
* public interface WindowListener extends EventListener
*    用于接收窗口事件的侦听器接口。旨在处理窗口事件的类要么实现此接口(及其包含的所有方
* 法),要么扩展抽象类 WindowAdapter(仅重写所需的方法)。然后使用窗口的 addWindowListener
* 方法将从该类所创建的侦听器对象向该 Window 注册。当通过打开、关闭、激活或停用、图标化或
* 取消图标化而改变了窗口状态时,将调用该侦听器对象中的相关方法,并将 WindowEvent 传递给
* 该方法。
*
* public abstract class WindowAdapter extends Object implements WindowListener,
* WindowStateListener, WindowFocusListener
*    接收窗口事件的抽象适配器类。此类中的方法为空。此类存在的目的是方便创建侦听器对象。
*    扩展此类可创建 WindowEvent 侦听器并为所需事件重写该方法。(如果要实现 WindowListener
* 接口,则必须定义该接口内的所有方法。此抽象类将所有方法都定义为 null,所以只需针对关
* 心的事件定义方法。)
*/
import java.awt.*;	//导入此包,只能添加窗体,但没有对应的处理动作
import java.awt.event.*;	//导入此包,可以为窗体添加效果(即时间监听)。玩窗体,此包必不可少。

public class AwtDemo {
public static void main(String[] args)
{
/**方法摘要:
* void setSize(int width, int height) 调整组件的大小,使其宽度为 width,高度为 height。
*
* (Component)  void setLocation(int x, int y) 将组件移到新位置。
*    x - 父级坐标空间中新位置左上角的 x 坐标
*    y - 父级坐标空间中新位置左上角的 y 坐标
*
* (Container)  void setLayout(LayoutManager mgr) 设置此容器的布局管理器。
*    FlowLayout() 构造一个新的 FlowLayout,它是居中对齐的,默认的水平和垂
* 直间隙是 5 个单位。
*
* (Container)   Component add(Component comp) 将指定组件追加到此容器的尾部。
*
* Button(String label) 构造一个带指定标签的按钮。
*/
Frame f = new Frame("my awt");
System.out.println("看到什么么?");

/*图形化界面是有另外的线程来控制的。如果想要让窗体可见。这个要放到最后。
* 2.看到窗体了。哈哈。但是太mini了。有点不爽。
*/

f.setSize(500,400);	//3.setSize(横坐标,纵坐标);	一般第一个都是横的,第二个都是纵的。

// 4.窗体每次出现的位置都是在左上角,有点不爽。那怎么自定义位置呢?
f.setLocation(300,200);	//定点距上边和左边的距离。

//6.调节按钮的方法。
f.setLayout(new FlowLayout());	//原来的按钮是全窗口的,加上这个之就会发生改变。

Button b = new Button("我是一个按钮");
f.add(b);
/*5.按钮有点大。怎么调节?
* 边界式布局。在Frame里调节。
* 用setLayout();调节。要放于button上面。
*/

/**
* 添加关闭动作。可用匿名内部类来代替。
* void addWindowListener(WindowListener l) 添加指定的窗口侦听器,以从此窗口接收窗口事件。
*   抽象类WindowAdapter继承WindowListener,并重写了父类中的所有方法,但是,WindowAdapter中
* 的所有方法却都不是抽象的,都有方法体,只不过方法体是null而已。
*/
//f.addWindowListener(new MyWin());
f.addWindowListener(new WindowAdapter()
{
/*
*    public void windowClosing(WindowEvent e)窗口正处在关闭过程中时调用。
* 此时可重写关闭操作。
*
*    public class WindowEvent extends ComponentEvent指示窗口状态改变的低级别事件。
* 当打开、关闭、激活、停用、图标化或取消图标化 Window 对象时,或者焦点转移到
* Window 内或移出 Window 时,由 Window 对象生成此低级别事件。
*
*    public static void exit(int status)终止当前正在运行的 Java 虚拟机。参数用作
* 状态码;根据惯例,非 0 的状态码表示异常终止。
*/
public void windowClosing(WindowEvent e)	//该动作最常见
{
System.out.println("这个匿名内部类的关闭方法");
System.exit(0);	//非0数字表示非正常关闭虚拟机
}
public void windowActivated(WindowEvent e)	//激活状态。即前置。
{
System.out.println("我活了。。。");
}
public void windowOpened(WindowEvent e)		//开启动作就一次。
{
System.out.println("我被打开了,哈哈哈");
}

}
);

//1.没有反应,什么都没有看到。也没有见窗体啊。f.setVisible(true);可以解决。
f.setVisible(true);

System.out.println("这次看到什么了?");

}
}

class MyWin extends WindowAdapter
{
public void windowClosing(WindowEvent e)
{
//System.out.println("Window closing"+e.toString());	//打印关闭的信息
System.out.println("只要你点了关闭,窗体就会关闭,不信你试试");
/*但是输出信息是在后面的,这也就意味着,这里面所有的操作都是在点击
* 关闭后才会出现的。
*/
System.exit(0);	//可以实现关闭的操作。
}
}

/**4 :列出制定目录的内容。
* 用到的内容:
* 1,一个窗体
* 2,按钮,文本框,文本域
* 3,对话框
* 4,label层
*
*
*/
import java.awt.*;
import java.awt.event.*;
import java.io.*;
public class MyWindow //extends Frame //继承Frame也可以。
{
private Frame f;
private TextField tf;
private Button but;
private TextArea ta;

private Dialog d;
/*   关于dialog的存在,如果用户的输入时正确的话,或窗体还没有加载完,此时
* dialog就没必要存在了。否则会浪费内存。
* dialog上面有一个按钮,还有些文字提示。
*/

private Label lab;	//把文字封装成对象,添加到组件上。组件里不能直接写文本。
private Button okBut;

MyWindow()
{
init();
}
public void init()
{
/*
* void setBounds(int x, int y, int width, int height) 移动组件并调整其大小。
*   x - 组件的新 x 坐标
*   y - 组件的新 y 坐标
*   width - 组件的新 width
*   height - 组件的新 height
*
* Dialog(Dialog owner, String title, boolean modal) 构造一个最初不可见的 Dialog,
* 它带有指定的所有者 Dialog、标题和模式。
*    owner - dialog 的所有者,如果此 dialog 没有所有者,则该参数为 null
*    title - dialog 的标题,如果此 dialog 没有标题,则该参数为 null
*    modal - 指定在显示的时候是否阻止用户将内容输入到其他顶级窗口中。如果该参数为 false,
* 则 dialog 是 MODELESS;如果该参数为 true,则模式类型属性被设置为 DEFAULT_MODALITY_TYPE
*/
f = new Frame("My windwo");
f.setBounds(300,100,600,500);	//设置窗体的位置。
f.setLayout(new FlowLayout());	//设置布局管理

tf = new TextField(60);		//制定列数

but = new Button("转到");

ta = new TextArea(25,70);	//参数可以指定行、列。还可传入默认文字。不需要可以不写。

d = new Dialog(f,"提示信息--self",true);
/*
* 构造函数:Dialog(Frame owner, boolean modal)
* 后面的modal(模式):
* 	1,为true时,这个对话框如果用户不操作,那么它所属的窗体就无法操作。就会死。
* 	2,为false时,可以不操作对话框,但可以操作窗体。
*/
d.setBounds(400,200,240,160);
d.setLayout(new FlowLayout());

/*
* public class Label extends Component implements Accessible
*   Label 对象是一个可在容器中放置文本的组件。一个标签只显示一行只读文本。文本可
* 由应用程序更改,但是用户不能直接对其进行编辑。
*
* Label() 构造一个空标签。
*/

lab = new Label();	//初始化时没有信息的。
okBut = new Button("确定");

d.add(lab);
d.add(okBut);
/*其实,d本身也是一个窗体,可以加到Frame里面。
* 因为Frame一打开,Dialog就存在,是没有意义的。只有见到某些操作,才会出现。
*
*/

f.add(tf);
f.add(but);
f.add(ta);
/*
* 现在基本的界面已经做出来了。但是我们想要的是,在文本框里输入一个“路径”,点击“转到”,
* 然后就能列出该目录下的文件。(不要求实现图标,但要显示名字)
* 做这个功能:按钮是事件源。
*/

myEvent();
f.setVisible(true);
}
private void myEvent()
{
/*
* Button--void addActionListener(ActionListener l) 添加指定的动作侦听器,
* 以接收发自此按钮的动作事件。
*
* public interface ActionListener extends EventListener
*    用于接收操作事件的侦听器接口。对处理操作事件感兴趣的类可以实现此接口,
* 而使用该类创建的对象可使用组件的 addActionListener 方法向该组件注册。在
* 发生操作事件时,调用该对象的 actionPerformed 方法。
*
*  void actionPerformed(ActionEvent e) 发生操作时调用。
*/
okBut.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
d.setVisible(false);
}
});

f.addWindowListener(new WindowAdapter()	//实现窗口关闭。
{
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
}
);

/*在windows中,输入路径后,一“回车”就会转到相应目录。
* 那么怎么实现呢?
* 此时,文本框是事件源,要为文本框添加键盘监听
*
* void addKeyListener(KeyListener l) 添加指定的按键侦听器,
* 以接收发自此组件的按键事件。
*
* void keyPressed(KeyEvent e) 按下某个键时调用此方法。
*
*  KeyEvent--int getKeyCode() 返回与此事件中的键关联的整数 keyCode。
*
*/
tf.addKeyListener(new KeyAdapter()
{
public void keyPressed(KeyEvent e)
{
if(e.getKeyCode()==KeyEvent.VK_ENTER)
{
showDir();
}
}
});

d.addWindowListener(new WindowAdapter()	//实现窗口关闭。
{
public void windowClosing(WindowEvent e)
{
//System.exit(0);
d.setVisible(false);
}
}
);

but.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
showDir();
}
});
}
private void showDir()
{
/*
*  TextField---String getText() 返回此文本组件表示的文本。
*
*  TextArea---void setText(String t) 将此文本组件显示的文本设置为指定文本。
*
*  TextArea---void append(String str) Appends the given text to the text
* area's current text.
*/
String dirPath = tf.getText();	//接受路径。

File dir = new File(dirPath);
if(dir.exists() && dir.isDirectory())	//判断路径是否存在,是否是目录
{
String[] names = dir.list();

ta.setText("");	//将之前的信息清空
ta.setText("\""+dirPath+"\""+"目录下的文件有:\r\n");
for(String name:names)
{
//ta.setText(name+"\r\n");	//添加数据。
/*
*   但是此时还有个问题:每次获取到的数据存到文本域里,都会替换原来
* 的数据,这个怎么解决?
*   可以用一个StringBuilder存起来。
*   TextArea里面有一个append方法。追加。
*/

ta.append(name+"\r\n");
/*
* 但是这时又出现一个问题:第一次添加的名字在下一次添加时并没有删除。
* 而是显示到了新的目录下。在循环开始前用setText("");清空
*/
}
}
/*
*    此时又出现了问题,如果所输入的路径不存在,应该有提示的。但此时还没
* 有实现这个功能。(对话框,window的子类)
*/
else{
String info = "您输入的路径:\""+dirPath+"\"是错误的";
lab.setText(info);
//lab.setAlignment(Label.CENTER);	//文字居中。
d.setVisible(true);	//这个参数必须要为true,否则对话框就是隐藏的。
}

//找tf的对象获取文本。
String text = tf.getText();	//按钮已经获取到了文本框的内容。
//System.out.println(text);	//测试输出

//ta.setText(text);	//将获取到的文本数据放到文本域里。
/*
*   但是此时还有个问题:每次获取到的数据存到文本域里,都会替换原来的
* 数据,这个怎么解决?
*/

//tf.setText("");		//清空文本框里的数据。
}

public static void main(String[] args)
{
new MyWindow();
}
}

/** 5 :菜单制作
*
* 菜单制作过程:
*    1,一个窗口要有菜单,首先要有MenuBar,不过真实编程中,f.setMenuBar(mb)
* 要放到最后一步(切记)
*    2,MenuBar上面要有菜单,必须要将Menu放到MenuBar上,而且只能是Menu。
*    3,如果要制作多级菜单:子菜单项MenuItem 必须要 添加到Menu上,然后把该
* Menu添加到MenuBar上。
*    4,上面的过程倒着来。
*/
import java.awt.*;
import java.awt.event.*;

public class MyMenuDemo {
private Frame f;
private MenuBar mb;
private Menu m;
private MenuItem closeItem,subItem;
private Menu subMenu;

MyMenuDemo()
{
init();
}

public void init()
{
/*
*  MenuItem add(MenuItem mi) 将指定的菜单项添加到此菜单。
*/
f = new Frame("my window");
f.setBounds(300,100,500,600);
f.setLayout(new FlowLayout());	//布局管理

mb = new MenuBar();	//搞一个菜单条

subMenu = new Menu("子菜单");

m = new Menu("文件");	//菜单初始化

subItem = new MenuItem("子条目");
/*
* 怎么给子菜单添加子菜单。
*/
closeItem = new MenuItem("退出");	//菜单项
/*向menu a 中添加menu b,b会带有小三角.那么b还可以有子条目
* 如果向menu a中添加menuItem c,则c不会带有小三角。即c为最终条目
*/

subMenu.add(subItem);
m.add(subMenu);
m.add(closeItem);	//将菜单项添加到菜单中。
mb.add(m);	//将菜单添加到菜单条中。

f.setMenuBar(mb);	//setMenuBar(MenuBar mb) 将此窗体的菜单栏设置为指定的菜单栏。

myEvent();
f.setVisible(true);
}

public void myEvent()
{
f.addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
});

/*
* MenuItem addActionListener(ActionListener l) 添加指定的动作侦听器,以从此菜单项接收动作事件。
* 动作侦听器:菜单条目可以用键盘操作。
*
*/
closeItem.addActionListener(new ActionListener()	//菜单监听器,菜单条目事件
{
public void actionPerformed(ActionEvent e)
{
System.exit(0);
}
});

}

public static void main(String[] args)
{
/*菜单栏,菜单项
* MenuBar
*
*/
new MyMenuDemo();
}
}

/** 6 :打开文件与保存文件
* 主要用的知识是:FileDialog,以及以前IO里面的操作。
*
*   public class FileDialog extends Dialog
*   FileDialog 类显示一个对话框窗口,用户可以从中选择文件。 由于它是一个模式对话
* 框,当应用程序调用其 show 方法来显示对话框时,它将阻塞其余应用程序,直到用户选
* 择一个文件。
*
*   FileDialog(Dialog parent, String title, int mode) 创建一个具有指定标题的文件
* 对话框窗口,用于加载或保存文件。
* 	 parent - 对话框的所有者
*   title - 对话框的标题;接受 null 值时不会抛出 NullPointerException
*   mode - 对话框的模式,FileDialog.LOAD 或 FileDialog.SAVE
*
*
*总结:
*1.操作窗体的动作:
*	f.addWindowListener(new WindowAdapter(){
*		public void .....(WindowEvent e){
*			......
*		}
*	});
*2.控制菜单的动作:
*  menuItem.addActionListener(new ActionListener(){
*  	public void actionPerformed(ActionEvent e){
*  		.......
*  	}
*  });
*
*/
import java.awt.*;
import java.awt.event.*;
import java.io.*;
public class MyMenuTest {
private Frame f;
private MenuBar mb;		//使用菜单,必须要有menubar
private Menu m;
private MenuItem openItem,saveItem,closeItem;

private FileDialog openDia,saveDia;

private TextArea ta;
private File file;	//为什么要这么写?

MyMenuTest()
{
init();
}
public void init()
{
f = new Frame("my window");
mb = new MenuBar();
m = new Menu("文件");
ta = new TextArea();

openItem = new MenuItem("打开");
saveItem = new MenuItem("保存");
closeItem = new MenuItem("退出");

f.setBounds(200,100,600,400);
//f.setLayout(new FlowLayout());	//没有了这个设置,文本域会自动适应窗体。

m.add(openItem);
m.add(saveItem);
m.add(closeItem);

mb.add(m);
f.setMenuBar(mb);
openDia = new FileDialog(f,"我要打开",FileDialog.LOAD);
saveDia = new FileDialog(f,"我要保存",FileDialog.SAVE);

f.add(ta);
myEvent();
f.setVisible(true);
}
public void myEvent()
{
f.addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
});

openItem.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
openDia.setVisible(true);	//这个必须要放在最上面,否则会出错。
/*
* FileDialog-- String getDirectory() 获取此文件对话框的目录。
*
* FileDialog-- String getFile() 获取此文件对话框的选定文件。
*/
String dirPath = openDia.getDirectory();
String fileName = openDia.getFile();
//System.out.println(dirPath+"...."+fileName);	//测试一下

if(dirPath==null || fileName==null)
{
//如果点击了“取消”话,没有此判断会出异常。
return ;	//直接返回,不做任何事情
}
ta.setText("");		//清空之前的文件
File 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 x)
{
throw new RuntimeException("读取失败");
}

}
});

/**保存文件
* 打开已经写完了。
* 保存对话框,有一个问题,就是该对话框在什么时候弹出呢?(不是“另存为”)
* 	如果文件存在,就不弹出,直接保存;如果文件不存在,就要弹出。
*
*/

saveItem.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
if(file==null)	//此处的file怎么理解?
{
//弹与不弹,关键怎么办?
saveDia.setVisible(true);

String dirPath = saveDia.getDirectory();
String fileName = saveDia.getFile();

if(dirPath==null||fileName==null)
return ;
file = new File(dirPath,fileName);	//此时,如果文件已经存在,就不需要再new了。所以要把文件提到成员上来。
}
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();
}

}
});

/*
closeItem.addActionListener(new ActionListener()
{
public void windowClosing(WindowEvent e )
{

}
});
*/
}

public static void main(String[] args)
{
new MyMenuTest();
}
}

/**6 :双击jar包执行。(具体请参照视频)因为是win7系统,所以不便操作。
* 	在使用dos命令行是,会有点麻烦。而且使用javac编译时,会在目录下产生好多类。有点乱。
* 此时,搞个包就完了:在最顶行添加代码:package mymenu;	其中,mymenu表示要打成的包名。
* 使用此命令:	javac -d e:\java(目的地)  MyMenuTest.java
* 然后进入e:\java
* 使用命令:jar -cvf my.jar mymenu
*
*/

[/code]

----------android培训java培训、期待与您交流!----------
  详细请查看:http://edu.csdn.net/heima/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: