java something

          不要以為......很遙遠
          隨筆 - 23, 文章 - 1, 評論 - 2, 引用 - 0
          數據加載中……

          2011年9月2日

          Activity生命周期

          現有兩個Activity:  Activity1,Activity2

          先啟動Activity1運行順序為: Activity1 onCreate -> Activity1 onStart -> Activity1 onResume
          用Intent從Activity1跳到Activity2運行順序 : 
          Activity1 onPause -> Activity2 onCreate -> Activity2 onStart -> Activity2 onResume ->Activity1 onStop -> Activity1  onDestroy
          退出應用程序: Activity2 onResume ->Activity2 onStop -> Activity2  onDestroy

          posted @ 2011-09-02 17:48 Jamie 閱讀(229) | 評論 (0)編輯 收藏

          控制3個線程運行順序的Demo

          本程序可以控制3個線程按順序執行, 代碼如下:

          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();
            }
           }
          }

          posted @ 2011-09-02 02:27 Jamie 閱讀(1777) | 評論 (2)編輯 收藏

          線程的同步與共享

               摘要: 線程的同步與共享 前面程序中的線程都是獨立的、異步執行的線程。但在很多情況下,多個線程需要共享數據資源,這就涉及到線程的同步與資源共享的問題。 1 資源沖突 下面的例子說明,多個線程共享資源,如果不加以控制可能會產生沖突。 程序CounterTest.java   Code highlighting produced by Actipro CodeHighlight...  閱讀全文

          posted @ 2011-09-02 01:38 Jamie 閱讀(484) | 評論 (0)編輯 收藏

          2011年9月1日

          線程的狀態與調度

            1,線程的生命周期

                  線程從創建、運行到結束總是處于下面五個狀態之一:新建狀態、就緒狀態、運行狀態、阻塞狀態及死亡狀態。



              1.新建狀態(New): 
                  當用new操作符創建一個線程時, 例如new Thread(r),線程還沒有開始運行,此時線程處在新建狀態。 當一個線程處于新生狀態時,程序還沒有開始運行線程中的代碼

               2.就緒狀態(Runnable)

                  一個新創建的線程并不自動開始運行,要執行線程,必須調用線程的start()方法。當線程對象調用start()方法即啟動了線程,start()方法創建線程運行的系統資源,并調度線程運行run()方法。當start()方法返回后,線程就處于就緒狀態。

                  處于就緒狀態的線程并不一定立即運行run()方法,線程還必須同其他線程競爭CPU時間,只有獲得CPU時間才可以運行線程。因為在單CPU的計算機系統中,不可能同時運行多個線程,一個時刻僅有一個線程處于運行狀態。因此此時可能有多個線程處于就緒狀態。對多個處于就緒狀態的線程是由Java運行時系統的線程調度程序(thread scheduler)來調度的。

              3.運行狀態(Running)

                  當線程獲得CPU時間后,它才進入運行狀態,真正開始執行run()方法.

              
          4. 阻塞狀態(Blocked)

                  線程運行過程中,可能由于各種原因進入阻塞狀態:
                  1>線程通過調用sleep方法進入睡眠狀態;
                  2>線程調用一個在I/O上被阻塞的操作,即該操作在輸入輸出操作完成之前不會返回到它的調用者;
                  3>線程試圖得到一個鎖,而該鎖正被其他線程持有;
                  4>線程在等待某個觸發條件;
                  ......           

                  所謂阻塞狀態是正在運行的線程沒有運行結束,暫時讓出
          CPU,這時其他處于就緒狀態的線程就可以獲得CPU時間,進入運行狀態。

              5. 死亡狀態(Dead)

                  有兩個原因會導致線程死亡:
                  1) run方法正常退出而自然死亡,
                  2) 一個未捕獲的異常終止了run方法而使線程猝死。
                  為了確定線程在當前是否存活著(就是要么是可運行的,要么是被阻塞了),需要使用isAlive方法。如果是可運行或被阻塞,這個方法返回true; 如果線程仍舊是new狀態且不是可運行的, 或者線程死亡了,則返回false.




          2,  線程的優先級和調度

          Java的每個線程都有一個優先級,當有多個線程處于就緒狀態時,線程調度程序根據線程的優先級調度線程運行。

          可以用下面方法設置和返回線程的優先級。

              · public final void setPriority(int newPriority) 設置線程的優先級。

              · public final int getPriority() 返回線程的優先級。

          newPriority為線程的優先級,其取值為110之間的整數,也可以使用Thread類定義的常量來設置線程的優先級,這些常量分別為:Thread.MIN_PRIORITYThread.NORM_PRIORITYThread.MAX_PRIORITY,它們分別對應于線程優先級的1510,數值越大優先級越高。當創建Java線程時,如果沒有指定它的優先級,則它從創建該線程那里繼承優先級。

          一般來說,只有在當前線程停止或由于某種原因被阻塞,較低優先級的線程才有機會運行。

          前面說過多個線程可并發運行,然而實際上并不總是這樣。由于很多計算機都是單CPU的,所以一個時刻只能有一個線程運行,多個線程的并發運行只是幻覺。在單CPU機器上多個線程的執行是按照某種順序執行的,這稱為線程的調度(scheduling)

          大多數計算機僅有一個CPU,所以線程必須與其他線程共享CPU。多個線程在單個CPU是按照某種順序執行的。實際的調度策略隨系統的不同而不同,通常線程調度可以采用兩種策略調度處于就緒狀態的線程。

          (1) 搶占式調度策略

               Java運行時系統的線程調度算法是搶占式的 (preemptive)Java運行時系統支持一種簡單的固定優先級的調度算法。如果一個優先級比其他任何處于可運行狀態的線程都高的線程進入就緒狀態,那么運行時系統就會選擇該線程運行。新的優先級較高的線程搶占(preempt)了其他線程。但是Java運行時系統并不搶占同優先級的線程。換句話說,Java運行時系統不是分時的(time-slice)。然而,基于Java Thread類的實現系統可能是支持分時的,因此編寫代碼時不要依賴分時。當系統中的處于就緒狀態的線程都具有相同優先級時,線程調度程序采用一種簡單的、非搶占式的輪轉的調度順序。

          (2) 時間片輪轉調度策略

              有些系統的線程調度采用時間片輪轉(round-robin)調度策略。這種調度策略是從所有處于就緒狀態的線程中選擇優先級最高的線程分配一定的CPU時間運行。該時間過后再選擇其他線程運行。只有當線程運行結束、放棄(yield)CPU或由于某種原因進入阻塞狀態,低優先級的線程才有機會執行。如果有兩個優先級相同的線程都在等待CPU,則調度程序以輪轉的方式選擇運行的線程。

           3.  線程狀態的改變

          一個線程在其生命周期中可以從一種狀態改變到另一種狀態,線程狀態的變遷如圖所示:

              
              
          1>  控制線程的啟動和結束

          當一個新建的線程調用它的start()方法后即進入就緒狀態,處于就緒狀態的線程被線程調度程序選中就可以獲得CPU時間,進入運行狀態,該線程就開始運行run()方法。

          控制線程的結束稍微復雜一點。如果線程的run()方法是一個確定次數的循環,則循環結束后,線程運行就結束了,線程對象即進入死亡狀態。如果run()方法是一個不確定循環,早期的方法是調用線程對象的stop()方法,然而由于該方法可能導致線程死鎖,因此從1.1版開始,不推薦使用該方法結束線程。一般是通過設置一個標志變量,在程序中改變標志變量的值實現結束線程。請看下面的例子:

          程序 ThreadStop.java

          import java.util.*;

          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();
              }
          }

          該程序在Timer類中定義了一個布爾變量flag,同時定義了一個stopRun()方法,在其中將該變量設置為false。在主程序中通過調用該方法,從而改變該變量的值,使得run()方法的while循環條件不滿足,從而實現結束線程的運行。

          說明  Thread類中除了stop()方法被標注為不推薦(deprecated) 使用外,suspend()方法和resume()方法也被標明不推薦使用,這兩個方法原來用作線程的掛起和恢復.

          2>  線程阻塞條件

          處于運行狀態的線程除了可以進入死亡狀態外,還可能進入就緒狀態和阻塞狀態。下面分別討論這兩種情況:

          (1) 運行狀態到就緒狀態

          處于運行狀態的線程如果調用了yield()方法,那么它將放棄CPU時間,使當前正在運行的線程進入就緒狀態。這時有幾種可能的情況:如果沒有其他的線程處于就緒狀態等待運行,該線程會立即繼續運行;如果有等待的線程,此時線程回到就緒狀態狀態與其他線程競爭CPU時間,當有比該線程優先級高的線程時,高優先級的線程進入運行狀態,當沒有比該線程優先級高的線程時,但有同優先級的線程,則由線程調度程序來決定哪個線程進入運行狀態,因此線程調用yield()方法只能將CPU時間讓給具有同優先級的或高優先級的線程而不能讓給低優先級的線程。

          一般來說,在調用線程的yield()方法可以使耗時的線程暫停執行一段時間,使其他線程有執行的機會。

          (2) 運行狀態到阻塞狀態

          有多種原因可使當前運行的線程進入阻塞狀態,進入阻塞狀態的線程當相應的事件結束或條件滿足時進入就緒狀態。使線程進入阻塞狀態可能有多種原因:

          線程調用了sleep()方法,線程進入睡眠狀態,此時該線程停止執行一段時間。當時間到時該線程回到就緒狀態,與其他線程競爭CPU時間。

          Thread類中定義了一個interrupt()方法。一個處于睡眠中的線程若調用了interrupt()方法,該線程立即結束睡眠進入就緒狀態。

          如果一個線程的運行需要進行I/O操作,比如從鍵盤接收數據,這時程序可能需要等待用戶的輸入,這時如果該線程一直占用CPU,其他線程就得不到運行。這種情況稱為I/O阻塞。這時該線程就會離開運行狀態而進入阻塞狀態。Java語言的所有I/O方法都具有這種行為。

          ③ 有時要求當前線程的執行在另一個線程執行結束后再繼續執行,這時可以調用join()方法實現,join()方法有下面三種格式:

          ·         public void join() throws InterruptedException 使當前線程暫停執行,等待調用該方法的線程結束后再執行當前線程。

          ·         public void join(long millis) throws InterruptedException 最多等待millis毫秒后,當前線程繼續執行。

          ·         public void join(long millis, int nanos) throws InterruptedException 可以指定多少毫秒、多少納秒后繼續執行當前線程。

          上述方法使當前線程暫停執行,進入阻塞狀態,當調用線程結束或指定的時間過后,當前線程線程進入就緒狀態,例如執行下面代碼:

          t.join();

          將使當前線程進入阻塞狀態,當線程t執行結束后,當前線程才能繼續執行。

          ④ 線程調用了wait()方法,等待某個條件變量,此時該線程進入阻塞狀態。直到被通知(調用了notify()notifyAll()方法)結束等待后,線程回到就緒狀態。

          另外如果線程不能獲得對象鎖,也進入就緒狀態。

          后兩種情況在下一節討論。



















          posted @ 2011-09-01 21:43 Jamie 閱讀(4010) | 評論 (0)編輯 收藏

          復習下java多線程

          好久沒搞這個了,今天把以前的筆記整理下,當復習。

          Thread類和Runnable接口

          多線程是一個程序中可以有多段代碼同時運行,那么這些代碼寫在哪里,如何創建線程對象呢?

              首先,我們來看Java語言實現多線程編程的類和接口。在java.lang包中定義了Runnable接口和Thread類。

           

          Runnable接口中只定義了一個方法:

          ·         public abstract void run()

          這個方法要由實現了Runnable接口的類實現。Runnable對象稱為可運行對象,一個線程的運行就是執行該對象的run()方法。


                Thread
          類實現了Runnable接口,因此Thread對象也是可運行對象。同時Thread類也是線程類,該類的常用構造方法如下:

          ·         public Thread()

          ·         public Thread(Runnable target)

          ·         public Thread(String name)

          ·         public Thread(Runnable target, String name)
          target為線程運行的目標對象,即線程調用start()方法啟動后運行那個對象的run()方法,該對象的類型為Runnable,若沒有指定目標對象,則以當前類對象為目標對象,name為線程名


           

            線程的創建 

          介紹下如何創建和運行線程的兩種方法。線程運行的代碼就是實現了Runnable接口的類的run()方法或者是Thread類的子類的run()方法,因此構造線程體就有兩種方法:
              ·         繼承Thread類并覆蓋它的run()方法;
              ·        
          實現Runnable接口并實現它的run()方法。

            1,繼承Thread類創建線程

          通過繼承Thread類,并覆蓋run()方法,這時就可以用該類的實例作為線程的目標對象。下面的程序定義了SimpleThread類,它繼承了Thread類并覆蓋了run()方法。

          程序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");

          }

          }

          _____________________________________________________________________________

              SimpleThread類繼承了Thread類,并覆蓋了run()方法,該方法就是線程體。

          程序 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();

           }

          }

          _____________________________________________________________________________

          ThreadTest類的main()方法中創建了兩個SimpleThread類的線程對象并調用線程類的start()方法啟動線程。構造線程時沒有指定目標對象,所以線程啟動后執行本類的run()方法。

          注意,實際上ThreadTest程序中有三個線程同時運行,在應用程序的main()方法啟動時,JVM就創建一個主線程,在主線程中可以創建其他線程。

            2,實現Runnable接口創建線程

          可以定義一個類實現Runnable接口,然后將該類對象作為線程的目標對象。實現Runnable接口就是實現run()方法。

          下面程序通過實現Runnable接口構造線程體。

          程序 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();

            }

          }

          _____________________________________________________________________________




              

           



          posted @ 2011-09-01 20:46 Jamie 閱讀(388) | 評論 (0)編輯 收藏

          2011年8月24日

          android 項目下文件的作用

          1, R.java 是建立項目時自動生成的,只讀,用來定義該項目所有資源的索引文件。
          這里面定義了很多常量, 名字與res文件夾的文件名和String.xml里的定義的常量名相同。當項目中加入了新的資源時,只需要刷新一下該項目,R.java 便自動生成了。
          2, strings.xml 里面定義了字符串資源。 
              在類中可通過如下方式使用這些資源, Resource r = this.getContext().getResources(); String str = ((String) r.getString(R.string.name));
              在main.xml中可以 android:text="@string/name"
          3,  mail.xml 用來寫UI(布局,控件...)
              主程序繼承Activity類,重寫了void onCreate(Bundle savedInstanceState)方法。 在方法里通過setContentView(R.layout.main)設置Activity要顯示的布局文件(\layout\main.xml)
          4.  AndroidManifest.xml
              看下默認的:

          <?xml version="1.0" encoding="utf-8"?>
          <manifest xmlns:android="      package="com.test"
                android:versionCode="1"
                android:versionName="1.0">
              <uses-sdk android:minSdkVersion="8" />

              <application android:icon="@drawable/icon" android:label="@string/app_name">   //應用程序的名字
                  <activity android:name=".WuActivity"   //默認啟動哪個Activity
                            android:label="@string/app_name">
                      <intent-filter>
                          <action android:name="android.intent.action.MAIN" />
                          <category android:name="android.intent.category.LAUNCHER" />
                      </intent-filter>
                  </activity>

              </application>
          </manifest>

          posted @ 2011-08-24 02:33 Jamie 閱讀(1027) | 評論 (0)編輯 收藏

          2011年8月23日

          關于ADT和SDK版本

          用最新的就都用最新的, 不然有可能導致配置過程中出現一些問題。

          我用SDK3.2和ADT 0.9.5配置, 結果Preferences->Android里設置路徑出現問題。

          posted @ 2011-08-23 17:45 Jamie 閱讀(254) | 評論 (0)編輯 收藏

          2011年4月20日

          Content is not allowed in prolog

          錯誤可能是由XML有中文格式的字符引起的。

          posted @ 2011-04-20 08:43 Jamie 閱讀(291) | 評論 (0)編輯 收藏

          2011年3月23日

          JTree用法

          import  java.awt.Dimension;
          import  java.awt.Color;
          import  javax.swing.JFrame;
          import  javax.swing.JPanel;
          import  javax.swing.JScrollPane;
          import  javax.swing.JTree;
          import  javax.swing.BoxLayout;
          import  javax.swing.tree.TreePath;
          import  javax.swing.tree.DefaultMutableTreeNode;
          import  javax.swing.tree.DefaultTreeModel;
          /*
          JTree的構造函數:
          JTree()
          JTree(Hashtable value)
          JTree(Object[] value)//只有這個構造函數可以創建多個根結點
          JTree(TreeModel newModel)
          JTree(TreeNode root)
          JTree(TreeNode root, boolean asksAllowsChildren)
          JTree(Vector value)

          */
          public   class  JTreeDemo
          {
           
          public   static   void  main (String[] args)
           {


            
          // 構造函數:JTree()
            JTree example1  =   new  JTree();

           

            
            
          // 構造函數:JTree(Object[] value)
            Object[] letters =  { " a " " b " " c " " d " " e " };
            JTree example2 
          =   new  JTree (letters);

           


            
          // 構造函數:JTree(TreeNode root)(TreeNode空)
            
          // 用空結點創建樹
            DefaultMutableTreeNode node1  =   new  DefaultMutableTreeNode(); // 定義樹結點
            JTree example3  =   new  JTree (node1); // 用此樹結點做參數調用 JTree的構造函數創建含有一個根結點的樹

           


            
          // 構造函數:JTree(TreeNode root)(同上,只是TreeNode非空)
            
          // 用一個根結點創建樹
            DefaultMutableTreeNode node2  =   new  DefaultMutableTreeNode( " Color " );
            JTree example4 
          =   new  JTree (node2); // 結點不可以顏色,默認為白面黑字
            example4.setBackground (Color.lightGray);

           


            
          // 構造函數:JTree(TreeNode root, boolean asksAllowsChildren)(同上,只是TreeNode又有不同)
            
          // 使用DefaultMutableTreeNode類先用一個根結點創建樹,設置為可添加孩子結點,再添加孩子結點
            DefaultMutableTreeNode color  =   new  DefaultMutableTreeNode( " Color " true );
            DefaultMutableTreeNode gray 
          =   new  DefaultMutableTreeNode ( " Gray " );
            color.add (gray);
            color.add (
          new  DefaultMutableTreeNode ( " Red " ));
            gray.add (
          new  DefaultMutableTreeNode ( " Lightgray " ));
            gray.add (
          new  DefaultMutableTreeNode ( " Darkgray " ));
            color.add (
          new  DefaultMutableTreeNode ( " Green " ));
            JTree example5 
          =   new  JTree (color);
            
            
            
            
            
          // 構造函數:JTree(TreeNode root)(同上,只是TreeNode非空)
            
          // 通過逐個添加結點創建樹
            DefaultMutableTreeNode biology  =   new  DefaultMutableTreeNode ( " Biology " );
            DefaultMutableTreeNode animal 
          =   new  DefaultMutableTreeNode ( " Animal " );
            DefaultMutableTreeNode mammal 
          =   new  DefaultMutableTreeNode ( " Mammal " );
            DefaultMutableTreeNode horse 
          =   new  DefaultMutableTreeNode ( " Horse " );
            mammal.add (horse);
            animal.add (mammal);
            biology.add (animal);
            JTree example6 
          =   new  JTree (biology);
            horse.isLeaf();
            horse.isRoot();
            
            


            
          // 構造函數:JTree(TreeModel newModel)
            
          // 用DefaultMutableTreeNodel類定義一個結點再用這個結點做參數定義一個用DefaultTreeMode
            
          // 創建一個樹的模型,再用JTree的構造函數創建一個樹
            
            DefaultMutableTreeNode root 
          =   new  DefaultMutableTreeNode ( " Root1 " );
            DefaultMutableTreeNode child1 
          =   new  DefaultMutableTreeNode ( " Child1 " );
            DefaultMutableTreeNode child11 
          =   new  DefaultMutableTreeNode ( " Child11 " );
            DefaultMutableTreeNode child111 
          =   new  DefaultMutableTreeNode ( " Child111 " );
            root.add (child1); child1.add (child11); child11.add (child111);
            
            
            
            DefaultTreeModel model 
          =   new  DefaultTreeModel (root);
            
            JTree example7 
          =   new  JTree (model);

           

            JPanel panel 
          =   new  JPanel();
            panel.setLayout (
          new  BoxLayout (panel, BoxLayout.X_AXIS));
            panel.setPreferredSize (
          new  Dimension ( 700 400 ));
            panel.add (
          new  JScrollPane (example1)); // JTree必須放在JScrollPane上
            panel.add ( new  JScrollPane (example2));
            panel.add (
          new  JScrollPane (example3));
            panel.add (
          new  JScrollPane (example4));
            panel.add (
          new  JScrollPane (example5));
            panel.add (
          new  JScrollPane (example6));
            panel.add (
          new  JScrollPane (example7));
            

           

            JFrame frame 
          =   new  JFrame ( " JTreeDemo " );
            frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
            frame.setContentPane (panel);
            frame.pack();
            frame.show();
           }
          }
          ××××××××××××××××××××××××××××××××××××××××××××××

          在實際開發過程中會經常使用JTree組件,平時會遇到這樣或那樣的問題,在此將偶得一點經驗寫下來,與大家共享,希望對大家有所幫助。

          private JTree jtNetDevice;//數組件申明
          private JScrollPane jspTree;//滾動面板申明


          1、初始化
              DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode("root");
              jtNetDevice = new JTree(rootNode);
              jtNetDevice.setAutoscrolls(true);
              getTreeSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);//設置單選模式
              jspTree = new JScrollPane();
              jspTree.getViewport().add(jtNetDevice, null);

          2、三個經常使用的取值函數
            private DefaultTreeModel getTreeModel(){
              return (DefaultTreeModel)jtNetDevice.getModel();
            }

            private DefaultMutableTreeNode getRootNode(){
              return (DefaultMutableTreeNode)getTreeModel().getRoot();
            }
           
            private TreeSelectionModel getTreeSelectionModel(){
              return jtNetDevice.getSelectionModel();
            }
           

          3、根據node得到path:
            TreePath visiblePath = new TreePath(getTreeModel().getPathToRoot(node));

          4、根據Path展開到該節點
            jtNetDevice.makeVisible(visiblePath);

          5、根據path設定該節點選定
            jtNetDevice.setSelectionPath(visiblePath);

          6、選中節點的方法
            首先,根據節點得到樹路徑,其中chosen為需要選中的節點
            TreePath visiblePath = new TreePath( ( (DefaultTreeModel) jtNetDevice.getModel()).
                                                  getPathToRoot(chosen));
            然后根據Path選中該節點
            jtNetDevice.setSelectionPath(visiblePath);

          7、滾動到可見位置
            jtNetDevice.scrollPathToVisible(visiblePath);

          8、給JTree添加右鍵彈出菜單
            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
             // 創建樹
             JTree tree = new JTree();
            
             // 添加樹節點......
            
             // 遍歷所有節點
             visitAllNodes(tree);
            
             // 僅遍歷展開的節點
             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);
                     }
                 }
             }


          posted on 2006-04-04 17:24 SIMONE 閱讀(9202) 評論(1)  編輯  收藏 所屬分類: JAVA

          posted @ 2011-03-23 08:32 Jamie 閱讀(1736) | 評論 (0)編輯 收藏

          2011年3月18日

          GridBagLayout 2

           

          今天終于耐著性子弄懂了GridBagLayout是怎么使用的。
          構造函數:
              GirdBagLayout()建立一個新的GridBagLayout管理器。
              GridBagConstraints()建立一個新的GridBagConstraints對象。
              GridBagConstraints(int gridx,int gridy,
                                             int gridwidth,int gridheight,
                                             double weightx,double weighty,
                                             int anchor,int fill, Insets insets,
                                             int ipadx,int ipady)建立一個新的GridBagConstraints對象,并指定其參數的值。
          看著這一堆的參數就快煩死了,下面就了解一下參數的意思:

          參數說明:
           gridx,gridy    ——    設置組件的位置,
                             gridx設置為GridBagConstraints.RELATIVE代表此組件位于之前所加入組件的右邊。
                             gridy設置為GridBagConstraints.RELATIVE代表此組件位于以前所加入組件的下面。
                            建議定義出gridx,gridy的位置以便以后維護程序。gridx=0,gridy=0時放在0行0列。

           gridwidth,gridheight    ——    用來設置組件所占的單位長度與高度,默認值皆為1。
                           你可以使用GridBagConstraints.REMAINDER常量,代表此組件為此行或此列的最后一個組件,而且會占據所有剩余的空間。

           weightx,weighty    ——    用來設置窗口變大時,各組件跟著變大的比例。
                          當數字越大,表示組件能得到更多的空間,默認值皆為0。

           anchor    ——    當組件空間大于組件本身時,要將組件置于何處。
                         有CENTER(默認值)、NORTH、NORTHEAST、EAST、SOUTHEAST、WEST、NORTHWEST選擇。

           insets    ——    設置組件之間彼此的間距。
                        它有四個參數,分別是上,左,下,右,默認為(0,0,0,0)。

          ipadx,ipady    ——    設置組件間距,默認值為0。

          GridBagLayout里的各種設置都必須通過GridBagConstraints,因此當我們將GridBagConstraints的參數都設置
          好了之后,必須new一個GridBagConstraints的對象出來,以便GridBagLayout使用。

          代碼片斷:
                 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);


          GridBagLayout這種管理器是十分靈活的,只不過他寫起來比較麻煩,不過用了之后才發現他對界面的部署幫助很大。
           


          本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/dracularking/archive/2008/04/22/2314336.aspx

          posted @ 2011-03-18 14:27 Jamie| 編輯 收藏

          主站蜘蛛池模板: 兰考县| 阜新| 瓮安县| 温泉县| 定日县| 家居| 二连浩特市| 珲春市| 巴马| 玉环县| 辰溪县| 琼结县| 正宁县| 图木舒克市| 长垣县| 抚远县| 沁水县| 新巴尔虎右旗| 长治市| 靖江市| 禄劝| 福贡县| 郎溪县| 论坛| 苍梧县| 闻喜县| 鹿邑县| 抚松县| 高碑店市| 孝感市| 房山区| 禹州市| 潼南县| 体育| 阳高县| 丹阳市| 海安县| 南丹县| 华亭县| 隆尧县| 通辽市|