存档

文章标签 ‘Java’

Java 布局管理器不完全指南

2010年6月20日 低调の华丽 2 条评论

绝大多数的Java程序员都不太热衷于写Java桌面应用程序,他们都觉得用Java写界面既丑,速度又慢,而且很复杂。许多人认为,Java写不了好的桌面程序。好多初学Java的人,在刚学会Java语法之后,直接跳过桌面程序,成为了JavaEE程序员

确实,对于VB或者VC来说,用Java写桌面程序难度差的不是一个数量级。Java语言,本来就不适合快速开发,对于Java大部分的开发框架,本不是针对快速开发而言,而是为了更好的扩展与重构。

个人认为,Swing的难点在于复杂的布局管理器。只要吃透了这个,写Java桌面程序就简单了。

1.流式布局 (FlowLayout)

这是面板(JPanel)的默认布局管理器。流式布局管理器的特点是在一行上水平排列组件,直到没有足够的空间为止,这时开始新的一行。当用户缩放容器时,布局管理器自动地调整组件的位置使其填充可用的空间。

FlowLayout有三种构造方法,

  • FlowLayout() : 使用居中的对齐方式,组件间水平和垂直间距都为5。
  • FlowLayout(int align) : align表示对齐方式,可以是LEFT,CENTER或RIGHT。
  • FlowLayout(int align, int hgap, int vgap) : hgap 水平间距,vgap 垂直间距。

2.边界布局 (BorderLayout)

这是每个JFrame的内容窗格的默认布局管理器( JFrame.getContentPane() ).

边界布局管理器把组件分成5个区域,NORTH,SOUTH,EAST,WEST,CENTER。先放入边缘组件,当容器缩放的时候,边缘组件不会改变,而中部组件的大小会发生相应变化。

但是BorderLayout有一个问题,就是当添加多个组件到一个区域时,只显示最新添加的组件,而且组件会充满整个区域。解决的方法是在区域上添加一个面板(JPanel),在面板上放置多个组件。

 

3.箱式布局 (BoxLayout)

要想创建一个使用箱式布局的新容器,可以调用:

Box b = Box.createHorizontalBox();


或者

Box b = Box.createVerticalBox();


下面是添加组件的常用方法:

b.add(okButton);
b.add(cancelButtn);

在水平的箱子里,组件从左到右排列.在垂直的箱子里,组件从上到下排列。

下面详细的研究一下水平布局。

每个组件有三个尺寸,首选尺寸,最大尺寸,最小尺寸。

下面是箱式布局管理器的工作细节:

  1. 计算最高组件的最大高度。
  2. 尝试把所有的组件在垂直方向上增至这个高度。
  3. 如果一个组件没有增至这个高度,那么它的y对齐方式要通过调用getAlignmentY()方法获得。这个方法将返回一个介于0(顶端对齐)到1(底端对齐)之间的浮点数,组件的默认值是0.5。
  4. 获得每个组件的首选宽度,然后把所有首选宽度累加起来。
  5. 如果所有的首选宽度的总和小于箱的宽度,那么组件的宽度就会延伸到不超过最大宽度的值,直到适应箱的宽度为止。组件从左到右依次排列,并且相邻的组件之间没有空间。如果所有的首选宽度的总和大于箱的宽度,组件就会被压缩,但不会小于各自的最小宽度,直到适应箱子的宽度为止。如果组件的最小宽度之和大于箱的宽度,有些组件就会显示不出来。

默认情况下,箱式布局各组件是没有间距的。如果需要添加间距,可以添加不可见的填充件。有这样三种填充件:支柱,固定区,胶水。

b.add(label)
b.add(Box.createHorizontalStrut(10));
b.add(textField);


固定区填充件有点像一对支柱。例如:

b.add(Box.createRightArea(new Dimension(5,20)));

将添加一个宽度为5像素,高度是20像素的不可见区域。

胶水将组件互相拉开,直至充满整个空间。例如

b.add(button1);
b.add(Box.createGlue());
b.add(button2);

如果这个箱子不包含其他的组件,那么button1就会被放在最左边,button2就会被放置到最右边。

4.网格组布局 (GridBagLayout)

网格组布局是所有布局管理器之首。可以认为网格组布局是没有限制的网格布局。在网格组布局中,行和列的尺寸都可以改变。可以通过将响铃的单元合并来适应更大的组件。使用网格组布局可能相当复杂,但是它最灵活且使用范围最广。

要想使用网格组布局管理器进行布局,必须经过下列过程:

  1. 建立GridBagLayout类型的对象。不需要指定网格的行数和列数,布局管理器会根据后面所给的信息猜测出来。
  2. 把GridBagLayout对象设置成组件的布局管理器。
  3. 为每个组件建立一个GridBagConstraints类型的对象。设置GridBagConstraints对象的域值以便制定组件在网格组中的布局方案。
  4. 最后通过下面的调用添加组件的约束。
add(component,constrants);


示例代码:

JPanel panel = new JPanel();
JLabel label = new JLabel("Test");
 
GridBagLayout layout = new GridBagLayout();
panel.setLayout(layout);
GridBagConstraints constrants = new GridBagConstraints();
constrants.weightx = 100;
constrants.weighty = 100;
constrants.gridx = 0;
constrants.gridy = 2;
constrants.gridwidth = 2;
constrants.gridheight = 1;
panel.add(label, constrants);

 

知道如何设置GridBagConstraints对象的状态是很重要的,下面详细介绍GridBagConstraints的约束属性。

1.gridxgridy,gridwidth,gridheight

gridx,gridy表示组件在网格中的行列位置(第N行,第N列,从0开始计算)。gridwidth,gridheight表示组件所占的网格的行数和列数。示例代码中constrants应用的组件在第0行,第2列,横向占用2格,纵向占用1格。

2.weightx,weighty

增量字段,如果增量字段设置为0,这个区域永远是初始尺寸。默认增量字段的值为1,代表等比例拉伸组件大小。

3.fill

表示组件填充当前网格的属性。它有四个有效值,NONE,HORIZONTAL,VERTICAL,BOTH (为GridBagConstraints的static final成员变量),分表代表:不填充,横向填充,纵向填充,填充整个区域。

4.anchor

表示当组件在当前网格区域中的位置。有效值可以设置为CENTER,NORTH,SOUTH,NORTHEAST,EAST等。仅当组件没有充满整个区域时有效。

5.insets

表示外部填塞,用来设置组件周围增加的空白区域。通过设置Insets对象的left,right,top,button值在设置组件周围的空间量。

6.ipadx,ipady

表示内部填塞,该参数用以设置组件的最小尺寸。如果参数值为正值则组件的最小尺寸将比原始最小尺寸大,如果为负值,则组件的最小尺寸将会变得比原始的最小尺寸小。该参数也可以理解为直接为组件指定大小,这个设置的大小就是组件的最小尺寸。其设置后组件的大小为组件的原始最小尺寸加上ipadx(y)*2个像素。

对于GridBagLayout对象来说,本身也有columnWidths,rowHeights,columnWidths,rowWeights这四个属性。

1.columnWidths,rowHeights 设置一个int数组对象来表示各个网格的长度和宽度。例如

gbl.columnWidths = new int[] { 30, 80, 80, 80, 30 };
gbl.rowHeights = new int[] { 45, 200, 30, 45 };

表示网格中的前四列宽度为30,80,80,80,30,前四行宽度为45,200,30,45。

2.columnWeights,rowWeights 设置一个double数组对象来表示各个网格的长度和宽度的权重。当面板被拉伸时,会根据权重拉伸相对应的网格。权重为0表示不拉伸网格。为1表示等比例拉伸。

个人认为这个属性和GridBagConstraints中的weightx,weighty是一个意思,只是一个针对面板上的所有组件,一个针对相应组件而已。不过在实际的设计中,个人比较倾向于使用columnWeights, rowWeights而不是weightx,weighty。因为这样更全局,也更直观。

在使用GridBagLayout布局时,最好使用GridBagContraints帮助类(GBC)代替GridBagContraints类.这样会使得代码更加易读而且便于调试。

public class GBC extends GridBagConstraints {
 
	private static final long serialVersionUID = 2242355893259876283L;
 
	public GBC(int gridx, int gridy) {
		this.gridx = gridx;
		this.gridy = gridy;
	}
 
 
	public GBC(int gridx, int gridy, int gridwidth, int gridheight) {
		this.gridx = gridx;
		this.gridy = gridy;
		this.gridwidth = gridwidth;
		this.gridheight = gridheight;
	}
 
	public GBC setAnchor(int anchor) {
		this.anchor = anchor;
		return this;
	}
 
	public GBC setFill(int fill) {
		this.fill = fill;
		return this;
	}
 
	public GBC setWeight(double weightx, double weighty) {
		this.weightx = weightx;
		this.weighty = weighty;
		return this;
	}
 
	public GBC setInsets(int distance) {
		this.insets = new Insets(distance, distance, distance, distance);
		return this;
	}
 
	public GBC setIpad(int ipadx, int ipady) {
		this.ipadx = ipadx;
		this.ipady = ipady;
		return this;
	}
 
}


下面是帮助类的使用方法

panel.add(label,new GBC(0,2,2,1).setFill(GBC.BOTH).setInsets(1));

 

注:本文参考《Java2核心技术卷一:基础知识》部分内容。

分类: Java 标签: , ,

如果Java OS成功,Sun就是今天的王者

2010年6月10日 低调の华丽 没有评论

这几天看了李开复的新书《世界因你不同》,谈到了当时开复在微软做Vista开发时,盖茨对Vista的三大目标,其中之一就是用C#重写Windows Vista。最终失败了,因为C#太慢了,基于当时的硬件根本系统无法跑起来。虽然如此,我还是很佩服盖茨的想法。想象一下,如果成功的话,Vista将成为一个无数程序员梦寐以求的,完美的开发平台:统一的语言,统一的接口。

Sun曾经也有过JavaOS的努力,不过貌似是在嵌入式系统领域。如果Java当时能做桌面操作系统的话,想必会有很大的成就。不过先得解决JVM速度,丑陋的界面,以及复杂的硬件驱动的问题。

在Jdk1.6之后,速度,界面等问题已经越来越不是问题,对于硬件驱动而言,可以参考Chrome OS 和Android,开源系统,基于Linux平台。

个人很看好Chrome OS 和Android,尤其是Android,因为还不清楚在Chrome OS上使用什么语言开发应用程序,但是Android程序是基于Java语言的。而且,我相信Android虽然是手机系统,但是谁能知道,在不远的将来,你的手机和PC还有什么功能上的区别吗?也许只是大小的区别了。

以上只是个人不成熟的看法。

分类: Web&IT业界 标签: , ,

Work Timer V0.2

2010年5月4日 低调の华丽 没有评论

为什么要做这个工具?



我一直想做一个这样的工具.很多单位(包括我们单位)实行的是弹性工作制,上班时间只要满8小时就可以下班.因为我老是忘记早上什么时候打的卡,以至于经常在单位多待N久(其实也就是十几二十分钟).这个工具能很好的满足我的要求.

这个工具有什么功能?



1.针对弹性工作制的下班提醒,在某个时间段后程序会自动弹出对话框提示。

2.最小化到系统托盘,双击后显示程序界面。

3.下班提醒时,系统托盘变成闪烁状态(类似于QQ新消息)。

4.程序默认9小时之后提醒,用户可自由设置具体的工作时间。

5.当程序被关闭,如果用户在下班提醒之前重新打开,程序计时依然有效。

如何使用?



1.首先要安装Jre,下载地址:http://www.java.com/zh_CN/download/manual.jsp

2.双击运行该程序。

3.建议将程序设置为开机启动(将程序快捷方式拖到 开始->所有程序->启动 中,并将文件setting.properties 中的autoStart设为true)

下载地址

对于这个工具有什么问题可以联系我。

分类: Java 标签: ,