??xml version="1.0" encoding="utf-8" standalone="yes"?>
先启动Activity1q行序为: Activity1 onCreate -> Activity1 onStart -> Activity1 onResume
用Intent从Activity1跛_Activity2q行序 Q?nbsp;
Activity1 onPause -> Activity2 onCreate -> Activity2 onStart -> Activity2 onResume ->Activity1 onStop -> Activity1 onDestroy
退出应用程序: Activity2 onResume ->Activity2 onStop -> Activity2 onDestroy
]]>
public class Test3 {
public static void main(String[] args) throws IOException {
final Test obj = new Test();
new Thread()
{
public void run()
{
obj.m1();
}
}.start();
new Thread()
{
public void run()
{
obj.m2();
}
}.start();
new Thread()
{
public void run()
{
obj.m3();
}
}.start();
}
}
class Test
{
static int count;
volatile int target = 1;
synchronized void m1()
{
for (int i = 0; i < 10; i++)
{
while (target == 2 || target == 3)
{
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("m1() =" + i);
target = 2;
notifyAll();
}
}
synchronized void m2()
{
for (int i = 0; i < 10; i++)
{
while (target == 1 || target == 3)
{
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("m2() =" + i);
target = 3;
notifyAll();
}
}
synchronized void m3()
{
for (int i = 0; i < 10; i++)
{
while (target == 1 || target == 2)
{
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("m3() =" + i);
target = 1;
notifyAll();
}
}
}
U程从创建、运行到l束L处于下面五个状态之一Q新建状态、就l状态、运行状态、阻塞状态及M状态?/p>
一个新创徏的线Eƈ不自动开始运行,要执行线E,必须调用U程?/span>start()Ҏ。当U程对象调用start()Ҏ卛_动了U程Q?/span>start()Ҏ创徏U程q行的系l资源,q调度线E运?/span>run()Ҏ。当start()Ҏq回后,U程处于就l状态?/span> 处于qA状态的U程q不一定立卌?/span>run()ҎQ线E还必须同其他线E竞?/span>CPU旉Q只有获?/span>CPU旉才可以运行线E。因为在?/span>CPU的计机pȝ中,不可能同时运行多个线E,一个时M有一个线E处于运行状态。因此此时可能有多个U程处于qA状态。对多个处于qA状态的U程是由Javaq行时系l的U程调度E序(thread scheduler)来调度的?br /> 当线E获?/span>CPU旉后,它才q入q行状态,真正开始执?/span>run()Ҏ. U程q行q程中,可能׃各种原因q入d状? 有两个原因会DU程MQ?br /> 1) runҎ正常退自然死亡, Java的每个线E都有一个优先Q当有多个线E处于就l状态时Q线E调度程序根据线E的优先U调度线E运行?/span> 可以用下面方法设|和q回U程的优先?/span> · public final void setPriority(int newPriority) 讄U程的优先?/span> · public final int getPriority() q回U程的优先?/span> newPriority为线E的优先U,其取gؓ1?/span>10之间的整敎ͼ也可以?/span>Threadcd义的帔R来设|线E的优先U,q些帔R分别为:Thread.MIN_PRIORITY?/span>Thread.NORM_PRIORITY?/span>Thread.MAX_PRIORITYQ它们分别对应于U程优先U的1?/span>5?/span>10Q数D大优先高。当创徏JavaU程Ӟ如果没有指定它的优先U,则它从创U程那里l承优先U?/span> 一般来_只有在当前线E停止或׃某种原因被阻塞,较低优先U的U程才有Zq行?/span> 前面说过多个U程可ƈ发运行,然而实际上q不Lq样。由于很多计机都是?/span>CPU的,所以一个时d能有一个线E运行,多个U程的ƈ发运行只是觉。在?/span>CPU机器上多个线E的执行是按照某U顺序执行的Q这UCؓU程的调?/span>(scheduling)?/span> 大多数计机仅有一?/span>CPUQ所以线E必M其他U程׃nCPU。多个线E在单个CPU是按照某U顺序执行的。实际的调度{略随系l的不同而不同,通常U程调度可以采用两种{略调度处于qA状态的U程?/span> (1) 抢占式调度策?/span> Javaq行时系l的U程调度法是抢占式?/span> (preemptive)?/span>Javaq行时系l支持一U简单的固定优先U的调度法。如果一个优先比其他Q何处于可q行状态的U程都高的线E进入就l状态,那么q行时系l就会选择该线E运行。新的优先较高的线E抢?/span>(preempt)了其他线E。但?/span>Javaq行时系lƈ不抢占同优先U的U程。换句话_Javaq行时系l不是分时的(time-slice)。然而,ZJava Threadcȝ实现pȝ可能是支持分时的Q因此编写代码时不要依赖分时。当pȝ中的处于qA状态的U程都具有相同优先ӞU程调度E序采用一U简单的、非抢占式的轮{的调度顺序?/span> (2) 旉片轮转调度策?/span> 有些pȝ的线E调度采用时间片轮{(round-robin)调度{略。这U调度策略是从所有处于就l状态的U程中选择优先U最高的U程分配一定的CPU旉q行。该旉q后再选择其他U程q行。只有当U程q行l束、放?/span>(yield)CPU或由于某U原因进入阻塞状态,低优先的线E才有机会执行。如果有两个优先U相同的U程都在{待CPUQ则调度E序以轮转的方式选择q行的线E?/p>
一个线E在其生命周期中可以从一U状态改变到另一U状态,U程状态的变迁如图所C: 当一个新建的U程调用它的start()Ҏ后即q入qA状态,处于qA状态的U程被线E调度程序选中可以获?/span>CPU旉Q进入运行状态,该线E就开始运?/span>run()Ҏ?/span> 控制U程的结束稍微复杂一炏V如果线E的run()Ҏ是一个确定次数的循环Q则循环l束后,U程q行q束了Q线E对象即q入M状态。如?/span>run()Ҏ是一个不定循环Q早期的Ҏ是调用线E对象的stop()ҎQ然而由于该Ҏ可能DU程死锁Q因此从1.1版开始,不推荐用该Ҏl束U程。一般是通过讄一个标志变量,在程序中改变标志变量的值实现结束线E。请看下面的例子Q?/span> E序 ThreadStop.java 该程序在TimercM定义了一个布变?/span>flagQ同时定义了一?/span>stopRun()ҎQ在其中该变量讄?/span>false。在ȝ序中通过调用该方法,从而改变该变量的|使得run()Ҏ?/span>while循环条g不满I从而实现结束线E的q行?/span> 说明 ?/span>ThreadcM除了stop()Ҏ被标注ؓ不推?/span>(deprecated) 使用外,suspend()Ҏ?/span>resume()Ҏ也被标明不推荐用,q两个方法原来用作线E的挂v和恢? 处于q行状态的U程除了可以q入M状态外Q还可能q入qA状态和d状态。下面分别讨两种情况Q?/span> (1) q行状态到qA状?/span> 处于q行状态的U程如果调用?/span>yield()ҎQ那么它放?/span>CPU旉Q当前正在q行的线E进入就l状态。这时有几种可能的情况:如果没有其他的线E处于就l状态等待运行,该线E会立即l箋q行Q如果有{待的线E,此时U程回到qA状态状态与其他U程竞争CPU旉Q当有比该线E优先高的U程Ӟ高优先的线E进入运行状态,当没有比该线E优先高的U程Ӟ但有同优先的线E,则由U程调度E序来决定哪个线E进入运行状态,因此U程调用yield()Ҏ只能?/span>CPU旉让给h同优先的或高优先的线E而不能让l低优先U的U程?/span> 一般来_在调用线E的yield()Ҏ可以使耗时的线E暂停执行一D|_使其他线E有执行的机会?/span> (2) q行状态到d状?/span> 有多U原因可使当前运行的U程q入d状态,q入d状态的U程当相应的事gl束或条件满xq入qA状态。ɾU程q入d状态可能有多种原因Q?/span> ① U程调用?/span>sleep()ҎQ线E进入睡眠状态,此时该线E停止执行一D|间。当旉到时该线E回到就l状态,与其他线E竞?/span>CPU旉?/span> ThreadcM定义了一?/span>interrupt()Ҏ。一个处于睡眠中的线E若调用?/span>interrupt()ҎQ该U程立即l束睡眠q入qA状态?/span> ② 如果一个线E的q行需要进?/span>I/O操作Q比如从键盘接收数据Q这时程序可能需要等待用L输入Q这时如果该U程一直占?/span>CPUQ其他线E就得不到运行。这U情늧?/span>I/Od。这时该U程׃dq行状态而进入阻塞状态?/span>Java语言的所?/span>I/OҎ都具有这U行为?/span> ③ 有时要求当前U程的执行在另一个线E执行结束后再l执行,q时可以调用join()Ҏ实现Q?/span>join()Ҏ有下面三U格式: · public void join() throws InterruptedException 使当前线E暂停执行,{待调用该方法的U程l束后再执行当前U程?/span> · public void join(long millis) throws InterruptedException 最多等?/span>millis毫秒后,当前U程l箋执行?/span> · public void join(long millis, int nanos) throws InterruptedException 可以指定多少毫秒、多纳U后l箋执行当前U程?/span> 上述Ҏ使当前线E暂停执行,q入d状态,当调用线E结束或指定的时间过后,当前U程U程q入qA状态,例如执行下面代码Q?/span> t.join(); 当前U程q入d状态,当线E?/span>t执行l束后,当前U程才能l箋执行?/span> ④ U程调用?/span>wait()ҎQ等待某个条件变量,此时该线E进入阻塞状态。直到被通知(调用?/span>notify()?/span>notifyAll()Ҏ)l束{待后,U程回到qA状态?/span> ⑤ 另外如果U程不能获得对象锁,也进入就l状态?/span> 后两U情况在下一节讨论?/span>
1.新徏状?New)Q?nbsp;
当用new操作W创Z个线E时Q?例如new Thread(r)Q线E还没有开始运行,此时U程处在新徏状态?当一个线E处于新生状态时Q程序还没有开始运行线E中的代?br />
2.qA状?/span>(Runnable)
3.q行状?/span>(Running)
4. d状?/span>(Blocked)
1>U程通过调用sleepҎq入睡眠状态;
2>U程调用一个在I/O上被d的操作,卌操作在输入输出操作完成之前不会返回到它的调用者;
3>U程试图得到一个锁Q而该锁正被其他线E持有;
4>U程在等待某个触发条Ӟ
......
所谓阻塞状态是正在q行的线E没有运行结束,暂时让出CPUQ这时其他处于就l状态的U程可以获?/span>CPU旉Q进入运行状态?br />
5. M状?/span>(Dead)
2) 一个未捕获的异常终止了runҎ而ɾU程猝死?br /> Z定U程在当前是否存zȝQ就是要么是可运行的Q要么是被阻塞了Q,需要用isAliveҎ。如果是可运行或被阻塞,q个Ҏq回trueQ?如果U程仍旧是new状态且不是可运行的Q?或者线E死亡了Q则q回false.2, U程的优先和调?/span>
3. U程状态的改变
1> 控制U程的启动和l束
class Timer implements Runnable{
boolean flag=true;
public void run(){
while(flag){
System.out.print("\r\t"+new Date()+"");
try{
Thread.sleep(1000);
}catch(InterruptedException e){}
}
System.out.println("\n"+Thread.currentThread().getName()+" Stop");
}
public void stopRun(){
flag = false;
}
}
public class ThreadStop{
public static void main(String args[]){
Timer timer = new Timer();
Thread thread = new Thread(timer);
thread.setName("Timer");
thread.start();
for(int i=0;i<100;i++){
System.out.print("\r"+i);
try{
Thread.sleep(100);
}catch(InterruptedException e){}
}
timer.stopRun();
}
}
2> U程d条g
多线E是一个程序中可以有多D代码同时运行,那么q些代码写在哪里Q如何创建线E对象呢?
首先Q我们来?/span>Java语言实现多线E编E的cd接口。在java.lang包中定义?/span>Runnable接口?/span>ThreadcR?/span>
Runnable接口中只定义了一个方法:
· public abstract void run()
q个Ҏ要由实现?/span>Runnable接口的类实现?/span>Runnable对象UCؓ可运行对象,一个线E的q行是执行该对象的run()Ҏ?/span>
ThreadcdCRunnable接口Q因?/span>Thread对象也是可运行对象。同?/span>ThreadcM是线E类Q该cȝ常用构造方法如下:
· public Thread()
· public Thread(Runnable target)
· public Thread(String name)
· public Thread(Runnable target, String name)
target为线E运行的目标对象Q即U程调用start()Ҏ启动后运行那个对象的run()ҎQ该对象的类型ؓRunnableQ若没有指定目标对象Q则以当前类对象为目标对象,name为线E名
介绍下如何创建和q行U程的两U方法。线E运行的代码是实现?/span>Runnable接口的类?/span>run()Ҏ或者是Threadcȝ子类?/span>run()ҎQ因此构造线E体有两种ҎQ?br /> · l承Threadcdƈ覆盖它的run()ҎQ?br /> · 实现Runnable接口q实现它?/span>run()Ҏ?/p>
通过l承Threadc,q覆?/span>run()ҎQ这时就可以用该cȝ实例作ؓU程的目标对象。下面的E序定义?/span>SimpleThreadc,它承了Threadcdƈ覆盖?/span>run()Ҏ?/span> E序SimpleThread.java public class SimpleThread extends Thread{ public SimpleThread(String str){ super(str); } public void run(){ for(int i=0; i<100; i++){ System.out.println(getName()+" = "+ i); try{ sleep((int)(Math.random()*100)); }catch(InterruptedException e){} } System.out.println(getName()+ " DONE"); } } _____________________________________________________________________________▃ SimpleThreadcȝ承了Threadc,q覆盖了run()ҎQ该Ҏ是U程体?/span> E序 ThreadTest.java public class ThreadTest{ public static void main(String args[]){ Thread t1 = new SimpleThread("Runner A"); Thread t2 = new SimpleThread("Runner B"); t1.start(); t2.start(); } } _____________________________________________________________________________▃ ?/span>ThreadTestcȝmain()Ҏ中创Z两个SimpleThreadcȝU程对象q调用线E类?/span>start()Ҏ启动U程。构造线E时没有指定目标对象Q所以线E启动后执行本类?/span>run()Ҏ?/span> 注意Q实际上ThreadTestE序中有三个U程同时q行Q在应用E序?/span>main()Ҏ启动ӞJVM创Z个主U程Q在ȝE中可以创徏其他U程?br /> 可以定义一个类实现Runnable接口Q然后将该类对象作ؓU程的目标对象。实?/span>Runnable接口是实现run()Ҏ?/span> 下面E序通过实现Runnable接口构造线E体?span lang="EN-US"> 1Q?/font>l承Threadcd建线E?/span>
2Q?/font>实现Runnable接口创徏U程
E序 ThreadTest.java
class T1 implements Runnable{
public void run(){
for(int i=0;i<15;i++)
System.out.println("Runner A="+i);
}
}
class T2 implements Runnable{
public void run(){
for(int j=0;j<15;j++)
System.out.println("Runner B="+j);
}
}
public class ThreadTest{
public static void main(String args[]){
Thread t1=new Thread(new T1(),"Thread A");
Thread t2=new Thread(new T2(),"Thread B");
t1.start();
t2.start();
}
}
_____________________________________________________________________________▃
在实际开发过E中会经怋用JTreelgQ^时会遇到q样或那L问题Q在此将偶得一点经验写下来Q与大家׃nQ希望对大家有所帮助?/p>
private JTree jtNetDevice;//数组件申?br /> private JScrollPane jspTree;//滚动面板x
1、初始化
DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode("root");
jtNetDevice = new JTree(rootNode);
jtNetDevice.setAutoscrolls(true);
getTreeSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);//讄单选模?br />
jspTree = new JScrollPane();
jspTree.getViewport().add(jtNetDevice, null);
2、三个经怋用的取值函?/strong>
private DefaultTreeModel getTreeModel(){
return (DefaultTreeModel)jtNetDevice.getModel();
}
private DefaultMutableTreeNode getRootNode(){
return (DefaultMutableTreeNode)getTreeModel().getRoot();
}
private TreeSelectionModel getTreeSelectionModel(){
return jtNetDevice.getSelectionModel();
}
3、根据node得到pathQ?br /> TreePath visiblePath = new TreePath(getTreeModel().getPathToRoot(node));
4、根据Path展开到该节点
jtNetDevice.makeVisible(visiblePath);
5、根据path讑֮该节炚w定
jtNetDevice.setSelectionPath(visiblePath);
6、选中节点的方?br />
首先Q根据节点得到树路径Q其中chosen为需要选中的节?br />
TreePath visiblePath = new TreePath( ( (DefaultTreeModel) jtNetDevice.getModel()).
getPathToRoot(chosen));
然后ҎPath选中该节?br />
jtNetDevice.setSelectionPath(visiblePath);
7、滚动到可见位置
jtNetDevice.scrollPathToVisible(visiblePath);
8、给JTreed右键弹出菜单
void jtNetDevice_mouseReleased(MouseEvent e) {
if (e.isPopupTrigger()) {
jPopupMenu1.show(e.getComponent(), e.getX(), e.getY());//弹出右键菜单
}
}
9、关于JTree的展开
// If expand is true, expands all nodes in the tree.
// Otherwise, collapses all nodes in the tree.
public void expandAll(JTree tree, boolean expand) {
TreeNode root = (TreeNode)tree.getModel().getRoot();
// Traverse tree from root
expandAll(tree, new TreePath(root), expand);
}
private void expandAll(JTree tree, TreePath parent, boolean expand) {
// Traverse children
TreeNode node = (TreeNode)parent.getLastPathComponent();
if (node.getChildCount() >= 0) {
for (Enumeration e=node.children(); e.hasMoreElements(); ) {
TreeNode n = (TreeNode)e.nextElement();
TreePath path = parent.pathByAddingChild(n);
expandAll(tree, path, expand);
}
}
// Expansion or collapse must be done bottom-up
if (expand) {
tree.expandPath(parent);
} else {
tree.collapsePath(parent);
}
}
10、如何遍历JTree
// 创徏?br />
JTree tree = new JTree();
// d树节?.....
// 遍历所有节?br />
visitAllNodes(tree);
// 仅遍历展开的节?br />
visitAllExpandedNodes(tree);
// Traverse all nodes in tree
public void visitAllNodes(JTree tree) {
TreeNode root = (TreeNode)tree.getModel().getRoot();
visitAllNodes(root);
}
public void visitAllNodes(TreeNode node) {
// node is visited exactly once
process(node);
if (node.getChildCount() >= 0) {
for (Enumeration e=node.children(); e.hasMoreElements(); ) {
TreeNode n = (TreeNode)e.nextElement();
visitAllNodes(n);
}
}
}
// Traverse all expanded nodes in tree
public void visitAllExpandedNodes(JTree tree) {
TreeNode root = (TreeNode)tree.getModel().getRoot();
visitAllExpandedNodes(tree, new TreePath(root));
}
public void visitAllExpandedNodes(JTree tree, TreePath parent) {
// Return if node is not expanded
if (!tree.isVisible(parent)) {
return;
}
// node is visible and is visited exactly once
TreeNode node = (TreeNode)parent.getLastPathComponent();
process(node);
// Visit all children
if (node.getChildCount() >= 0) {
for (Enumeration e=node.children(); e.hasMoreElements(); ) {
TreeNode n = (TreeNode)e.nextElement();
TreePath path = parent.pathByAddingChild(n);
visitAllExpandedNodes(tree, path);
}
}
}
今天l于耐着性子弄懂了GridBagLayout是怎么使用的?br />
构造函敎ͼ
GirdBagLayout()建立一个新的GridBagLayout理器?br />
GridBagConstraints()建立一个新的GridBagConstraints对象?br />
GridBagConstraints(int gridx,int gridy,
int gridwidth,int gridheight,
double weightx,double weighty,
int anchor,int fill, Insets insets,
int ipadx,int ipady)建立一个新的GridBagConstraints对象Qƈ指定其参数的倹{?br />
看着q一堆的参数快烦死了,下面׃解一下参数的意思:
参数说明Q?br />
gridx,gridy —?nbsp; 讄lg的位|,
gridx讄为GridBagConstraints.RELATIVE代表此组件位于之前所加入lg的右辏V?br />
gridy讄为GridBagConstraints.RELATIVE代表此组件位于以前所加入lg的下面?br />
定义出gridx,gridy的位|以便以后维护程序。gridx=0,gridy=0时放??列?/p>
gridwidth,gridheight —?nbsp; 用来讄lg所占的单位长度与高度,默认值皆??br /> 你可以用GridBagConstraints.REMAINDER帔RQ代表此lg为此行或此列的最后一个组Ӟ而且会占据所有剩余的I间?/p>
weightx,weighty —?nbsp; 用来讄H口变大Ӟ各组件跟着变大的比例?br /> 当数字越大,表示lg能得到更多的I间Q默认值皆??/p>
anchor —?nbsp; 当组件空间大于组件本w时Q要组件置于何处?br /> 有CENTER(默认?、NORTH、NORTHEAST、EAST、SOUTHEAST、WEST、NORTHWEST选择?/p>
insets —?nbsp; 讄lg之间彼此的间距?br /> 它有四个参数Q分别是上,左,下,叻I默认?0,0,0,0)?/p>
ipadx,ipady —?nbsp; 讄lg间距Q默认gؓ0?/p>
GridBagLayout里的各种讄都必通过GridBagConstraintsQ因此当我们GridBagConstraints的参数都讄
好了之后Q必new一个GridBagConstraints的对象出来,以便GridBagLayout使用?/p>
代码片断Q?br />
JButton b;
GridBagConstraints c;
int gridx,gridy,gridwidth,gridheight,anchor,fill,ipadx,ipady;
double weightx,weighty;
Insets inset;
JFrame f=new JFrame();
GridBagLayout gridbag=new GridBagLayout();
Container contentPane=f.getContentPane();
contentPane.setLayout(gridbag);
b=new JButton("first");
gridx=0;
gridy=0;
gridwidth=1;
gridheight=1;
weightx=10;
weighty=1;
anchor=GridBagConstraints.CENTER;
fill=GridBagConstraints.HORIZONTAL;
inset=new Insets(0,0,0,0);
ipadx=0;
ipady=0;
c=new GridBagConstraints(gridx,gridy,gridwidth,gridheight,weightx,weighty,anchor,fill,inset,ipadx,ipady);
gridbag.setConstraints(b,c);
contentPane.add(b);
GridBagLayoutq种理器是十分灉|的,只不q他写v来比较麻烦,不过用了之后才发C对界面的部v帮助很大?br />
本文来自CSDN博客Q{载请标明出处Qhttp://blog.csdn.net/dracularking/archive/2008/04/22/2314336.aspx
正如你所看到的,最l的l果看上d计划的想法完全一栗?/p>
你应该能看到在草N有一些线Q这些线是用来把ȝ面分成若q行和列的,q样你就很清楚每一个组件放|的格子位置。这是GridBagLayout??的那一部分Q而图上的数字是格的L?/p>
在某U意义上? 我们可以把GridBagLayout惌成ؓ早些q的HTML3?Q它们都是基于表的布局QGrid的概念就cMrowspan和colspan的意思,只不q换了个名字|了?/p>
随着我们的界面和表格的设|完成,是时候该q行界面布局q开始写代码了?/p>
工作q程
q一节我假定你已l了解了基本的窗口和lg创徏知识?/p>
通过q篇文章我们最l能在一个frame中布局lgQ我们将在以后的文章对界面进行改q它更适用。因?Z了解q整个工作的q程Q我们列Z所有的目标代码?/p>
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class GridBagWindow extends JFrame {
private JButton searchBtn;
private JComboBox modeCombo;
private JLabel tagLbl;
private JLabel tagModeLbl;
private JLabel previewLbl;
private JTable resTable;
private JTextField tagTxt;
public GridBagWindow() {
Container contentPane = getContentPane();
GridBagLayout gridbag = new GridBagLayout();
contentPane.setLayout(gridbag);
GridBagConstraints c = new GridBagConstraints();
//setting a default constraint value
c.fill =GridBagConstraints.HORIZONTAL;
tagLbl = new JLabel("Tags");
c.gridx = 0; //x grid position
c.gridy = 0; //y grid position
gridbag.setConstraints(tagLbl, c); //associate the label with a constraint object
contentPane.add(tagLbl); //add it to content pane
tagModeLbl = new JLabel("Tag Mode");
c.gridx = 0;
c.gridy = 1;
gridbag.setConstraints(tagModeLbl, c);
contentPane.add(tagModeLbl);
tagTxt = new JTextField("plinth");
c.gridx = 1;
c.gridy = 0;
c.gridwidth = 2;
gridbag.setConstraints(tagTxt, c);
contentPane.add(tagTxt);
String[] options = {"all", "any"};
modeCombo = new JComboBox(options);
c.gridx = 1;
c.gridy = 1;
c.gridwidth = 1;
gridbag.setConstraints(modeCombo, c);
contentPane.add(modeCombo);
searchBtn = new JButton("Search");
c.gridx = 1;
c.gridy = 2;
gridbag.setConstraints(searchBtn, c);
contentPane.add(searchBtn);
resTable = new JTable(5,3);
c.gridx = 0;
c.gridy = 3;
c.gridwidth = 3;
gridbag.setConstraints(resTable, c);
contentPane.add(resTable);
previewLbl = new JLabel("Preview goes here");
c.gridx = 0;
c.gridy = 4;
gridbag.setConstraints(previewLbl, c);
contentPane.add(previewLbl);
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
public static void main(String args[]) {
GridBagWindow window = new GridBagWindow();
window.setTitle("GridBagWindow");
window.pack();
window.setVisible(true);
}
}
构造方法前的代码都不是很特D,都是一些相当标准的import和变量定义。但是进入构造方法后Q事情就变得有趣了?/p>
Container contentPane = getContentPane();
GridBagLayout gridbag = new GridBagLayout();
contentPane.setLayout(gridbag);
我们以GridBagWindow的内定w板作为开始来创徏一个GridBagLayout对象Q准地_q个Ҏ与过L们所创徏 GridLayout对象和BorderLayout对象的方法是一L。那么,现在我们开始来讄GridBagLayout对象使它作ؓ内容面板?布局?/p>
GridBagConstraints c = new GridBagConstraints();
然后我要提到q整个进E中的一个独特的对象Q那是GridBagConstraints。这个对象在GridBagLayout中控制所 有被安置在其中组件的U束。ؓ了把一个组件增加到你的GridBagLayout中去Q你首先必须它与一个GridBagConstraints对象?立连接?/p>
GridBagConstraints可以?1个方面来q行控制和操U,也可以给你提供一些帮助。这些内ҎQ?/p>
可能对于一个组件的每一个实例你都需要ؓ它徏立一个单独的GridBagConstraintsQ然而,q种Ҏ我们q不推荐使用。最好的Ҏ是,当你调用它的时候把对象讄为默认|然后针对于每一个组件改变其相应的域?/p>
q个Ҏh通用性,因ؓ在一些域中,比如insets、padx、pady和fillq些域,对于每一个组件来说一般都是相同的Q因此这样对一个域q行讄׃更轻松了Q也能更L的在另外的组件中改变某些域的倹{?/p>
如果在改变了某些域g后,你想回到原始的域值的话,你应该在增加下一个组件之前进行改变。这U方法你更Ҏ明白你正在修改的内容Q也能你更Ҏ明白在一q串对象中的q?1个参数的作用?/p>
也许你现在对q些内容q是一知半解,不过事实上一旦你理解了GridBagConstraintsQ值得安慰的是你以后做再困隄工作都会游刃有余了?/p>
所以,如果我们已经明白了GridBagConstraints的详l用法了Q那么现在就让我们来看看在实际应用中应该如何来实现它Q?/p>
tagLbl = new JLabel("Tags");
c.gridx = 0; //x grid position
c.gridy = 0; //y grid position
gridbag.setConstraints(tagLbl, c); //讄标签的限?/p>
contentPane.add(tagLbl); //增加到内定w?/p>
我们所做的是示例我们的标签、分配给它一个格位置Q将它与一个约束对象联pv来ƈ把它增加到我们的内容面板中?/p>
tagModeLbl = new JLabel("Tag Mode");
c.gridx = 0;
c.gridy = 1;
gridbag.setConstraints(tagModeLbl, c);
contentPane.add(tagModeLbl);
h意,虽然我们已经在我们的U束对象中把gridx的D|ؓ0Q但是在q里我们仍然要对它进行重新设|——这样做没有其它原因Q只是ؓ了增加可L?/p>
下面Q我们增加一个文本域以便能存储我们希望能搜烦到的关键字,再增加一个组合框以便用来搜烦多个关键字。除了我们希望的文本域有两列之外Q这个概念其他的斚w都与上面所说的是相同的Q所以,我们需要在增加l合框之前重新设|文本域的倹{?/p>
tagTxt = new JTextField("plinth");
c.gridx = 1;
c.gridy = 0;
c.gridwidth = 2;
gridbag.setConstraints(tagTxt, c);
contentPane.add(tagTxt);
String[] options = {"all", "any"};
modeCombo = new JComboBox(options);
c.gridx = 1;
c.gridy = 1;
c.gridwidth = 1;
gridbag.setConstraints(modeCombo, c);
contentPane.add(modeCombo);
做了q些之后Q我们再在内定w板中增加一些其余的单组Ӟq时候我们就能够览它了Q其余的代码应该不会出现M问题了?/p>
到这个阶D,我们应该已经得到了一个类g我们先前所设计的界面了?/p>