2014-02-13 66 views
0

我有一個JTree在鞦韆。樹節點應該包含帶有選項卡的面板。選項卡應該包含帶有滾動窗格的textarea。問題是我能夠在樹節點中添加選項卡面板,但問題是我無法從一個選項卡移動到另一個選項卡。看起來面板被禁用。任何幫助或建議表示讚賞。提前致謝。下面是我的代碼:JTree與選項卡式面板作爲樹節點

import java.awt.Component; 
import java.awt.Dimension; 
import java.awt.GridLayout; 
import java.awt.event.MouseEvent; 
import java.util.EventObject; 
import java.util.Random; 

import javax.swing.AbstractCellEditor; 
import javax.swing.JComponent; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.JScrollPane; 
import javax.swing.JTabbedPane; 
import javax.swing.JTree; 
import javax.swing.event.TreeSelectionEvent; 
import javax.swing.event.TreeSelectionListener; 
import javax.swing.tree.DefaultMutableTreeNode; 
import javax.swing.tree.DefaultTreeModel; 
import javax.swing.tree.TreeCellEditor; 
import javax.swing.tree.TreeCellRenderer; 
import javax.swing.tree.TreePath; 

public class ModifiedTreePanel 
{ 
    Random seed; 

    public ModifiedTreePanel() 
    { 
     seed = new Random(); 

     // south section 
     final JLabel colorLabel = new JLabel(); 
     colorLabel.setHorizontalAlignment(JLabel.CENTER); 
     Dimension d = colorLabel.getPreferredSize(); 
     d.height = 25; 
     colorLabel.setPreferredSize(d); 

     // center section 
     JTree tree = createTree(); 
     tree.setCellRenderer(new CustomRenderer(tree)); 
     tree.getSelectionModel().addTreeSelectionListener( 
             new TreeSelectionListener() 
     { 
      public void valueChanged(TreeSelectionEvent e) 
      { 

      } 
     }); 

     JFrame f = new JFrame(); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     f.add(new JScrollPane(tree)); 
     f.add(colorLabel, "South"); 
     f.setSize(400,400); 
     f.setLocation(200,200); 
     f.setVisible(true); 
    } 

    protected JComponent createTabbedPanel (String text) { 
     JPanel panel = new JPanel(new GridLayout(1, 1)); 

     JTabbedPane tabbedPane = new JTabbedPane(); 

     JComponent panel1 = makeTextPanel("Panel #1"); 
     tabbedPane.addTab("Tab 1", panel1); 
     panel1.setPreferredSize(new Dimension(200, 100)); 

     JComponent panel2 = makeTextPanel("Panel #2"); 
     tabbedPane.addTab("Tab 2", panel2); 

     JComponent panel3 = makeTextPanel("Panel #3"); 
     tabbedPane.addTab("Tab 3", panel3); 

     panel.add(tabbedPane); 
     tabbedPane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT); 

     panel.setEnabled(true); 
     return panel; 
    } 

    protected JComponent makeTextPanel (String text) { 
      JPanel panel = new JPanel(false); 
      JLabel filler = new JLabel(text); 
      filler.setHorizontalAlignment(JLabel.CENTER); 
      panel.setLayout (new GridLayout(1,1)); 
      panel.add(filler); 
      return panel; 
    } 

    private JTree createTree() 
    { 
     int children = 4; 
     int grandChildren = 1; 

     DefaultMutableTreeNode root = new DefaultMutableTreeNode("Root"); 
     DefaultMutableTreeNode node; 
     for(int j = 0; j < children; j++) 
     { 
      node = new DefaultMutableTreeNode("Child-"+String.valueOf(j)); 

      root.add(node); 
       for(int k = 0; k < grandChildren; k++) 
        node.add(new DefaultMutableTreeNode(createTabbedPanel("Grand-" + String.valueOf(k)))); 
     } 
     DefaultTreeModel model = new DefaultTreeModel(root); 
     return new JTree(model); 
    } 

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

class CustomRenderer extends AbstractCellEditor 
    implements TreeCellRenderer, TreeCellEditor 
{  

    final JTree tree; 

    public CustomRenderer (JTree tree) { 
     this.tree = tree; 
    } 


    public Component getTreeCellRendererComponent(JTree tree, 
                Object value, 
                boolean selected, 
                boolean expanded, 
                boolean leaf, 
                int row, 
                boolean hasFocus) 
    { 
     Object nodeObject = ((DefaultMutableTreeNode)value).getUserObject(); 
     if (nodeObject instanceof JPanel){ 
      JPanel panel = (JPanel) nodeObject;  
      panel.setPreferredSize(new Dimension(200, 100)); 
      return panel; 
     } else{ 
      return new JLabel(nodeObject.toString()); 
     } 

    } 

    public Component getTreeCellEditorComponent(
      JTree tree, Object value, boolean selected, 
      boolean expanded, boolean leaf, int row) { 
     return getTreeCellRendererComponent(
       tree, value, true, expanded, leaf, row, true); 
    } 

    public boolean isCellEditable(final EventObject event) { 
     if (!(event instanceof MouseEvent)) { 
      return false; 
     } 

     final MouseEvent mouseEvent = (MouseEvent) event; 
     final TreePath path = tree.getPathForLocation(
       mouseEvent.getX(), mouseEvent.getY()); 
     if (path == null) { 
      return false; 
     } 

     Object node = path.getLastPathComponent(); 
     if (node == null || (!(node instanceof DefaultMutableTreeNode))) { 
      return false; 
     } 

     DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode) node; 
     Object userObject = treeNode.getUserObject(); 

     return (userObject instanceof JPanel); 
    } 


    @Override 
    public Object getCellEditorValue() { 
     return null; 
    } 

} 
+0

單元渲染的 「快照」,並沒有真正的帶電部件。 – MadProgrammer

+0

開始應用你的學習(mad's引用),而不是在你的節點中存儲組件:而是存儲數據並讓渲染器/編輯器完成他們的工作 – kleopatra

回答

2

單元渲染的「快照」,並沒有真正的帶電部件

Concepts: Editors and Renderers

您必須提供該節點的自定義編輯器,並建立它的內容每次根據原始節點的內容激活編輯器。

你不應該做的是使用組件作爲節點的userObject屬性,而是將信息傳遞給節點,渲染器和編輯器都可以使用這些信息構造它們各自的視圖。

看看:

對於一些例子...

+0

感謝您的回覆。你能否修改我的發佈代碼? – pintu

+0

@pintu _你可以修改我發佈的代碼和修改的內容_當然他可以,但很可能不會(除非你僱用他作爲你的顧問,也許;-) - 這是你的工作來理解引用,沒有什麼其他人可以幫助你。如果沒有這樣的理解,代碼就沒有多大的幫助,因爲下次再次圍繞你將無法解決類似的問題。因此,請嘗試自己使用它們,並在卡住時回來,解釋您在哪裏遇到問題 – kleopatra

+0

@kleopatra感謝您的建議。我問了一個關於我發佈的代碼的例子。在我看來,這很複雜,因爲我是編程java swing的初學者,並且節點也包含一個複雜的組件。當然我會嘗試,如果想出一個問題,我會來找你。 – pintu

相關問題