java swt 布局管理器_JAVA.SWT/JFace: SWT布局管理器
7.1 布局管理器概述
FillLayout(充滿式布局):在單行或單列中放置相同大小的控件,是最簡單的布局。
RowLayout(行列式布局):在單行或者多行中放置控件,應(yīng)用了fill、wrap和spacing等選項(xiàng)。
GridLayout(網(wǎng)格式布局):向表格一樣放置控件。
FormLayout(表格式布局):與GridLayout功能差不多的布局,可以通過定義4個(gè)邊的“附加值”來放置控件。
StackLayout(堆棧式布局):類似堆棧式的布局,只顯示最上方的控件。
7.2 FillLayout(充滿式布局)
規(guī)則:試圖填充一行或一列,盡可能的充滿整個(gè)面板,并且強(qiáng)制所有控件平均分配大小。FillLayout不會(huì)自動(dòng)執(zhí)行,也不能設(shè)置每個(gè)控件之間的空隙,但能夠指定面板的四周的空白。
FillLayout layout = new FillLayout(SWT.VERTICAL);
或
FillLayout layout = new FillLayout();
layout.type = SWT.VERTICAL; // 默認(rèn)為:SWT.HORIZONTAL
水平填充(SWT.HORIZONTAL):
垂直填充(SWT.VERTICAL):
設(shè)置四周補(bǔ)白:
FillLayout layout = new FillLayout();
layout.type=SWT.VERTICAL;
layout.marginHeight = 10; // 設(shè)置上下補(bǔ)白高度
layout.marginWidth = 20; // 設(shè)置左右
layout.spacing = 5;??? // 設(shè)置控件之間的空隙
shell.setLayout( layout );
顯示效果:
7.3 RowLayout(行列式布局)
RowLayout填充控件時(shí)可以折行顯示,并且可以使用RowData設(shè)置某一個(gè)指定控件的大小。
packagewww.swt.com.ch7;
import org.eclipse.swt.SWT;
public class RowLayoutSample {
public static void main(String[] args) {
Display display = new Display();
Shell shell = new Shell(display, SWT.SHELL_TRIM);
RowLayout layout = new RowLayout();
layout.type = SWT.HORIZONTAL;// 設(shè)置水平填充
layout.marginLeft = 5;// 左補(bǔ)白
layout.marginTop = 5;// 上補(bǔ)白
layout.marginRight = 5;// 右補(bǔ)白
layout.marginBottom = 5;// 下補(bǔ)白
layout.spacing = 2;// 控件的間隙
layout.wrap = true;// 是否折行顯示
layout.pack = false;// false:控件平均分配大小
layout.justify = true;// 是否充滿整個(gè)一行
shell.setLayout(layout);
new Button(shell, SWT.NONE).setText("B1");
new Button(shell, SWT.NONE).setText("Button2");
new Button(shell, SWT.NONE).setText("Wide Button3");
new Button(shell, SWT.NONE).setText("B4");
shell.layout();
shell.pack();
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
}
顯示效果:
設(shè)置控件的大小:
//?? layout.pack = false;// false:控件平均分配大小
Button b = new Button(shell, SWT.NONE);
b.setText("RowData");
b.setLayoutData(new RowData(100, 30));
顯示效果:
設(shè)置是否等寬或等高:fill屬性
當(dāng)以水平方式填充時(shí),fill屬性試圖使所用控件具有同樣高度;當(dāng)以垂直方式顯示時(shí),試圖使用所有控件具有同樣寬度。
水平填充,設(shè)置等高:layout.fill = true;
垂直填充,設(shè)置等寬:layout.fill = true;
7.4 GridLayout(網(wǎng)格式布局)
使用GridLayout布局,控件將會(huì)按照網(wǎng)格的方式進(jìn)行填充。GridLayout所放置的控件可以有一個(gè)關(guān)聯(lián)的布局?jǐn)?shù)據(jù)對象GridData。GridLayout的強(qiáng)大功能在于,可以使用GridData為每一個(gè)控件設(shè)置不同的布局。
import org.eclipse.swt.SWT;
public class GridLayoutSample {
public static void main(String[] args) {
Display display = new Display();
Shell shell = new Shell(display, SWT.SHELL_TRIM);
GridLayout gridLayout = new GridLayout();
gridLayout.numColumns = 3; //設(shè)置網(wǎng)格的列數(shù)
gridLayout.makeColumnsEqualWidth = true; //設(shè)置網(wǎng)格等寬
gridLayout.verticalSpacing = 10;
gridLayout.horizontalSpacing = 10;
shell.setLayout(gridLayout);
new Button(shell, SWT.PUSH).setText("B1");
new Button(shell, SWT.PUSH).setText("Wide Button 2");
new Button(shell, SWT.PUSH).setText("Button 3");
new Button(shell, SWT.PUSH).setText("B4");
new Button(shell, SWT.PUSH).setText("Button 5");
new Button(shell, SWT.PUSH).setText("B6");
//GridData
Button button = new Button(shell, SWT.PUSH);
button.setText("GridData");
button.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL|GridData.GRAB_HORIZONTAL));
Button b1 = new Button(shell, SWT.PUSH);
b1.setText("GridData2");
GridData gridData = new GridData();
//?? gridData.horizontalIndent = 20; // 縮進(jìn)
gridData.horizontalSpan =2; // 水平跨越兩個(gè)單元格
gridData.horizontalAlignment = SWT.FILL; //充滿
b1.setLayoutData(gridData);
Button b2 = new Button(shell, SWT.PUSH);
b2.setText("GridData3");
GridData gridData2 = new GridData();
gridData2.horizontalSpan =2; // 水平跨越兩個(gè)單元格
gridData2.verticalSpan = 2;?? // 垂直跨越兩個(gè)單元格
gridData2.horizontalAlignment = SWT.FILL; //水平充滿
gridData2.verticalAlignment = SWT.FILL;?? //垂直充滿
gridData2.grabExcessHorizontalSpace = true; //設(shè)置水平搶占
gridData2.grabExcessVerticalSpace = true; //設(shè)置垂直搶占
gridData2.minimumHeight=100; //最小高度
gridData2.minimumWidth =100; //最小寬度
gridData2.widthHint=100; //設(shè)置寬度
gridData2.heightHint=100; //設(shè)置高度
b2.setLayoutData(gridData2);
shell.layout();
shell.pack();
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
}
注意:不要重用GridData對象。每一個(gè)面板(Composite)對象中被GridLayout管理的控件必須有一個(gè)唯一的GridData對象。如果在設(shè)置布局時(shí)一個(gè)GridLayout中的控件的GridData為null,就會(huì)為它創(chuàng)建一個(gè)唯一的GridData對象。
注意:設(shè)置了widthHint和heightHint屬性后只是在程序剛一運(yùn)行時(shí)才會(huì)起作用,隨著窗口的改變,會(huì)重新計(jì)算控件大小。
顯示效果:
去掉下面兩行后的效果:
gridData2.grabExcessHorizontalSpace = true; //設(shè)置水平搶占
gridData2.grabExcessVerticalSpace = true; //設(shè)置垂直搶占
按鈕“GridData3”未隨著窗口大小調(diào)整高度。
樣式常量對照表
樣式常量 <==> 對應(yīng)屬性值
GRAB_HORIZONTAL <==> grabExcessHorizontalSpace=true
GRAB_VERTICAL <==> grabExcellVerticalSpace=true
HORIZONTAL_ALIGN_BEGINNING?? <==> horizontalAlignment=SWT.BEGINNING
HORIZONTAL_ALIGN_CENTER <==> horizontalAlignment=SWT.CENTER
HORIZONTAL_ALIGN_END <==> horizontalAlignment=SWT.END
HORIZONTAL_ALIGN_FILL <==> horizontalAlignment=SWT.FILL
VERTICAL_ALIGN_BEGINNING?? <==> verticalAlignment=SWT.BEGINNING
VERTICAL_ALIGN_CENTER <==> verticalAlignment=SWT.CENTER
VERTICAL_ALIGN_END <==> verticalAlignment=SWT.END
VERTICAL_ALIGN_FILL <==> verticalAlignment=SWT.FILL
FILL_BOTH <==> horizontalAlignment=SWT.FILL + verticalAlignment=SWT.FILL
7.5 FormLayout(表格式布局)
FormLayout通過設(shè)置FormData四邊的附加值(FormAttachment對象)來設(shè)置控件的布局。一個(gè)附加值讓一個(gè)控件指定的一邊附件到父面板容器類(Composite)的位置或者其他控件上。所以,這種布局可以指定某兩個(gè)控件的相對位置,并且能隨著窗口的改變而改變。
FormAttachment 的使用說明及示例參考:SWT 之 FormAttachment
7.6 StackLayout(堆棧式布局)
StackLayout堆棧式布局類似于選項(xiàng)卡(TabFolder),當(dāng)前只顯示最上方的控件。例如,面板上有10個(gè)文本框,面板設(shè)置為StackLayout布局,當(dāng)單擊“顯示下一個(gè)文本框”按鈕時(shí),下一個(gè)文本框就顯示出來,這樣面板中始終只有一個(gè)文本框,設(shè)置最上方顯示控件的屬性是layout.topControl。
packagewww.swt.com;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StackLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
public class testStackLayout {
/**
* @param args
*/
public static void main(String[] args) {
Display display = new Display();
Shell shell = new Shell(display);
shell.setLayout(new GridLayout());
// 創(chuàng)建放置文本框的面板
final Composite parent = new Composite(shell, SWT.NONE);
// 設(shè)置面板的布局?jǐn)?shù)據(jù)
parent.setLayoutData(new GridData(GridData.FILL_BOTH));
// 創(chuàng)建堆棧式布局
final StackLayout layout = new StackLayout();
// 將堆棧式布局應(yīng)用于模板
parent.setLayout(layout);
// 創(chuàng)建10個(gè)文本框
final Text[] textArray = new Text[10];
for (int i = 0; i < textArray.length; i++) {
textArray[i] = new Text(parent, SWT.MULTI);
textArray[i].setText("這是第 " + i + " 個(gè)文本框");
}
// 設(shè)置堆棧中當(dāng)前顯示的控件
layout.topControl = textArray[0];
Button b = new Button(shell, SWT.PUSH);
b.setText("顯示下一個(gè)文本框");
// 保存當(dāng)前顯示的文本框的索引值
final int[] index = new int[1];
// 為按鈕添加單擊事件
b.addListener(SWT.Selection, new Listener() {
@Override
public void handleEvent(Event arg0) {
// 計(jì)算出下一個(gè)文本框的索引數(shù)
index[0] = (index[0] + 1) % textArray.length;
// 設(shè)置當(dāng)前顯示的控件
layout.topControl = textArray[index[0]];
// 重新刷新布局
parent.layout();
}
});
shell.setSize(200, 150);
shell.open();
shell.layout();
//?? shell.pack();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
display.dispose();
}
}
顯示效果:
點(diǎn)擊按鈕后:
7.7 自定義布局管理器
任何布局類都是Lyaout的子類,Layout是一個(gè)抽象類,源代碼如下:
package org.eclipse.swt.widgets;
import org.eclipse.swt.graphics.*;
public abstract class Layout {
protected abstract Point computeSize (Composite composite, int wHint, int hHint, boolean flushCache);
protected boolean flushCache (Control control) {
return false;
}
protected abstract void layout (Composite composite, boolean flushCache);
}
創(chuàng)建一個(gè)自定義的布局類要繼承Layout類,并且要實(shí)現(xiàn)Layout中的抽象方法。以下代碼創(chuàng)建的是一個(gè)最簡單的自定義類MyLayout:
packagewww.swt.com;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Layout;
public class MyLayout extends Layout {
// 該方法計(jì)算面板顯示的大小
protected Point computeSize(Composite composite, int wHint, int hHint, boolean flushCache) {
return new Point(wHint, hHint);
}
// 設(shè)置子控件的位置
protected void layout(Composite composite, boolean flushCache) {
}
}
Point computeSize(Composite composite, int wHint, int hHint, boolean flushCache)方法:該方法是計(jì)算布局的大小,也就是按照一定的規(guī)則算法計(jì)算出最終布局的長和寬,其中wHint和hHint是設(shè)置默認(rèn)的寬和高。例如:當(dāng)計(jì)算出來的長和寬小于默認(rèn)的寬和高時(shí),就可以使用默認(rèn)的寬和高。flushCache參數(shù)設(shè)置是否使用緩存的數(shù)據(jù)。
void layout(Composite composite, boolean flushCache)方法:該方法是對該面板(參數(shù)Composite)中所有的控件(Control)設(shè)置顯示的具體位置,通常獲得該面板中的所有控件的方法是composite.getChildren()。這樣就可以根據(jù)指定的計(jì)算規(guī)則來放置每個(gè)控件的位置了。
綜上所述,創(chuàng)建一個(gè)自定義布局關(guān)鍵是實(shí)現(xiàn)這兩個(gè)方法,而具體布局的設(shè)置要根據(jù)設(shè)定的計(jì)算方法來實(shí)現(xiàn)。
布局計(jì)算的常用方法
1. 控件(Control)類中的常用方法
◆ 計(jì)算控件合適的大小的方法:Point computeSize(int wHint, int hHint)和Point computeSize(int wHint, int hHint, boolean changed)。例如:
Point point = control.computeSize(SWT.DEFAULT, SWT.DEFAULT);
int width = point.x;
int height = point.y;
◆ 獲得控件當(dāng)前坐標(biāo)位置的方法:Rectangle getBounds()。例如:
Rectangle rect = control.getBounds();
int left = rect.x;
int right = rect.width;
int top = rect.y;
int bottom = rect.height;
◆ 設(shè)置控件位置的方法:setBounds(int x, int y, int width, int height)或setBounds(Rectangle rect)。
2. 面板(Composite)類中的常用方法
◆ 獲得面板的大小區(qū)域的方法:Rectangle getClientArea()。
◆ 獲得所有子控件的方法:Control[] getChildren()。
◆ 獲得面板的布局對象:Layout getLayout()。
自定義布局類(BorderLayout)
BorderLayout布局將控件按東、南、西、北、中5個(gè)區(qū)域放置,每個(gè)方向最多只能放置一個(gè)控件,隨著窗口大小的改變,整個(gè)窗口會(huì)不斷撐大。
(1)創(chuàng)建一個(gè)BorderData類,該類設(shè)置控件所在位置。
packagewww.swt.com.ch7.testBorderLayout;
import org.eclipse.swt.SWT;
public final class BorderData {
public int region = SWT.CENTER; // 默認(rèn)為中間
public BorderData() {
}
public BorderData(int region) {
this.region = region;
}
}
(2)編寫最重要的BorderLayout類,該類的詳細(xì)代碼如下:
packagewww.swt.com.ch7.testBorderLayout;
import org.eclipse.swt.SWT;
public class BorderLayout extends Layout {
// 定義存放在不同位置的5個(gè)控件
private Control north;
private Control south;
private Control east;
private Control west;
private Control center;
@Override
protected Point computeSize(Composite composite, int wHint, int hHint,
boolean flushCache) {
getControls(composite);
// 定義面板的寬和高
int width = 0, height = 0;
// 計(jì)算面板的寬度
width += west == null ? 0 : getSize(west, flushCache).x;
width += east == null ? 0 : getSize(east, flushCache).x;
width += center == null ? 0 : getSize(center, flushCache).x;
// 如果上部和下部都有控件,則寬取較大值
if (north != null) {
Point pt = getSize(north, flushCache);
width = Math.max(width, pt.x);
}
if (south != null) {
Point pt = getSize(south, flushCache);
width = Math.max(width, pt.x);
}
// 計(jì)算面板的高度
height += north == null ? 0 : getSize(north, flushCache).y;
height += south == null ? 0 : getSize(south, flushCache).y;
int heightOther = center == null ? 0 : getSize(center, flushCache).y;
if (west != null) {
Point pt = getSize(west, flushCache);
heightOther = Math.max(heightOther, pt.y);
}
if (east != null) {
Point pt = getSize(east, flushCache);
heightOther = Math.max(heightOther, pt.y);
}
height += heightOther;
// 計(jì)算的寬和高與默認(rèn)的寬和高作比較,返回之中較大的
return new Point(Math.max(width, wHint), Math.max(height, hHint));
}
@Override
protected void layout(Composite composite, boolean flushCache) {
getControls(composite);
// 獲得當(dāng)前面板可顯示的區(qū)域
Rectangle rect = composite.getClientArea();
int left = rect.x, right = rect.width, top = rect.y, bottom = rect.height;
// 將各個(gè)控件放置到面板中
if (north != null) {
Point pt = getSize(north, flushCache);
north.setBounds(left, top, rect.width, pt.y);
top += pt.y;
}
if (south != null) {
Point pt = getSize(south, flushCache);
south.setBounds(left, rect.height - pt.y, rect.width, pt.y);
bottom -= pt.y;
}
if (east != null) {
Point pt = getSize(east, flushCache);
east.setBounds(rect.width - pt.x, top, pt.x, (bottom - top));
right -= pt.x;
}
if (west != null) {
Point pt = getSize(west, flushCache);
west.setBounds(left, top, pt.x, (bottom - top));
left += pt.x;
}
if (center != null) {
center.setBounds(left, top, (right - left), (bottom - top));
}
}
// 計(jì)算某一控件當(dāng)前的大小,長和寬
protected Point getSize(Control control, boolean flushCache) {
return control.computeSize(SWT.DEFAULT, SWT.DEFAULT, flushCache);
}
// 設(shè)置該類中每個(gè)位置控件的屬性的方法
protected void getControls(Composite composite) {
// 獲得當(dāng)前面板中所有的控件對象
Control[] children = composite.getChildren();
// 循環(huán)所有控件,并將每個(gè)控件所放的位置對號(hào)入座
for (int i = 0; i < children.length; i++) {
Control child = children[i];
BorderData borderData = (BorderData) child.getLayoutData();
if (borderData.region == SWT.TOP) {
north = child;
} else if (borderData.region == SWT.BOTTOM) {
south = child;
} else if (borderData.region == SWT.RIGHT) {
east = child;
} else if (borderData.region == SWT.LEFT) {
west = child;
} else {
center = child;
}
}
}
}(3)最后創(chuàng)建一個(gè)測試類:
packagewww.swt.com.ch7.testBorderLayout;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
public class TestBorderLayout {
/**
* @param args
*/
public static void main(String[] args) {
Display display = new Display();
Shell shell = new Shell(display);
shell.setSize(200, 150);
shell.setLayout(new BorderLayout());
Button buttonWest = new Button(shell, SWT.PUSH);
buttonWest.setText("左");
buttonWest.setLayoutData(new BorderData(SWT.LEFT));
Button buttonEast = new Button(shell, SWT.PUSH);
buttonEast.setText("右");
buttonEast.setLayoutData(new BorderData(SWT.RIGHT));
Button buttonNorth = new Button(shell, SWT.PUSH);
buttonNorth.setText("上");
buttonNorth.setLayoutData(new BorderData(SWT.TOP));
Button buttonSouth = new Button(shell, SWT.PUSH);
buttonSouth.setText("下");
buttonSouth.setLayoutData(new BorderData(SWT.BOTTOM));
Text text = new Text(shell, SWT.MULTI);
text.setText("中間");
text.setLayoutData(new BorderData());
shell.pack();
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
display.dispose();
}
}
顯示效果:
拖放后的效果:
總結(jié)
以上是生活随笔為你收集整理的java swt 布局管理器_JAVA.SWT/JFace: SWT布局管理器的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python脚本猜解网站登录密码(带to
- 下一篇: Python暴力破解网站登录密码脚本