前言
这篇文章会详细介绍如何用Java来完成图形化界面设计,帮助大家完成课程设计或者提高编程的趣味性,避免只能一直和控制台打交道,希望能给大家带来帮助的同时方便自己更好的进行复习。
PS:文章内容大部分学习自黑马程序员的课程。
目录
1 AWT编程
1.1 AWT简介
1.2 AWT继承体系
2 Component容器
2.1 Component继承体系
2.2 常见API
2.3 容器演示
2.3.1 Window
2.3.2 Panel
2.3.2.0解决乱码问题
2.3.3 ScrollPane
3 LayoutManager布局管理器
3.1 FlowLayout
3.2 BorderLayout
3.3 GridLayout
3.4 GridBagLayout
3.5 CardLayout
3.6 BoxLayout
4 AWT中常用组件
4.1 基本组件
4.2 对话框Dialog
4.2.1 Dialog
4.2.2 FileDialog
Java完成图形化界面编程需要用到AWT和Swing相关的类库。其中AWT全称为抽象窗口工具集(Abstract Window Tookit),它可以为Java应用程序提供基本的图形组件。
AWT编程中有两个基类:Component和MenuComponent
Component:代表一个能一图形化方式显示出来,并可与用户交互的对象,例如Button代表一个按钮,Text Field代表一个文本框等。
MenuComponent:代表图形界面的菜单组件,包括MenuBar(菜单条),MenuItem(菜单项)等子类。
其体系图如下:
其中Container是一种特殊的组件(Component),他代表一种容器,可以盛装普通的组件。
此外,AWT中还有一个非常重要的接口叫LayoutManager,即布局管理器,如果容器中有多个组件,则容器就需要使用LayoutManager来管理这些组建的布局方式。
下面就依次介绍Container容器和布局管理器LayoutManager
1.Window是可以独立存在的顶级窗口,默认使用BorderLayout管理其内部组件布局。
2.Panel可以容纳其他组件,但不能独立存在,它必须内嵌其他容器中使用,默认使用FlowLayout管理其内部组件布局。
3.ScrollPane是一个带滚动条的容器,它也不能独立存在,默认使用BorderLayout管理其内部组件布局。
Component作为基类,提供了如下常用的方法来设置组建的大小,位置,可见性等。
setLocation(int x,int y) | 设置组件的位置 |
setSize(int width,int height) | 设置组建的大小 |
setBounds(int x,int y,int width,int height) | 同时设置组件的位置,大小 |
setVisible(Boolean b) | 设置该组件的可见性 |
Container作为容器根类,提供了如下方法来访问容器的组件
Component add(Component c) | 向容器中添加其他组件(该组件既可以是普通组件,也可以是容器),并返回被添加的组件 |
Component getComponentAt(int x,int y) | 返回指定点的组件 |
int getComponentCount() | 返回该容器内组件的数量 |
Component[] getComponents() | 返回该容器内所有的组件 |
演示代码如下:
public class WindowDemo {
public static void main(String[] args) {
//1.创建一个窗口对象
Frame frame = new Frame("window窗口演示");
//2.指定窗口的位置,大小
frame.setLocation(100,100);
frame.setSize(500,300);
//3.设置窗口对象可见
frame.setVisible(true);
}
}
效果如下:
演示代码如下:
public class PanelDemo {
public static void main(String[] args) {
//1.要先创建一个window对象,因为panel以及其他的容器都不能独立存在,必须依附于window存在
Frame frame = new Frame("这里演示Panel");
//2.创建一个Panel对象
Panel p = new Panel();
//3.创建一个文本框和一个按钮,并且把他们放入到Panel容器中
p.add(new TextField("这里是一个测试文本"));
p.add(new Button("这里是一个测试按钮"));
//4.把panel放入到window中
frame.add(p);
//5.设置window的位置以及大小
frame.setBounds(100,100,500,300);
//6.设置window可见
frame.setVisible(true);
}
}
效果演示:
可以看到,我们的按钮中的出现了乱码,至于原因,则是因为我们的idea此时的编码是UTF-8编码,而我们运行程序时,这个Button是由我们当前的Windows操作系统创建的,所以创建时的默认编码是gbk,为了解决乱码问题,我们只需要使该程序的编码和解码一致即可。
具体操作如下:
第一步:找到右上角的“编辑运行/调试配置”对话框,
点击编辑配置(未汉化版的叫做Edit Configurations...)。
第二步:
找到VM options,在其中填入-Dfile.encoding=gbk
如果找不到VM options 选项,就输入Alt+V或者点击Modify options,然后点击Add VM options
在填入-Dfile.encoding=gbk后,点击应用即可
演示代码如下:
public class ScrollPaneDemo {
public static void main(String[] args) {
Frame frame = new Frame("这里演示ScrollPane");
//1.创建一个ScrollPane对象
ScrollPane sp = new ScrollPane(ScrollPane.SCROLLBARS_ALWAYS);
//ScrollPane.SCROLLBARS_ALWAYS 表示默认自带滚动条
//2.往ScrollPane中添加内容
sp.add(new TextField("这是测试文本"));
sp.add(new Button("这是测试按钮"));
//3.把ScrollPane添加到Frame中
frame.add(sp);
frame.setBounds(100,100,500,300);
frame.setVisible(true);
}
}
效果如下:
我们可以发现,我们的程序明明向ScrollPane容器添加了一个文本框和一个按钮,但却只能看到一个按钮,却看不到文本框,这是因为ScrollPane使用BorderLayout布局管理器的缘故,二BorderLayout导致了该容器中只有一个组件被显示出来,为解决这一问题,就需要我们学习布局管理器的知识,下面介绍LayoutManager布局管理器。
在前面,我们介绍了Component中有一个方法setBounds()可以设置当前容器的位置和大小,但我们需要明确一件事,如果我们手动为组件设置位置和大小的话,就会造成程序的不通用性。
例如:Labal labal=new Labal("你好,世界");创建了一个labal组件,很多情况下,我们需要让labal组件的宽高和"你好,世界"这个字符串自身的宽高一致,这种大小称为"最佳大小",由于操作系统存在差异,例如在windows上,我们要达到这种效果,需要把宽高设置为100px,20px,而Linux则需要设置为120px,24px。
由此可见,在不同操作系统下手动设置组件的位置和大小是一种很不好的体验,因为太多组件都需要分别为其设置不同操作系统的位置和大小,工作量太大。为此,Java提供了LayoutManager布局管理器,可以根据运行平台来自动调整组件大小,程序员只需要为容器选择合适的布局管理器即可。
下面来看LayoutManager布局管理器继承体系:
在FlowLayout布局管理器中 ,组件像流水一样向某个方向排列,遇到边界就折回,从头开始排列。默认情况下,FlowLayout布局管理器从左往右排列所有组件,遇到边界就折回下一行重新开始。
构造方法 | 方法功能 |
FlowLayout() | 使用默认的对齐方法和默认的垂直间距、水平间距创建FlowLayout布局管理器 |
FlowLayout (int align) |
使用指定的对齐方法和默认的垂直间距、水平间距创建FlowLayout布局管理器 |
FlowLayout (int align, int hgap, int vgap) |
使用指定的对齐方法和指定的垂直间距、水平间距创建FlowLayout布局管理器 |
FlowLayout中组件的排列方向(从左到右,从右到左,从中间向两边等),该参数应该使用FlowLayout类的静态常量:FlowLayout LEFT、FlowLayout CENTER、FlowLayout RIGHT,默认是左对齐。
FlowLayout中组件中间距通过整数设置,单位是像素,默认是5个像素。
代码演示:
public class FlowLayoutDemo {
public static void main(String[] args) {
Frame frame = new Frame("这里测试FlowLayout");
//1.通过setLayout方法设置容器的布局管理器
// frame.setLayout(new FlowLayout(FlowLayout.LEFT,20,20));
//frame.setLayout(new FlowLayout(FlowLayout.CENTER,20,20));
frame.setLayout(new FlowLayout(FlowLayout.RIGHT,40,20));
//2.添加多个按钮到frame中
for (int i = 1; i <= 100; i++) {
frame.add(new Button("按钮"+i));
}
//3.设置最佳大小,pack方法
frame.pack();
frame.setVisible(true);
}
}
效果演示:
BorderLayout将容器分为EAST,SOUTH,WEST,CENTER五个区域,普通组件可以被放置在这5个区域的任意一个中。
BorderLayout布局管理器示意图如下:
当改变使用BorderLayout的容器大小时,NORTH,SOUTH和CENTER区域水平调整,而EAST,WEST和CENTER区域垂直调整。
使用BorderLayout注意事项:
1.当向使用BorderLayout布局管理器的容器中添加组件时,需要指定要添加到哪个区域中,如果没有指定,则默认添加到中间区域。
2.如果向同一个区域添加多个组件时,后放入的组件会覆盖掉先放入的组件。
构造方法 | 方法功能 |
BorderLayout() | 使用默认的水平间距,垂直间距创建BorderLayout布局管理器 |
BorderLayout (int hgap, int vgap) |
使用指定的水平间距,垂直间距创建BorderLayout布局管理器 |
代码演示:
public class BorderLayoutDemo1 {
public static void main(String[] args) {
Frame frame = new Frame("这里测试BorderLayout");
//1.给frame设置BorderLayout布局管理器
frame.setLayout(new BorderLayout(30,10));
//2.往frame的指定区域添加组件
frame.add(new Button("北侧按钮"),BorderLayout.NORTH);
frame.add(new Button("南侧按钮"),BorderLayout.SOUTH);
frame.add(new Button("东侧按钮"),BorderLayout.EAST);
frame.add(new Button("西侧按钮"),BorderLayout.WEST);
frame.add(new Button("中间按钮"),BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
}
}
效果如下:
注意:如果不往某个区域放入组件,那么该区域不会空白出来,而是会被其他区域占用。
例如
public class BorderLayoutDemo2 {
public static void main(String[] args) {
Frame frame = new Frame("这里测试BorderLayout");
//1.给frame设置BorderLayout布局管理器
frame.setLayout(new BorderLayout(30,10));
//2.往frame的指定区域添加组件
frame.add(new Button("北侧按钮"),BorderLayout.NORTH);
frame.add(new Button("南侧按钮"),BorderLayout.SOUTH);
frame.add(new Button("中间按钮"),BorderLayout.CENTER);
frame.add(new TextField("测试文本框"));
frame.pack();
frame.setVisible(true);
}
}
会得到
这里东西两侧区域就被中间区域占用了,且中间的按钮被后面的文本框所覆盖。
如果想要中间按钮和测试文本框都显示出来,可以把中间按钮和测试文本放在一个Panel中,然后把Panel添加到Frame中间去即可,代码演示如下:
public class BorderLayoutDemo2 {
public static void main(String[] args) {
Frame frame = new Frame("这里测试BorderLayout");
//1.给frame设置BorderLayout布局管理器
frame.setLayout(new BorderLayout(30,10));
//2.往frame的指定区域添加组件
frame.add(new Button("北侧按钮"),BorderLayout.NORTH);
frame.add(new Button("南侧按钮"),BorderLayout.SOUTH);
// frame.add(new Button("中间按钮"),BorderLayout.CENTER);
// frame.add(new TextField("测试文本框"));
Panel p = new Panel();
p.add(new Button("中间按钮"));
p.add(new TextField("测试文本框"));
frame.add(p);
frame.pack();
frame.setVisible(true);
}
}
得到
GridLayout布局管理器将容器分割成纵横线分割的网格,每个网格所占的区域大小相同,当向使用GridLayout布局管理器的容器添加组件时,默认从左向右,从上向下依次添加到每个网格中,与FlowLayout不同的是,放置在GridLayout布局管理器中的各组件的大小由组件所处的区域决定(每个组件将自动占满整个区域)。
GridLayout (int rows,int cols) |
采用指定的行数,列数,以及默认的横向间距,纵向间距将容器分割成多个网格 |
GridLayout (int rows,int cols, int hgap,int vgap) |
采用指定的行数,列数,以及指定的横向间距,纵向间距将容器分割成多个网格 |
下面演示使用Frame+Panel,配合FlowLayout和GridLayout完成一个计算器效果。
代码如下:
public class GridLayoutDemo {
public static void main(String[] args) {
Frame frame = new Frame("计算器");
//1.创建一个Panel对象,里面存放一个TextFiled组件
Panel p = new Panel();
p.add(new TextField(30));
//2.把当前这个Panel添加到frame的北边区域
frame.add(p,BorderLayout.NORTH);
//3.创建一个Panel对象,并且设置它的布局管理器为GridLayout
Panel p2 = new Panel();//Panel的默认布局管理器是FlowLayout
p2.setLayout(new GridLayout(3,5,4,4));
//4.往Panel中添加内容
for (int i = 0; i < 10; i++) {
p2.add(new Button(i+""));//放入Button的不能为数字,需要改为字符串
}
p2.add(new Button("+"));
p2.add(new Button("-"));
p2.add(new Button("*"));
p2.add(new Button("/"));
p2.add(new Button("."));
//5.把当前Panel添加到frame中
frame.add(p2);
frame.pack();
frame.setVisible(true);
}
}
效果如下:
GridBagLayout布局管理器中,一个组件可以跨越一个或多个网格,并可以设置各个网格的大小各不相同,从而增加布局的灵活性,但实现过程也会很复杂,由于在Swing类库中有更加强大的布局管理器来完成这些效果,因此这里只做介绍,不做演示。
CardLayout布局管理器一时间而非空间来管理它里面的组件,它将加入容器的所有组件看成一叠卡片(每个卡片其实就是一个组件),每次只有最上面那个Component才可见。就好像一张扑克牌,每次只要最上面那张扑克可见。
CardLayout() | 创建默认的CardLayout布局管理器 |
CardLayout (int hgap,int vgap) |
通过指定卡片与容器左右边界的间距(hgap),上下边界(vgap)的间距来创建CardLayout布局管理器 |
first(Container target) | 显示target容器的第一张卡片 |
last(Container target) |
显示target容器的最后一张卡片 |
previous(Container target) | 显示target容器的前一张卡片 |
next(Container target) | 显示target容器的后一张卡片 |
show(Container taget, String name) |
显示target容器中指定名字的卡片 |
下面进行案例演示:
public class CardLayoutDemo {
public static void main(String[] args) {
Frame frame = new Frame("这里测试CardLayout");
//1.创建一个Panel,用来存储多张卡片
Panel p1 = new Panel();
//2.创建CardLayout对象,并且把该对象设置给之前创建的容器
CardLayout cardLayout = new CardLayout();
p1.setLayout(cardLayout);
//3.往panel中存储多个组件
String[] names = {"第一张","第二张","第三张","第四张","第五张"};
for (int i = 0; i < names.length; i++) {
p1.add(names[i],new Button(names[i]));
}
//4.把panel放到frame的中间区域
frame.add(p1);
//5.创建另外一个panel p2,用来存储多个按钮组件
Panel p2 = new Panel();
//6.创建5个按钮组件
Button b1 = new Button("上一张");
Button b2 = new Button("下一张");
Button b3 = new Button("第一张");
Button b4 = new Button("最后一张");
Button b5 = new Button("第三张");
//7.创建一个事件监听器,监听按钮的点击动作
ActionListener listener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
String actionCommand = e.getActionCommand();//这个字符串其实就是按钮上的文字
switch (actionCommand){
case "上一张":
cardLayout.previous(p1);
break;
case "下一张":
cardLayout.next(p1);
break;
case "第一张":
cardLayout.first(p1);
break;
case "最后一张":
cardLayout.last(p1);
break;
case "第三张":
cardLayout.show(p1,"第三张");
break;
}
}
};
//8.把当前这个时间监听器和多个按钮绑定到一起
b1.addActionListener(listener);
b2.addActionListener(listener);
b3.addActionListener(listener);
b4.addActionListener(listener);
b5.addActionListener(listener);
//9.把按钮添加到容器p2中
p2.add(b1);
p2.add(b2);
p2.add(b3);
p2.add(b4);
p2.add(b5);
//10.把p2放到frame的南边区域
frame.add(p2,BorderLayout.SOUTH);
frame.pack();
frame.setVisible(true);
}
}
效果如下:
为了简化开发,Swing引入了一个新的布局管理器:BoxLayout,BoxLayout可以在垂直和水平两个方向上摆放GUI组件,BoxLayout提供了一个如下简单的构造器。
BoxLayout (Container target, int axis) |
指定创建基于target容器的BoxLayout布局管理器,该布局里的组件按照axis方向排列。其中axis有BoxLayout.X_AXIS(横向)和BoxLayout.Y_AXIS(纵向)两个方向 |
下面演示使用Frame和BoxLayout完成下图效果:
代码如下:
public class BoxLayoutDemo1 {
public static void main(String[] args) {
Frame frame = new Frame("这里测试BoxLayout");
//1.基于frame容器,创建一个BoxLayout对象,并且,该对象存放组件是垂直存放
//BoxLayout boxLayout = new BoxLayout(frame, BoxLayout.Y_AXIS);
BoxLayout boxLayout = new BoxLayout(frame, BoxLayout.X_AXIS);//水平排列
//2.把BoxLayout对象设置给Frame
frame.setLayout(boxLayout);
//3.往frame中添加两个按钮组件
frame.add(new Button("按钮1"));
frame.add(new Button("按钮2"));
frame.pack();
frame.setVisible(true);
}
}
在Java.Swing包中,提供了一个新的容器Box,该容器的默认布局管理器就是BoxLayout,大多数情况下,使用Box容器去容纳多个GUI组件,然后把Box容器作为一个组件,添加到其他容器中,从而形成整体窗口布局。Box容器中提供了两个方法:
static Box createHorizontalBox() | 创建一个水平排列组件的Box容器 |
static Box createVerticalBox() | 创建一个垂直排列组建的Box容器 |
下面演示使用Frame和Box完成下图效果:
代码如下:
public class BoxLayoutDemo2 {
public static void main(String[] args) {
Frame frame = new Frame("这里测试BoxLayout");
//1.创建一个水平排列组件的Box容器
Box hBox = Box.createHorizontalBox();
//2.往当前容器中添加两个按钮
hBox.add(new Button("水平按钮1"));
hBox.add(new Button("水平按钮2"));
//3.创建一个垂直排列组件的Box容器
Box vBox = Box.createVerticalBox();
//4.往当前容器中添加两个按钮
vBox.add(new Button("垂直按钮1"));
vBox.add(new Button("垂直按钮2"));
//5.把两个Box容器添加到Frame中展示
frame.add(hBox,BorderLayout.NORTH);
frame.add(vBox);
frame.pack();
frame.setVisible(true);
}
}
通过上面两个BoxLayout演示,我们发现,被它管理的容器中的组件之间是没有任何间隔的,但我们前面所学的几种布局管理器中,组件之间都会有一些间隔,如何让BoxLayout中的组件之间也存在间隔呢?
这就只需要我们在原有的组件需要间隔的地方,手动添加间隔即可,这里的每个间隔可以是一个组件,只是该组件没有内容,仅仅起到分割效果。
Box类中,提供了以下方便的静态方法来生成这些间隔组件:
static Component createHorizontalGlue() |
创建一条水平Glue (可在两个方向上同时拉伸的间距) |
static Component createVerticalGlue() |
创建一条垂直Glue (可在两个方向上同时拉伸的间距) |
static Component createHorizontalStrut(int width) |
创建一条指定宽度(宽度固定了,不能拉伸)的水平Strut(可在垂直方向上拉伸的间距) |
static Component createVerticalStrut(int height) |
创建一条指定高度(高度固定了,不能拉伸)的水平Strut(可在水平方向上拉伸的间距) |
下面演示使用Frame和Box完成下图效果:
代码如下:
public class BoxLayoutDemo3 {
public static void main(String[] args) {
Frame frame = new Frame("这里测试BoxLayout");
//1.创建水平排列的Box容器 hBox
Box hBox = Box.createHorizontalBox();
//2.往hBox容器中添加按钮,还需要在多个按钮之间添加分割
hBox.add(new Button("水平按钮一"));
hBox.add(Box.createHorizontalGlue());//该分割在两个方向上都可以拉伸
hBox.add(new Button("水平按钮二"));
hBox.add(Box.createHorizontalStrut(30));
hBox.add(new Button("水平按钮三"));
//3.创建垂直排列的Box容器 vBox
Box vBox = Box.createVerticalBox();
//4.往vBox容器中添加按钮,还需要在多个按钮之间添加分割
vBox.add(new Button("垂直按钮一"));
vBox.add(Box.createVerticalGlue());//该分割在两个方向上都可以拉伸
vBox.add(new Button("垂直按钮二"));
vBox.add(Box.createVerticalStrut(30));
vBox.add(new Button("垂直按钮三"));
//5.把box容器添加到frame中
frame.add(hBox,BorderLayout.NORTH);
frame.add(vBox);
frame.pack();
frame.setVisible(true);
}
}
组件名 | 功能 |
Button | 按钮 |
Canvas | 用于绘图的画布 |
Checkbox | 复选框组件(也可当做单选框组件使用) |
CheckboxGroup | 用于将多个Checkbox组件组合成一组,一组Checkbox组件将只有一个可以被选中,即全部变成单选框组件 |
Choice | 下拉选择框 |
Frame | 窗口,在GUI程序里通过该类创建窗口 |
Labal | 标签类,用于放置提示性文本 |
List | 列表框组件,可以添加多项条目 |
Panel | 不能单独存在基本容器类,必须放在其他容器中 |
Scrollbar | 滑动条组件,如果需要用户输入位于某个范围的值,就可以使用滑动条组件,比如调色板中设置RGB的三个值所用的滑动条,当创建一个滑动条时,必须指定它的方向,初始值,滑块的大小,最小值和最大值 |
ScollPane | 带水平即垂直滚动条的容器组件 |
TextArea | 多行文本域 |
TextField | 单行文本域 |
这些AWT组件可以查阅API文档以获取它们各自的详细信息。
下面来用代码实现一个这样的效果:
代码如下:
public class BasicComponentDemo {
Frame frame = new Frame("这里测试基本组件");
TextArea ta = new TextArea(5,20);//左上角占大部分的文本框,最多5行,20列
Choice colorChooser = new Choice();//中间左边部分的下拉选择框
CheckboxGroup cbg = new CheckboxGroup();//中间部分复选框
Checkbox male = new Checkbox("男",cbg,true);
Checkbox female = new Checkbox("女",cbg,false);
Checkbox isMarried = new Checkbox("是否已婚?");
TextField tf = new TextField(50);//左下角的单行文本框
Button ok = new Button("确认");//右下角的确认按钮
List colorList = new List(6,true);//右上角列表框
public void init(){
//组装界面
//组装底部
Box bBox = Box.createHorizontalBox();//创建一个水平排列组件的Box容器
bBox.add(tf);
bBox.add(ok);
frame.add(bBox,BorderLayout.SOUTH);
//组装 选择部分
colorChooser.add("红色");
colorChooser.add("蓝色");
colorChooser.add("绿色");
Box cBox = Box.createHorizontalBox();
cBox.add(colorChooser);//放下拉选择框
cBox.add(male);
cBox.add(female);
cBox.add(isMarried);
//组装文本域和选择部分
Box topLeft = Box.createVerticalBox();//创建一个垂直排列组件的Box容器
topLeft.add(ta);
topLeft.add(cBox);
//组装顶部左边和列表框
colorList.add("红色");
colorList.add("绿色");
colorList.add("蓝色");
Box top = Box.createHorizontalBox();
top.add(topLeft);//topLeft也是一个容器,现在作为组件放在新的top容器里
top.add(colorList);
frame.add(top);
//设置frame为最佳大小,并且可见
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
new BasicComponentDemo().init();
}
}
Dialog是Window类的子类,是一个容器类,属于特殊组件,对话框是可以独立存在的顶级窗口,因此用法与普通窗口的用法几乎一致,但是使用对话框需要注意以下两点:
1.对话框通常依赖于其他窗口,就是通常需要有一个父窗口。
2.对话框有非模式(non-modal)和模式(modal)两种,当某个模式对话框被打开后,该模式对话框总是位于它的父窗口之上,在模式对话框被关闭之前,父窗口无法获得焦点。
Dialog (Frame owner, String title, boolean modal) |
创建一个对话框对象: owner:当前对话框的父窗口 title:当前对话框的标题 modal:当前对话框是否是模式对话框,true/false |
下面通过Frame,Button,Dialog实现下图效果:
代码如下:
package com.one.component;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class DialogDemo1 {
public static void main(String[] args) {
Frame frame = new Frame("这里测试Dialog");
//1.创建两个对话框Dialog对象,一个模式的,一个非模式的
Dialog d1 = new Dialog(frame, "模式对话框", true);
Dialog d2 = new Dialog(frame, "非模式对话框", false);
//2.通过setBounds方法设置Dialog的位置以及大小
d1.setBounds(20,30,300,200);
d2.setBounds(20,30,300,200);
//3.创建两个按钮
Button b1 = new Button("打开模式对话框");
Button b2 = new Button("打开非模式对话框");
//4.给这两个按钮添加点击后的行为
b1.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
d1.setVisible(true);
}
});
b2.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
d2.setVisible(true);
}
});
//5.把按钮添加到frame中
frame.add(b1,BorderLayout.NORTH);
frame.add(b2);
//设置frame最佳大小并可见
frame.pack();
frame.setVisible(true);
}
}
继续演示打开对话框后,对话框中根据需求,自定义内容。
代码如下:
public class DialogDemo2 {
public static void main(String[] args) {
Frame frame = new Frame("这里测试Dialog");
//1.创建两个对话框Dialog对象,一个模式的,一个非模式的
Dialog d1 = new Dialog(frame, "模式对话框", true);
/**
* 创建一个垂直的Box容器,把一个文本框和一个按钮添加到Box容器中
*/
Box vBox = Box.createVerticalBox();
vBox.add(new TextField(20));
vBox.add(new Button("确认"));
//把Box容器添加到Dialog中
d1.add(vBox);
//2.通过setBounds方法设置Dialog的位置以及大小
d1.setBounds(20,30,300,200);
/**
* ================================================
*/
//3.创建按钮
Button b1 = new Button("打开模式对话框");
//4.给按钮添加点击后的行为
b1.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
d1.setVisible(true);
}
});
//5.把按钮添加到frame中
frame.add(b1,BorderLayout.NORTH);
//设置frame最佳大小并可见
frame.pack();
frame.setVisible(true);
}
}
于是我们的对话框中就有了垂直排列的文本框和确认按钮
Dialog类还有一个子类:FileDialog,它代表一个文件对话框,用于打开或者保存文件,需要注意的是FileDialog无法指定模态或者非模态,这是因为FileDialog依赖于运行平台的实现,如果运行平台的文件对话框是模态的,那么FileDialog也是模态的,否则就是非模态的。
FileDialog (Frame parent, String title, int mode) |
创建一个文件对话框: parent:指定父窗口 title:对话框标题 mode:文件对话框类型, 如果指定为FileDialog.LOAD,则用于打开文件 如果指定为FileDialog.SAVE,则用于保存文件 |
String getDirectory() | 获取被打开或者保存文件的绝对路径 |
String getFile() | 获取被打开或者保存文件的文件名 |
使用Frame,Button,FileDialog完成下图效果:
代码如下:
package com.one.component;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class FileDialogTest {
public static void main(String[] args) {
Frame frame = new Frame("这里测试FileDialog");
//1.创建两个FileDialog对象
FileDialog f1 = new FileDialog(frame,"选择要打开的文件",FileDialog.LOAD);
FileDialog f2 = new FileDialog(frame,"选择要保存的路径",FileDialog.SAVE);
//2.创建两个按钮
Button b1 = new Button("打开文件");
Button b2 = new Button("保存文件");
//3.给这两个按钮设置点击后的行为:获取打开或者保存的路劲文件名
b1.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
f1.setVisible(true);//选择完毕前,代码会阻塞到这里
//获取选择的路径及文件
String directory = f1.getDirectory();
String file = f1.getFile();
System.out.println("打开的文件路径为:"+directory);
System.out.println("打开的文件名称为:"+file);
}
});
b2.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
f2.setVisible(true);
//获取选择的路径及文件
String directory = f2.getDirectory();
String file = f2.getFile();
System.out.println("保存的文件路径为:"+directory);
System.out.println("保存的文件名称为:"+file);
}
});
//4.把按钮添加到Frame中
frame.add(b1,BorderLayout.NORTH);
frame.add(b2);
//设置frame最佳大小并可见
frame.pack();
frame.setVisible(true);
}
}