精通java swing開發樹(Tree)

++ 樹(Tree)的使用與介紹

10-1:使用JTree組件:
    java.lang.Object
      --java.awt.Component
--java.awt.Container
        --javax.swing.JComponent
         --javax.swing.JTree
JTree構造函數:
JTree():建立一棵系統預設的樹。
JTree(Hashtable value):利用Hashtable建立樹,不顯示root node(根節點).
JTree(Object[] value):利用Object Array建立樹,不顯示root node.
JTree(TreeModel newModel):利用TreeModel建立樹。
JTree(TreeNode root):利用TreeNode建立樹。
JTree(TreeNode root,boolean asksAllowsChildren):利用TreeNode建立樹,並決
定是否允許子節點的存在.
JTree(Vector value):利用Vector建立樹,不顯示root node.

範例:
 InitalTree.java
 
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class InitalTree{
   public InitalTree(){
    JFrame f=new JFrame("TreeDemo");
    Container contentPane=f.getContentPane();
   
    JTree tree=new JTree();
    JScrollPane scrollPane=new JScrollPane();
    scrollPane.setViewportView(tree);
   
    contentPane.add(scrollPane);
    f.pack();
    f.setVisible(true);
    f.addWindowListener(new WindowAdapter(){
      public void windowClosing(WindowEvent e){
        System.exit(0);
      }
    });
   } 
   public static void main(String[] args){
     new InitalTree();
   }
}

10-2:以Hashtable構造JTree:
    上面的例子對我們並沒有裨的幫助,因為各個節點的數據均是java的預設值,
而非我們自己設置的。因此我們需利用其他JTree
構造函數來輸入我們想要的節點數據。以下範例我們以Hashtable當作JTree的數據
輸入:
範例:TreeDemo1.java

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;

public class TreeDemo1{
   public TreeDemo1(){
     JFrame f=new JFrame("TreeDemo1");
     Container contentPane=f.getContentPane();
   
     String[] s1={"公司文件","個人信件","私人文件"};
     String[] s2={"本機磁盤(C:)","本機磁盤(D:)","本機磁盤(E:)"};
     String[] s3={"奇摩站","職棒消息","網絡書店"};
   
     Hashtable hashtable1=new Hashtable();
     Hashtable hashtable2=new Hashtable();
     hashtable1.put("我的公文包",s1);
     hashtable1.put("我的電腦",s2);
     hashtable1.put("收藏夾",hashtable2);
     hashtable2.put("網站列表",s3);
   
     Font font = new Font("Dialog", Font.PLAIN, 12);
Enumeration keys = UIManager.getLookAndFeelDefaults().keys();
    /**定義widnows界面**/
     while (keys.hasMoreElements()) {
          Object key = keys.nextElement();
          if (UIManager.get(key) instanceof Font) {
              UIManager.put(key, font);
          }
    }
    try{
     
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
    }catch(Exception el){
       System.exit(0);
    }
    /**定義widnows界面**/
     JTree tree=new JTree(hashtable1);
     JScrollPane scrollPane=new JScrollPane();
     scrollPane.setViewportView(tree);
    contentPane.add(scrollPane);
    f.pack();
    f.setVisible(true);
    f.addWindowListener(new WindowAdapter(){
      public void windowClosing(WindowEvent e){
        System.exit(0);
      }
    });
   } 
   public static void main(String[] args){
     new TreeDemo1();
   }
}

純XP界面的設置:

10-3:以TreeNode構造JTree:
    JTree上的每一個節點就代表一個TreeNode對象,TreeNode本身是一個
Interface,裡面定義了7個有關節點的方法,例如判斷是否
為樹葉節點、有幾個子節點(getChildCount())、父節點為何(getparent())等等、
這些方法的定義你可以在javax.swing.tree的
package中找到,讀者可自行查閱java api文件。在實際的應用上,一般我們不會
直接實作此界面,而是採用java所提供的
DefaultMutableTreeMode類,此類是實作MutableTreeNode界面而來,並提供了其
他許多實用的方法。MutableTreeNode本身也是一
個Interface,且繼承了TreeNode界面此類主要是定義一些節點的處理方式,例如新
增節點(insert())、刪除節點(remove())、設置
節點(setUserObject())等。整個關係如下圖:
   
TreeNode----extends--->MutableTreeNode---implements---DefaultMutableTreeNode

   接下來我們來看如何利DefaultMutableTreeNode來建立JTree,我們先來看
DefaultMutableTreeNode的構造函數:

DefaultMutableTreeNode構造函數:
DefaultMutableTreeNode():建立空的DefaultMutableTreeNode對象。
DefaultMutableTreeNode(Object userObject):建立DefaultMutableTreeNode對
象,節點為userObject對象。
DefaultMutableTreeNode(Object userObject,Boolean allowsChildren):建立
DefaultMutableTreeNode對象,節點為userObject對
                                 象並決定此節點是否允許具有子節點。
   以下為利用DefaultMutableTreeNode建立JTree的範例:TreeDemo2.java
     此程式"資源管理器"為此棵樹的根節點.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.tree.*;
public class TreeDemo2{
   public TreeDemo2(){
     JFrame f=new JFrame("TreeDemo2");
     Container contentPane=f.getContentPane();
   
     DefaultMutableTreeNode root=new DefaultMutableTreeNode("資源管理器");
     DefaultMutableTreeNode node1=new DefaultMutableTreeNode("我的公文包");
     DefaultMutableTreeNode node2=new DefaultMutableTreeNode("我的電腦");
     DefaultMutableTreeNode node3=new DefaultMutableTreeNode("收藏夾");
     DefaultMutableTreeNode node4=new DefaultMutableTreeNode("Readme");
     root.add(node1);
     root.add(node2);
     root.add(node3);
     root.add(node4);
   
     DefaultMutableTreeNode leafnode=new DefaultMutableTreeNode("公司文件");
     node1.add(leafnode);
     leafnode=new DefaultMutableTreeNode("私人文件");
     node1.add(leafnode);
     leafnode=new DefaultMutableTreeNode("個人信件");
   
     leafnode=new DefaultMutableTreeNode("本機磁盤(C:)");
     node2.add(leafnode);
     leafnode=new DefaultMutableTreeNode("本機磁盤(D:)");
     node2.add(leafnode);
     leafnode=new DefaultMutableTreeNode("本機磁盤(E:)");
     node2.add(leafnode);
   
     DefaultMutableTreeNode node31=new DefaultMutableTreeNode("網站列表");
     node3.add(node31);
   
     leafnode=new DefaultMutableTreeNode("奇摩站");
     node31.add(leafnode);
     leafnode=new DefaultMutableTreeNode("職棒消息");
     node31.add(leafnode);
     leafnode=new DefaultMutableTreeNode("網絡書店");
     node31.add(leafnode);
   
     JTree tree=new JTree(root);
     JScrollPane scrollPane=new JScrollPane();
     scrollPane.setViewportView(tree);
   
     contentPane.add(scrollPane);
    f.pack();
    f.setVisible(true);
    f.addWindowListener(new WindowAdapter(){
      public void windowClosing(WindowEvent e){
        System.exit(0);
      }
    });
   } 
   public static void main(String[] args){
     new TreeDemo2();
   }
}

10-4:以TreeModel構造JTree.
    除了以節點的觀念(TreeNode)建立樹之外,你可以用data model的模式建立
樹。樹的data model稱為TreeModel,用此模式的好處
是可以觸發相關的樹事件,來處理樹可能產生的一些變動。TreeModel是一個
interface,裡面定義了8種方法;如果你是一個喜歡自己
動手做的人,或是你想顯示的數據格式很複雜,你可以考慮直接實作TreeModel界
面中所定義的方法來構造出JTree.TreeModel界面
的方法如下所示:
TreeModel方法:
void      addTreeModelListener(TreeModelListener l):增加一個
TreeModelListener來監控TreeModelEvent事件。
Object    getChild(Object parent,int index):返回子節點。
int       getChildCount(Object parent):返回子節點數量.
int       getIndexOfChild(Object parent,Object child):返回子節點的索引值。
Object    getRoot():返回根節點。
boolean   isLeaf(Object node):判斷是否為樹葉節點。
void      removeTreeModelListener(TreeModelListener l):刪除
TreeModelListener。
void      valueForPathChanged(TreePath path,Object newValue):當用戶改變
Tree上的值時如何應對。

    你可以實作出這8種方法,然後構造出自己想要的JTree,不過在大部份的情況下
我們通常不會這樣做,畢竟要實作出這8種方法不
是件很輕鬆的事,而且java本身也提供了一個預設模式,叫做DefaultTreeModel,
這個類已經實作了TreeModel界面,也另外提供許
多實用的方法。利用這個預設模式,我們便能很方便的構造出JTree出來了。下面
為DefaultTreeModel的構造函數與範例:
DefaultTreeModel構造函數:
DefaultTreeModel(TreeNode root):建立DefaultTreeModel對象,並定出根節點。
DefaultTreeModel(TreeNode root,Boolean asksAllowsChildren):建立具有根節
點的DefaultTreeModel對象,並決定此節點是否允
                        許具有子節點。

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.tree.*;
import com.incors.plaf.alloy.*;//組件的下載網址http://www.incors.com
/lookandfeel/
/*將alloy.jar放在c:/j2sdk1.4.0/jre/lib/ext/目錄下.
  */
public class TreeDemo3
{
     public TreeDemo3()
     {
         JFrame f = new JFrame("TreeDemo");
         Container contentPane = f.getContentPane();
       
       
         DefaultMutableTreeNode root = new DefaultMutableTreeNode("資源管
理器");
         DefaultMutableTreeNode node1 = new DefaultMutableTreeNode("我的
公文包");
         DefaultMutableTreeNode node2 = new DefaultMutableTreeNode("我的
電腦");
         DefaultMutableTreeNode node3 = new DefaultMutableTreeNode("收藏夾");
         DefaultMutableTreeNode node4 = new DefaultMutableTreeNode("Readme");
       
         DefaultTreeModel treeModel = new DefaultTreeModel(root);

         /*DefaultTreeModel類所提供的insertNodeInto()方法加入節點到父節點
的數量.
          *利用DefaultMutableTreeNode類所提供的getChildCount()方法取得目
前子節點的數量.
          */
         treeModel.insertNodeInto(node1, root, root.getChildCount());
         treeModel.insertNodeInto(node2, root, root.getChildCount());
         treeModel.insertNodeInto(node3, root, root.getChildCount());
         treeModel.insertNodeInto(node4, root, root.getChildCount());
       
         DefaultMutableTreeNode leafnode = new
                 DefaultMutableTreeNode("公司文件");

         //DefaultTreeModel類所提供的insertNodeInto()方法加入節點到父節點
的數量.
         treeModel.insertNodeInto(leafnode, node1, node1.getChildCount());
         leafnode = new DefaultMutableTreeNode("個人信件");
         treeModel.insertNodeInto(leafnode, node1, node1.getChildCount());
         leafnode = new DefaultMutableTreeNode("私人文件");
         treeModel.insertNodeInto(leafnode, node1, node1.getChildCount());
       
         leafnode = new DefaultMutableTreeNode("本機磁盤(C:)");
         treeModel.insertNodeInto(leafnode, node2, node2.getChildCount());
         leafnode = new DefaultMutableTreeNode("本機磁盤(D:)");
         treeModel.insertNodeInto(leafnode, node2, node2.getChildCount());
         leafnode = new DefaultMutableTreeNode("本機磁盤(E:)");
         treeModel.insertNodeInto(leafnode, node2, node2.getChildCount());
       
         DefaultMutableTreeNode node31 = new DefaultMutableTreeNode("網站
列表");
         treeModel.insertNodeInto(node31, node3, node3.getChildCount());
         leafnode = new DefaultMutableTreeNode("奇摩站");
         treeModel.insertNodeInto(leafnode, node3, node3.getChildCount());
         leafnode = new DefaultMutableTreeNode("職棒消息");
         treeModel.insertNodeInto(leafnode, node3, node3.getChildCount());
         leafnode = new DefaultMutableTreeNode("網絡書店");
         treeModel.insertNodeInto(leafnode, node3, node3.getChildCount());
         try {
            LookAndFeel alloyLnF = new AlloyLookAndFeel();  
            UIManager.setLookAndFeel(alloyLnF);
         } catch (UnsupportedLookAndFeelException ex) {
         // You may handle the exception here
         }
          // this line needs to be implemented in order to make JWS work
properly
           UIManager.getLookAndFeelDefaults().put("ClassLoader",
getClass().getClassLoader());
       
         //以TreeModel建立JTree。
         JTree tree = new JTree(treeModel);
         /*改變JTree的外觀**/
           tree.putClientProperty("JTree.lineStyle","Horizontal");
         /*改變JTree的外觀**/
         JScrollPane scrollPane = new JScrollPane();
         scrollPane.setViewportView(tree);
       
         contentPane.add(scrollPane);
         f.pack();
         f.setVisible(true);
       
         f.addWindowListener(new WindowAdapter() {
             public void windowClosing(WindowEvent e) {
                 System.exit(0);
             }
         });

     }

     public static void main(String args[]) {
   
         new TreeDemo3();
     }
}
10-5:改變JTree的外觀:
  你可以使用JComponent所提供的putClientProperty(Object key,Object value)
方法來設置java預設的JTree外觀,設置方式共有
3種:
1.tree.putClientProperty("JTree.lineStyle","None"):java預設值。
2.tree.putClientProperty("JTree.lineStyle","Horizontal"):使JTree的文件夾
間具有水平分隔線。
3.tree.putClientProperty("JTree.lineStyle","Angled"):使JTree具有類似
Windows文件管理器的直角連接線。
   具體怎樣做,可看上例.

10-6:更換JTree節點圖案:
   JTree利用TreeCellRenderer界面來運行繪製節點的工作,同樣的,你不需要直
接支實作這個界面所定義的方法,因為java本身提
供一個已經實作好的類來給我們使用,此類就是DefaultTreeCellRenderer,你可以
在javax.swing.tree package中找到此類所提供
的方法。下面為使用DefaultTreeCellRenderer更改節點圖案的一個例子:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.tree.*;
import com.incors.plaf.alloy.*;

public class TreeDemo4{
    public TreeDemo4(){
      JFrame f=new JFrame("TreeDemo");
      Container contentPane=f.getContentPane();
    
         DefaultMutableTreeNode root = new DefaultMutableTreeNode("資源管
理器");
         DefaultMutableTreeNode node1 = new DefaultMutableTreeNode("我的
公文包");
         DefaultMutableTreeNode node2 = new DefaultMutableTreeNode("我的
電腦");
         DefaultMutableTreeNode node3 = new DefaultMutableTreeNode("收藏夾");
         DefaultMutableTreeNode node4 = new DefaultMutableTreeNode("Readme");
         DefaultTreeModel treeModel = new DefaultTreeModel(root);
         treeModel.insertNodeInto(node1, root, root.getChildCount());
         treeModel.insertNodeInto(node2, root, root.getChildCount());
         treeModel.insertNodeInto(node3, root, root.getChildCount());
         treeModel.insertNodeInto(node4, root, root.getChildCount());
       
         DefaultMutableTreeNode leafnode = new
                 DefaultMutableTreeNode("公司文件");
         treeModel.insertNodeInto(leafnode, node1, node1.getChildCount());
         leafnode = new DefaultMutableTreeNode("個人信件");
         treeModel.insertNodeInto(leafnode, node1, node1.getChildCount());
         leafnode = new DefaultMutableTreeNode("私人文件");
         treeModel.insertNodeInto(leafnode, node1, node1.getChildCount());
       
         leafnode = new DefaultMutableTreeNode("本機磁盤(C:)");
         treeModel.insertNodeInto(leafnode, node2, node2.getChildCount());
         leafnode = new DefaultMutableTreeNode("本機磁盤(D:)");
         treeModel.insertNodeInto(leafnode, node2, node2.getChildCount());
         leafnode = new DefaultMutableTreeNode("本機磁盤(E:)");
         treeModel.insertNodeInto(leafnode, node2, node2.getChildCount());
       
         DefaultMutableTreeNode node31 = new DefaultMutableTreeNode("網站
列表");
         treeModel.insertNodeInto(node31, node3, node3.getChildCount());
         leafnode = new DefaultMutableTreeNode("奇摩站");
         treeModel.insertNodeInto(leafnode, node3, node3.getChildCount());
         leafnode = new DefaultMutableTreeNode("職棒消息");
         treeModel.insertNodeInto(leafnode, node3, node3.getChildCount());
         leafnode = new DefaultMutableTreeNode("網絡書店");
         treeModel.insertNodeInto(leafnode, node3, node3.getChildCount());
         try {
            LookAndFeel alloyLnF = new AlloyLookAndFeel();  
            UIManager.setLookAndFeel(alloyLnF);
         } catch (UnsupportedLookAndFeelException ex) {
         // You may handle the exception here
         }
          // this line needs to be implemented in order to make JWS work
properly
           UIManager.getLookAndFeelDefaults().put("ClassLoader",
getClass().getClassLoader());

         JTree tree = new JTree(treeModel);
         tree.setRowHeight(20);
         DefaultTreeCellRenderer
cellRenderer=(DefaultTreeCellRenderer)tree.getCellRenderer();
         cellRenderer.setLeafIcon(new ImageIcon("..//icons//leaf.gif"));
         cellRenderer.setOpenIcon(new ImageIcon("..//icons//open.gif"));
         cellRenderer.setClosedIcon(new ImageIcon("..//icons//close.gif"));
       
         cellRenderer.setFont(new Font("宋體",Font.PLAIN,12));//設置字體.
         cellRenderer.setBackgroundNonSelectionColor(Color.white);
         cellRenderer.setBackgroundSelectionColor(Color.yellow);
         cellRenderer.setBorderSelectionColor(Color.red);
         /*設置選時或不選時,文字的變化顏色
          */
         cellRenderer.setTextNonSelectionColor(Color.black);
         cellRenderer.setTextSelectionColor(Color.blue);
       
         JScrollPane scrollPane=new JScrollPane();
         scrollPane.setViewportView(tree);
       
         contentPane.add(scrollPane);
         f.pack();
         f.setVisible(true);
       
         f.addWindowListener(new WindowAdapter() {
             public void windowClosing(WindowEvent e) {
                 System.exit(0);
             }
         });

     }

     public static void main(String args[]) {
   
         new TreeDemo4();
     }
}
  Window Xp界面:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.tree.*;
import com.incors.plaf.alloy.*;
public class TreeDemo3
{
     public TreeDemo3()
     {
        //設置成Alloy界面樣式
         try {
          
AlloyLookAndFeel.setProperty("alloy.isLookAndFeelFrameDecoration", "true");
            LookAndFeel alloyLnF = new AlloyLookAndFeel();
            JFrame.setDefaultLookAndFeelDecorated(true);
            UIManager.setLookAndFeel(alloyLnF);
         } catch (UnsupportedLookAndFeelException ex) {
         // You may handle the exception here
         }
          // this line needs to be implemented in order to make JWS work
properly
         UIManager.getLookAndFeelDefaults().put("ClassLoader",
getClass().getClassLoader());
         
          //JDialog.setDefaultLookAndFeelDecorated(true);
         JFrame f = new JFrame("firstTree");
      
         Container contentPane = f.getContentPane();
        // if (contentPane instanceof JComponent) {
         //   ((JComponent) contentPane).setMinimumSize(new
Dimension(100, 100));
         //}
        // Container contentPane = f.getContentPane();
       
       
         DefaultMutableTreeNode root = new DefaultMutableTreeNode("資源管
理器");
         DefaultMutableTreeNode node1 = new DefaultMutableTreeNode("我的
公文包");
         DefaultMutableTreeNode node2 = new DefaultMutableTreeNode("我的
電腦");
         DefaultMutableTreeNode node3 = new DefaultMutableTreeNode("收藏夾");
         DefaultMutableTreeNode node4 = new DefaultMutableTreeNode("Readme");
       
         DefaultTreeModel treeModel = new DefaultTreeModel(root);
         treeModel.insertNodeInto(node1, root, root.getChildCount());
         treeModel.insertNodeInto(node2, root, root.getChildCount());
         treeModel.insertNodeInto(node3, root, root.getChildCount());
         treeModel.insertNodeInto(node4, root, root.getChildCount());
       
         DefaultMutableTreeNode leafnode = new
                 DefaultMutableTreeNode("公司文件");
         treeModel.insertNodeInto(leafnode, node1, node1.getChildCount());
         leafnode = new DefaultMutableTreeNode("個人信件");
         treeModel.insertNodeInto(leafnode, node1, node1.getChildCount());
         leafnode = new DefaultMutableTreeNode("私人文件");
         treeModel.insertNodeInto(leafnode, node1, node1.getChildCount());
       
         leafnode = new DefaultMutableTreeNode("本機磁盤(C:)");
         treeModel.insertNodeInto(leafnode, node2, node2.getChildCount());
         leafnode = new DefaultMutableTreeNode("本機磁盤(D:)");
         treeModel.insertNodeInto(leafnode, node2, node2.getChildCount());
         leafnode = new DefaultMutableTreeNode("本機磁盤(E:)");
         treeModel.insertNodeInto(leafnode, node2, node2.getChildCount());
       
         DefaultMutableTreeNode node31 = new DefaultMutableTreeNode("網站
列表");
         treeModel.insertNodeInto(node31, node3, node3.getChildCount());
         leafnode = new DefaultMutableTreeNode("奇摩站");
         treeModel.insertNodeInto(leafnode, node3, node3.getChildCount());
         leafnode = new DefaultMutableTreeNode("職棒消息");
         treeModel.insertNodeInto(leafnode, node3, node3.getChildCount());
         leafnode = new DefaultMutableTreeNode("網絡書店");
         treeModel.insertNodeInto(leafnode, node3, node3.getChildCount());

         JTree tree = new JTree(treeModel);
         /*改變JTree的外觀**/
         //  tree.putClientProperty("JTree.lineStyle","Horizontal");
         /*改變JTree的外觀**/
         JScrollPane scrollPane = new JScrollPane();
         scrollPane.setViewportView(tree);
       
         contentPane.add(scrollPane);
         f.pack();
         f.setVisible(true);
       
         f.addWindowListener(new WindowAdapter() {
             public void windowClosing(WindowEvent e) {
                 System.exit(0);
             }
         });

     }

     public static void main(String args[]) {
   
         new TreeDemo3();
     }
}


10-7:JTree的事件處理模式:
     在此節中,我們將詳細介紹JTree兩個常用的事件與處理,分別是
TreeModeEvent與TreeSelectionEvent.
10-7-1:處理TreeModeEvent事件:
   當樹的結構上有任何改變時,例如節點值改變了、新增節點、刪除節點等,都會
TreeModelEvent事件,要處理這樣的事件必須實
作TreeModelListener界面,此界面定義了4個方法,如下所示:
TreeModelListener方法:
Void              treeNodesChanged(TreeModelEvent e):當節點改變時系統就
會雲調用這個方法。
Void              treeNodesInserted(TreeModelEvent e):當新增節時系統就會
去調用這個方法。
Void              treeNodesRemoved(TreeModeEvent e):當刪除節點時系統就會
去調用這個方法。
Void              treeStructureChanged(TreeModelEvent e):當樹結構改變時
系統就會去調用這個方法。

   TreeModelEvent類本身提供了5個方法,幫我們取得事件的信息,如下所示:

TreeModelEvent方法:
int[]                getChildIndices():返回子節點群的索引值。
Object[]             getChildren():返回子節點群.
Object[]             getPath():返回Tree中一條path上(從root nod到leaf
node)的節點。
TreePath             getTreePath():取得目前位置的Tree Path.
String               toString():取得蝗字符串表示法.
 
     由TreeModelEvent的getTreePath()方法就可以得到TreePath對象,此對象就
能夠讓我們知道用戶目前正選哪一個節點,
TreePath類最常用的方法為:
      public  Object getLastPathComponent():取得最深(內)層的節點。
      public int    getPathCount():取得此path上共有幾個節點.
     我們來看下面這個例子,用戶可以在Tree上編輯節點,按下[Enter]鍵後就可
以改變原有的值,並將改變的值顯示在下面的
JLabel中:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.tree.*;
import com.incors.plaf.alloy.*;
import com.incors.plaf.alloy.themes.bedouin.*;

public class TreeDemo5 implements TreeModelListener
{
     JLabel label = null;
     String nodeName = null; //原有節點名稱
   
     public TreeDemo5()
     {
         try {
       
  AlloyLookAndFeel.setProperty("alloy.isLookAndFeelFrameDecoration", "true");
          AlloyTheme theme = new BedouinTheme();//設置界面的外觀,手冊中
共有5種樣式
          LookAndFeel alloyLnF = new AlloyLookAndFeel(theme);
             UIManager.setLookAndFeel(alloyLnF);
         } catch (UnsupportedLookAndFeelException ex) {
         // You may handle the exception here
         }
          // this line needs to be implemented in order to make JWS work
properly
         UIManager.getLookAndFeelDefaults().put("ClassLoader",
getClass().getClassLoader());
         JFrame f = new JFrame("TreeDemo");
         Container contentPane = f.getContentPane();
       
         DefaultMutableTreeNode root = new DefaultMutableTreeNode("資源管
理器");
         DefaultMutableTreeNode node1 = new DefaultMutableTreeNode("文件夾");
         DefaultMutableTreeNode node2 = new DefaultMutableTreeNode("我的
電腦");
         DefaultMutableTreeNode node3 = new DefaultMutableTreeNode("收藏夾");
         DefaultMutableTreeNode node4 = new DefaultMutableTreeNode("Readme");
         root.add(node1);
         root.add(node2);
         root.add(node3);
         root.add(node4);
       
         DefaultMutableTreeNode leafnode = new DefaultMutableTreeNode("公
司文件");
         node1.add(leafnode);
         leafnode = new DefaultMutableTreeNode("個人信件");
         node1.add(leafnode);
         leafnode = new DefaultMutableTreeNode("私人文件");
         node1.add(leafnode);
       
         leafnode = new DefaultMutableTreeNode("本機磁盤(C:)");
         node2.add(leafnode);
         leafnode = new DefaultMutableTreeNode("本機磁盤(D:)");
         node2.add(leafnode);
         leafnode = new DefaultMutableTreeNode("本機磁盤(E:)");
         node2.add(leafnode);
       
         DefaultMutableTreeNode node31 = new DefaultMutableTreeNode("網站
列表");
         node3.add(node31);
       
         leafnode = new DefaultMutableTreeNode("天勤網站");
         node31.add(leafnode);
         leafnode = new DefaultMutableTreeNode("足球消息");
         node31.add(leafnode);
         leafnode = new DefaultMutableTreeNode("網絡書店");
         node31.add(leafnode);
       
         JTree tree = new JTree(root);
         tree.setEditable(true);//設置JTree為可編輯的
         tree.addMouseListener(new MouseHandle());//使Tree加入檢測Mouse事
件,以便取得節點名稱
         //下面兩行取得DefaultTreeModel,並檢測是否有TreeModelEvent事件.
         DefaultTreeModel treeModel = (DefaultTreeModel)tree.getModel();
         treeModel.addTreeModelListener(this);
       
         JScrollPane scrollPane = new JScrollPane();
         scrollPane.setViewportView(tree);
       
         label = new JLabel("更改數據為: ");
         contentPane.add(scrollPane,BorderLayout.CENTER);
         contentPane.add(label,BorderLayout.SOUTH);
         f.pack();
         f.setVisible(true);
       
         f.addWindowListener(new WindowAdapter() {
             public void windowClosing(WindowEvent e) {
                 System.exit(0);
             }
         });

     }
     /*本方法實作TreeModelListener介面,本介面共定義四個方法,分別是
TreeNodesChanged()
      *treeNodesInserted()、treeNodesRemoved()、treeNodesRemoved()、
      *treeStructureChanged().在此範例中我們只針對更改節點值的部份,因此
只實作
      *treeNodesChanged()方法.
      */
     public void treeNodesChanged(TreeModelEvent e) {
       
         TreePath treePath = e.getTreePath();
         System.out.println(treePath);
         //下面這行由TreeModelEvent取得的DefaultMutableTreeNode為節點的父
節點,而不是用戶點選
         //的節點,這點讀者要特別注意。要取得真正的節點需要再加寫下面6行代碼.
         DefaultMutableTreeNode node =
(DefaultMutableTreeNode)treePath.getLastPathComponent();
         try {
             //getChildIndices()方法會返回目前修改節點的索引值。由於我們
只修改一個節點,因此節點索引值就放在index[0]
             //的位置,若點選的節點為root node,則getChildIndices()的返回
值為null,程式下面的第二行就在處理點選root
             //node產生的NullPointerException問題.
             int[] index = e.getChildIndices();
               //由DefaultMutableTreeNode類的getChildAt()方法取得修改的節
點對象.
             node = (DefaultMutableTreeNode)node.getChildAt(index[0]);
         } catch (NullPointerException exc) {}
         //由DefaultMutableTreeNode類getUserObject()方法取得節點的內容,
或是寫成node.toString()亦相同.
         label.setText(nodeName+"更改數據為: "+(String)node.getUserObject());
     }
     public void treeNodesInserted(TreeModelEvent e) {
     }
     public void treeNodesRemoved(TreeModelEvent e) {
     }
     public void treeStructureChanged(TreeModelEvent e) {
     }

     public static void main(String args[]) {
   
         new TreeDemo5();
     }
     //處理Mouse點選事件
     class MouseHandle extends MouseAdapter
     {
         public void mousePressed(MouseEvent e)
         {
             try{
               JTree tree = (JTree)e.getSource();
         //JTree的getRowForLocation()方法會返回節點的列索引值。例如本例
中,“本機磁盤(D:)”的列索引值為4,此索引值
         //會隨着其他數據夾的打開或收起而變支,但“資源管理器”的列索引值恆為0.
               int rowLocation = tree.getRowForLocation(e.getX(), e.getY());

              /*JTree的getPathForRow()方法會取得從root node到點選節點的一
條path,此path為一條直線,如程式運行的圖示
               *若你點選“本機磁盤(E:)”,則Tree Path為"資源管理器"-->"我的
電腦"-->"本機磁盤(E:)",因此利用TreePath
               *的getLastPathComponent()方法就可以取得所點選的節點.
               */

               TreePath treepath = tree.getPathForRow(rowLocation);
               TreeNode treenode = (TreeNode)
treepath.getLastPathComponent();
       
               nodeName = treenode.toString();
             }catch(NullPointerException ne){}
         }
     }
}

注:上面的程式MouseHandle中:
               int rowLocation = tree.getRowForLocation(e.getX(), e.getY());
               TreePath treepath = tree.getPathForRow(rowLocation);
    與:
               TreePath treepath=tree.getSelectionPath();
               等價,可互換。
 
   我們將“我的電腦”改成“網上領居”:
   我們再來看一個TreeModelEvent的例子,下面這個例子我們可以讓用戶自行增
加、刪除與修改節點:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.tree.*;
import com.incors.plaf.alloy.*;
import com.incors.plaf.alloy.themes.bedouin.*;

public class TreeDemo6 implements ActionListener,TreeModelListener{
   JLabel label=null;
   JTree  tree=null;
   DefaultTreeModel treeModel=null;
   String nodeName=null;//原有節點名稱
 
   public TreeDemo6(){
         try {
       
  AlloyLookAndFeel.setProperty("alloy.isLookAndFeelFrameDecoration", "true");
          AlloyTheme theme = new BedouinTheme();
          LookAndFeel alloyLnF = new AlloyLookAndFeel(theme);
             UIManager.setLookAndFeel(alloyLnF);
         } catch (UnsupportedLookAndFeelException ex) {
         // You may handle the exception here
         }
          // this line needs to be implemented in order to make JWS work
properly
         UIManager.getLookAndFeelDefaults().put("ClassLoader",
getClass().getClassLoader());
     JFrame f=new JFrame("TreeDemo6");
     Container contentPane=f.getContentPane();
   
     DefaultMutableTreeNode root=new DefaultMutableTreeNode("資源管理器");
   
     tree=new JTree(root);
     tree.setEditable(true);
     tree.addMouseListener(new MouseHandle());
     treeModel=(DefaultTreeModel)tree.getModel();
     treeModel.addTreeModelListener(this);
   
     JScrollPane scrollPane=new JScrollPane();
     scrollPane.setViewportView(tree);
   
     JPanel panel=new JPanel();
     JButton b=new JButton("新增節點");
     b.addActionListener(this);
     panel.add(b);
     b=new JButton("刪除節點");
     b.addActionListener(this);
     panel.add(b);
     b=new JButton("清除所有節點");
     b.addActionListener(this);
     panel.add(b);
   
     label=new JLabel("Action");
     contentPane.add(panel,BorderLayout.NORTH);
     contentPane.add(scrollPane,BorderLayout.CENTER);
     contentPane.add(label,BorderLayout.SOUTH);
     f.pack();
     f.setVisible(true);
     f.addWindowListener(new WindowAdapter(){
      public void windowClosing(WindowEvent e){
        System.exit(0);
      }
     });
   }
   //本方法運行新增、刪除、清除所有節點的程式代碼.
   public void actionPerformed(ActionEvent ae){
     if (ae.getActionCommand().equals("新增節點")){
       DefaultMutableTreeNode parentNode=null;
       DefaultMutableTreeNode newNode=new DefaultMutableTreeNode("新節點");
       newNode.setAllowsChildren(true);
       TreePath parentPath=tree.getSelectionPath();
         
          //取得新節點的父節點
     
parentNode=(DefaultMutableTreeNode)(parentPath.getLastPathComponent());

          //由DefaultTreeModel的insertNodeInto()方法增加新節點
     
treeModel.insertNodeInto(newNode,parentNode,parentNode.getChildCount());

          //tree的scrollPathToVisible()方法在使Tree會自動展開文件夾以便顯
示所加入的新節點。若沒加這行則加入的新節點
          //會被 包在文件夾中,你必須自行展開文件夾才看得到。
       tree.scrollPathToVisible(new TreePath(newNode.getPath()));    
       label.setText("新增節點成功");
     }
     if (ae.getActionCommand().equals("刪除節點")){
      TreePath treepath=tree.getSelectionPath();
      if (treepath!=null){
           //下面兩行取得選取節點的父節點.
        DefaultMutableTreeNode
selectionNode=(DefaultMutableTreeNode)treepath.getLastPathComponent();
        TreeNode parent=(TreeNode)selectionNode.getParent();
        if (parent!=null) {
              //由DefaultTreeModel的removeNodeFromParent()方法刪除節點,
包含它的子節點。
          treeModel.removeNodeFromParent(selectionNode);
          label.setText("刪除節點成功");
        }
      }    
     }
     if (ae.getActionCommand().equals("清除所有節點")){

         //下面一行,由DefaultTreeModel的getRoot()方法取得根節點.
      DefaultMutableTreeNode
rootNode=(DefaultMutableTreeNode)treeModel.getRoot();
 
         //下面一行刪除所有子節點.
      rootNode.removeAllChildren(); 
 
         //刪除完後務必運行DefaultTreeModel的reload()操作,整個Tree的節點
才會真正被刪除.   
      treeModel.reload();
      label.setText("清除所有節點成功");
     }
   }
      public void treeNodesChanged(TreeModelEvent e){
       TreePath treePath=e.getTreePath();
       DefaultMutableTreeNode
node=(DefaultMutableTreeNode)treePath.getLastPathComponent();
       try{
         int[] index=e.getChildIndices();
         node=(DefaultMutableTreeNode)node.getChildAt(index[0]);
       }catch(NullPointerException exc){}
         label.setText(nodeName+"更改數據為:"+(String)node.getUserObject());
      }
     public void treeNodesInserted(TreeModelEvent e){
       System.out.println("new node insered");      
     }
     public void treeNodesRemoved(TreeModelEvent e){
       System.out.println("node deleted");
     }
     public void treeStructureChanged(TreeModelEvent e){
       System.out.println("Structrue changed");
     }
     public static void main(String[] args){
       new TreeDemo6();
     }
   
     class MouseHandle extends MouseAdapter{
       public void mousePressed(MouseEvent e){
          try{
            JTree tree=(JTree)e.getSource();
            int rowLocation=tree.getRowForLocation(e.getX(),e.getY());
            TreePath treepath=tree.getPathForRow(rowLocation);
            TreeNode treenode=(TreeNode)treepath.getLastPathComponent();
            nodeName=treenode.toString();         
          }catch(NullPointerException ne){}
       }
     }
}
 
10-7-2:處理TreeSelectionEvent事件:
     當我們在JTree上點選任何一個節點,都會觸發TreeSelectionEvent事件,如
果我們要處理這樣的事件,必須實作
TreeSelectionListener界面,此界面只定義了一個方法,那就是valueChanged()
方法。
     TreeSelectionEvent最常用在處理顯示節點的內容,例如你在文件圖標中點兩
下就可以看到文件的內容。在JTree中選擇節點
的方式共有3種,這3種情況跟選擇JList上的項目是一模一樣的,分別是:
       DISCONTIGUOUS_TREE_SELECTION:可作單一選擇,連續點選擇(按住[Shift]
鍵),不連續選擇多個節點(按住[Ctrl]鍵),
這是java預設值.
       CONTINUOUS_TREE_SELECTION:按住[Shift]鍵,可對某一連續的節點區間作
選取。
       SINGLE_TREE_SELECTION:一次只能選一個節點。
    你可以自行實作TreeSelectionModel製作作更複雜的選擇方式,但通常是沒有
必要的,因為java提供了預設的選擇模式類供我們
使用,那就是DefaultTreeSelectionModel,利用這個類我們可以很方便的設置上面
3種選擇模式。
    下面這個範例,當用戶點選了一個文件名時,就會將文件的內容顯示出來。
TreeDemo7.java

import javax.swing.*;
import javax.swing.tree.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;
import com.incors.plaf.alloy.*;
import com.incors.plaf.alloy.themes.glass.*;

public class TreeDemo7 implements TreeSelectionListener
{
     JEditorPane editorPane;

     public TreeDemo7()
     {
         JFrame f = new JFrame("TreeDemo");
         Container contentPane = f.getContentPane();
         DefaultMutableTreeNode root = new DefaultMutableTreeNode("資源管
理器");
         DefaultMutableTreeNode node = new
DefaultMutableTreeNode("TreeDemo1.java");
         root.add(node);
         node = new DefaultMutableTreeNode("TreeDemo2.java");
         root.add(node);
         node = new DefaultMutableTreeNode("TreeDemo3.java");
         root.add(node);
         node = new DefaultMutableTreeNode("TreeDemo4.java");
         root.add(node);
       
         JTree tree = new JTree(root);
         //設置Tree的選擇模式為一次只能選擇一個節點
       
tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
         //檢查是否有TreeSelectionEvent事件。
         tree.addTreeSelectionListener(this);

         //下面五行,JSplitPane中,左邊是放含有JTree的JScrollPane,右邊是
放JEditorPane.
         JScrollPane scrollPane1 = new JScrollPane(tree);
         editorPane = new JEditorPane();
         JScrollPane scrollPane2 = new JScrollPane(editorPane);
         JSplitPane splitPane = new JSplitPane(
         JSplitPane.HORIZONTAL_SPLIT,true, scrollPane1, scrollPane2);

         contentPane.add(splitPane);
         f.pack();
         f.setVisible(true);
       
         f.addWindowListener(new WindowAdapter() {
             public void windowClosing(WindowEvent e) {
                 System.exit(0);
             }
         });
     }
     //本方法實作valueChanged()方法
     public void valueChanged(TreeSelectionEvent e)
     {
         JTree tree = (JTree) e.getSource();
         //利用JTree的getLastSelectedPathComponent()方法取得目前選取的節點.
         DefaultMutableTreeNode selectionNode =
             (DefaultMutableTreeNode)tree.getLastSelectedPathComponent();

         String nodeName = selectionNode.toString();
       
         //判斷是否為樹葉節點,若是則顯示文件內容,若不是則不做任何事。
         if (selectionNode.isLeaf())
         {
            /*取得文件的位置路徑,System.getProperty("user.dir")可以取得目
前工作的路徑,
             *System.getProperty("file.separator")是取得文件分隔符,例如
在window環境的
             *文件分陋符是"/",而Unix環境的文件分隔符剛好相反,是"/".利用
System.getProperty()
             *方法你可以取得下列的信息:
             java.version                             顯示java版本
             java.endor                               顯示java製造商
             java.endor.url                           顯示java製造商URL
             java.home                                顯示java的安裝路徑
             java.class.version                       顯示java類版本
             java.class.path                          顯示java classpath
             os.name                                  顯示操作系統名稱
             os.arch                                  顯示操作系統結構,如x86
             os.version                               顯示操作系統版本
             file.separator                           取得文件分隔符
             path.separator                           取得路徑分隔符,如
Unix是以“:”表示
             line.separator                           取得換行符號,如
Unix是以"/n"表示
             user.name                                取得用戶名稱
             user.home                                取得用戶家目錄(home
directory),如Windows中Administrator的家目
                                                      錄為c:/Documents
and Settings/Administrator
             user.dir                                 取得用戶目前的工作目錄.
             */
             String filepath = "file:"+System.getProperty("user.dir") +
                                System.getProperty("file.separator") +
                                nodeName;
                          
             try {
                //利用JEditorPane的setPage()方法將文件內容顯示在
editorPane中。若文件路徑錯誤,則會產生IOException.
                  editorPane.setPage(filepath);
             } catch(IOException ex) {
                  System.out.println("找不到此文件");
             }
         }
     }
   
     public static void main(String[] args) {
      SwingUtil.setLookAndFeel();
         new TreeDemo7();      
     }
}            

class SwingUtil{
   public static final void setLookAndFeel() {
    try{
             Font font = new Font("JFrame", Font.PLAIN, 12);
             Enumeration keys = UIManager.getLookAndFeelDefaults().keys();
 
             while (keys.hasMoreElements()) {
                Object key = keys.nextElement();
                if (UIManager.get(key) instanceof Font) {
                   UIManager.put(key, font);
                 }
             }
       
  AlloyLookAndFeel.setProperty("alloy.isLookAndFeelFrameDecoration", "true");
          AlloyTheme theme = new GlassTheme();
          LookAndFeel alloyLnF = new AlloyLookAndFeel(theme);
            JFrame.setDefaultLookAndFeelDecorated(true);
         
            UIManager.setLookAndFeel(alloyLnF);
    }catch(UnsupportedLookAndFeelException ex){
      ex.printStackTrace();
    }
  }
}

10-8:JTree的其他操作:
      我們在之前小節中曾說到Tree中的每一個節點都是一個TreeNode,並可利用
JTree的setEditable()方法設置節點是否可編輯,
若要在Tree中找尋節點的父節點或子節點,或判斷是否為樹節點,皆可由實作
TreeNode界面做到,但要編輯節點呢?java將編輯
節點的任務交給TreeCellEditor,TreeCellEditor本身是一個界面,裡面只定義了
getTreeCellEditor Component()方法,你可以實
作此方法使節點具有編輯的效果。不過你不用這麼辛苦去實作這個方法,java本身
提供了DefaultTreeCellEditor類來實作此方法
,亦提供了其他許多方法,例如取得節點內容(getCellEditorValue()) 、設置節
點字體(setFont())、決定節點是否可編輯
(isCellEditable())等等。除非你覺得DefaultTreeCellEditor所提供的功能不
夠,你才需要去實作TreeCellEditor界面。你可以利
用JTree的getCellEditor()方法取得DefaultTreeCellEditor對象。當我們編輯節
點時會觸發ChangeEvent事件,你可以實作
CellEditorListener界面來處理此事件,CellEditorListener界面包括兩個方法,
分別是editingStopped(ChangeEvent e)與
editingCanceled(ChangeEvent e).若你沒有實作TreeCellEditor界面,系統會以
預設的DefaultTreeCellEdtior類來處理掉這兩個
方法(你可以在DefaultTreeCellEditor中找到這兩個方法),因此你無須再編寫任
何的程式。
      另外,JTree還有一種事件處理模式,那就是TreeExpansionEvent事件。要處
理這個事件你必須實作TreeExpansionListener
界面,此界面定義了兩個方法,分別是treeCollapsed(TreeExpansionEvent e)與
treeExpanded(TreeExpansionEvent e).當節點展
開時系統就會自動調用treeExpanded()方法,當節點合起來時,系統就會自動調用
treeCollapsed()方法。你可以在這兩個方法中編寫所要處理事情的程式碼。
目录 目录 1 (一) Spring 开发 Swing GUI 简介——依赖注入和富客户机 5 关于本教程 5 前提条件 6 Spring 和依赖注入概述 7 什么是 Spring 框架? 7 什么是依赖注入? 7 环境设置 7 选择编译环境 7 设置 Ant 8 通过 Ant 自动下载依赖软件 10 设置 Maven 10 通过 Maven 自动下载依赖软件 12 设置 Eclipse 13 下载依赖的 JAR 文件并在 Eclipse 的 classpath 中定义这种依赖性 15 创建 to-do 列表:基本的 Swing 和 Spring 应用程序设置 17 创建 MainFrame、Launcher 和 ToDo 类 17 创建 Spring app-context.xml bean 定义文件 19 运行应用程序 20 定义 bean 属性 21 创建 to-do 列表:创建一个可重用组件并在表中显示数据 23 创建一个可重用的面板 23 将 bean 组合在一起 24 添加一个表并重用这个面板 26 定义表模型 28 显示列表中的项 29 创建 to-do 列表:完成 —— 按钮和监听程序 31 创建按钮和监听程序 32 组合按钮和监听程序 35 Spring Rich Client Project 37 Spring Rich Client Project 概述 37 结束语 38 (二) 适用于各类Swing应用的通用数据验证模块 39 项目创建好后,加入类库: 41 然后写一个persistence bean: 41 Java代码 41 我称这个类为HibernateValidationUI,代码如下: 43 Java代码 43 类中用到的Java2DIconFactory代码如下: 47 Java代码 47 Factory类 49 Java代码 49 最后,我们可以编写一个Demo application来看看效果如何,代码如下: 51 Java代码 51 总结: 55 (三) 对JTree从创建到使用详解 56 (四) JTree的使用方法 57 JTreeDemo.java源程序 57 经验汇总 60 1. 初始化 60 2. 三个经常使用的取值函数 60 3. 根据node得到path: 60 4. 根据Path展开到该节点 60 5. 根据path设定该节点选定 61 6. 选中节点的方法 61 7. 滚动到可见位置 61 8. 给JTree添加右键弹出菜单 61 9. 关于JTree的展开 61 10. 如何遍历JTree 62 (五) JTree右键菜单实现编辑、添加、删除节点 63 Test.java源代码 63 (六) 功能齐全的JTree例子 66 TreeEditTest.java源代码 66 (七) JTree控件的使用 70 构造函数: 70 TreeModel接口 70 DefaultTreeModel缺省版本 71 TreeNode接口 71 TreeExpansionListener接口 71 TreeCellRenderer 72 例子: 73 (八) 如何为JTree添加右键菜单? 75 (九) 如何使JTextArea随着窗体的变化自动调整大小 76 TextAreaTest源代码 76 (十) JAVA swing编程JTree实现系统目录 77 FileTree1.java源代码 77 (十一) Java Swing中的JTree模型 85 Swing.tree包中的主要类名称实现 85 1. 构建树模型 86 2. 树结点 86 树结构详细类图 86 2.1 TreeNode接口 86 2.2 MutableTreeNode接口 87 2.3 DefaultMutableTreeNode类 88 3. 编辑树 88 3.1获得结点路径 88 3.2编辑结点 88 3.3视图显示 89 4. 查找树 89 5. 绘制结点 90 (十二) JTree鼠标左键的双击事件选用那个监听器 91 MouseDemo.java源代码 92 (十三) JTree 92 JTree的构造函数: 93 JTreeDefaultDemo.java源代码 93 (十四) JTree 应用 96 Frame1.java源代码 96 MyDefaultTreeCellRenderer.java源代码 98 (十五) JTree控件 100 树和节点的基本概念 100 有关树JTree的类和接口 100 代码实例:构建一棵树 101 相关语句解释 101 (十六) JTree应用示例——文件路径 103 AnimatedIconTreeExample.java源代码 103 //内部类NodeImageObserver.java源代码 105 //IconNodeRenderer.java源代码 106 //IconNode.java源代码 107 (十七) Swing 学习笔记 108 Swing API 包括18个公共包: 108 例程1.1 HelloWorldSwing.java 109 例程2.2 HelloWorldJFrame.java 110 (十八) 动态加载文件树的java程序 111 FileSystemTree.java源代码 112 //内部类 TreeWillExpandListenerImp.java 114 (十九) 向 Java 应用程序伸出援助之手——用 JavaHelp 2.0 构建下一个 Java 应用程序的帮助系统 115 入门 116 使用 HelpSet 117 HelpSet 数据文件 118 helpset 文件 118 maps 部分 119 view 部分 119 presentation 部分 120 implementation 部分 121 map 文件 121 导航文件 121 TOC 122 Index 122 Glossary 123 Favorites 123 主题文件 123 在 Java 应用程序中调用 JavaHelp 124 自定义外观 125 配置图标 125 基于文字的标签还是基于图像的标签? 125 要工具栏还是不要工具栏? 125 设置字体 126 使用展示窗口 127 <object> 标签 128 四种 activator 129 添加内容敏感的帮助 130 窗口级帮助 131 字段级帮助 131 屏幕级帮助 133 添加嵌入帮助 135 添加搜索功能 136 停用词 137 自定义停用词列表 137 合并 helpset 138 静态和动态合并 139 添加轻量级组件 141 基于服务器的帮助 144 设置 144 JavaHelp 服务器 bean 144 JavaScript 文件 145 JSP 文件 145 测试服务器端帮助 148 结束语 149
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值