2015-07-13 45 views
1

當我點擊JButton時沒有任何反應。這甚至適用於我放入的JScrollPane(它顯示,但不會滾動)。爲什麼JPanel不在前面?我明白必須重寫某些東西。是不是箭頭的擴展部分?如果是這樣,那是怎麼做的?如何將JPanel的組件作爲JTree中的節點使用?

import java.awt.*; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import javax.swing.*; 
import javax.swing.tree.*; 

public class test { 

public test() { 

    JTree tree = createTree(); 
    tree.setToggleClickCount(0); 
    tree.setRowHeight(50); 
    tree.setCellRenderer(new PanelRenderer()); 

    JFrame f = new JFrame(); 
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    f.add(new JScrollPane(tree)); 

    f.setSize(400, 400); 
    f.setLocation(200, 200); 
    f.setVisible(true); 
} 

private JTree createTree() { 
    int children = 4; 
    int grandChildren = 3; 
    DefaultMutableTreeNode root = new DefaultMutableTreeNode(); 
    DefaultMutableTreeNode node; 
    for (int j = 0; j < children; j++) { 
     node = new DefaultMutableTreeNode(); 
     root.add(node); 
     for (int k = 0; k < grandChildren; k++) 
      node.add(new DefaultMutableTreeNode()); 
    } 
    DefaultTreeModel model = new DefaultTreeModel(root); 
    return new JTree(model); 
} 

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

class PanelRenderer implements TreeCellRenderer { 
JPanel panel; 

public PanelRenderer() { 
    panel = new JPanel(new BorderLayout()); 
} 

public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, 
     boolean leaf, int row, boolean hasFocus) { 

    panel.add(new JLabel("aloha"), BorderLayout.WEST); 
    JButton fg = new JButton("fg"); 
    panel.add(fg, BorderLayout.EAST); 
    fg.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent d) { 
      System.out.println("hello"); 
     } 
    }); 
    panel.setPreferredSize(new Dimension(200, 500)); 
    return panel; 
} 
} 

這是爲MadProgrammer誰說,渲染器和編輯製作你放下的東西的圖像。在這個例子中,JButtons是可點擊的。

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

public class test extends JFrame { 

public test() { 
    super("TreeDemo"); 
    setSize(500, 500); 
    JPanel p = new JPanel(); 
    p.setLayout(new BorderLayout()); 

    JButton theParent = new JButton("Feature Set #1"); 
    JButton thefeature = new JButton("sdfdsfds"); 
    JButton feature2 = new JButton("Second Feature"); 
    JButton feature3 = new JButton("Third Feature"); 
    DefaultMutableTreeNode top = new DefaultMutableTreeNode(theParent, true); 
    DefaultMutableTreeNode n1 = new DefaultMutableTreeNode(thefeature, true); 
    DefaultMutableTreeNode n2 = new DefaultMutableTreeNode(feature2, true); 
    DefaultMutableTreeNode n3 = new DefaultMutableTreeNode(feature3, false); 

    n1.add(n3); 
    top.add(n1); 
    top.add(n2); 
    JTree tree = new JTree(top); 
    p.add(tree, BorderLayout.NORTH); 
    getContentPane().add(p); 
    TestRenderer tr = new TestRenderer(); 
    TestEditor1 te = new TestEditor1(); 

    tree.setEditable(true); 
    tree.setCellRenderer(tr); 
    tree.setCellEditor(te); 
} 

public class TestEditor1 implements TreeCellEditor { 

    public TestEditor1() { 
    } 

    public void addCellEditorListener(CellEditorListener l) { 
    } 

    public void cancelCellEditing() { 
    } 

    public Object getCellEditorValue() { 
     return this; 
    } 

    public boolean isCellEditable(EventObject evt) { 
     if (evt instanceof MouseEvent) { 
      MouseEvent mevt = (MouseEvent) evt; 

      if (mevt.getClickCount() == 1) { 
       return true; 
      } 
     } 

     return false; 
    } 

    public void removeCellEditorListener(CellEditorListener l) { 
    } 

    public boolean shouldSelectCell(EventObject anEvent) { 
     return true; 
    } 

    public boolean stopCellEditing() { 
     return false; 
    } 

    public Component getTreeCellEditorComponent(JTree tree, Object value, boolean isSelected, boolean expanded, 
      boolean leaf, int row) { 
     DefaultMutableTreeNode temp = (DefaultMutableTreeNode) value; 
     JComponent temp2 = (JComponent) temp.getUserObject(); 
     return temp2; 

    } 
} 

public class TestRenderer implements TreeCellRenderer { 
    transient protected Icon closedIcon; 
    transient protected Icon openIcon; 

    public TestRenderer() { 
    } 

    public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, 
      boolean leaf, int row, boolean hasFocus) { 
     DefaultMutableTreeNode temp = (DefaultMutableTreeNode) value; 
     JComponent temp2 = (JComponent) temp.getUserObject(); 
     temp2.setBackground(UIManager.getColor("Tree.textBackground")); 

     return temp2; 
    } 

    public void setClosedIcon(Icon newIcon) { 
     closedIcon = newIcon; 
    } 

    public void setOpenIcon(Icon newIcon) { 
     openIcon = newIcon; 
    } 
} 

public static void main(String args[]){ 
JFrame frame = new test(); 
    frame.addWindowListener(new WindowAdapter() 
{ 
     public void windowClosing(WindowEvent e) 
{ 
      System.exit(0); 
     } 
}); 

frame.pack(); 
    frame.setVisible(true); 
} 
+0

開始由具有一看[概念:編輯和渲染器(http://docs.oracle.com/javase/tutorial/uiswing/components/table.html#editrender)。渲染器不過是直接繪製到另一個組件上的組件的「圖像」,它不是「活動」組件 – MadProgrammer

+0

渲染器是一個「橡皮圖章」,編輯器是一個活動組件,它可以與用戶交互...(希望你沒有履行'TreeCellEditor'的合同) – MadProgrammer

+0

等一下,爲什麼這個工作?請參閱我已添加到帖子中的添加內容。是否因爲JButton在渲染器之外初始化? – Jeff

回答

1

先看看Concepts: Editors and Renderers

渲染器只是一個「橡皮圖章」,用於「戳記」組件呈現的數據視圖,而不是生命組件。視圖中的每個單元格都使用同一個渲染實例呈現。

另一方面,編輯器是一個實時組件,它可以響應用戶交互。一個視圖一次只有一個活動的編輯器。

你的模型不應該攜帶組件,它們應該只是攜帶你需要的狀態信息來渲染(編輯)它。

TreeEditor

import java.awt.Component; 
import java.awt.EventQueue; 
import javax.swing.AbstractCellEditor; 
import javax.swing.JCheckBox; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JScrollPane; 
import javax.swing.JTree; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 
import javax.swing.tree.DefaultMutableTreeNode; 
import javax.swing.tree.DefaultTreeModel; 
import javax.swing.tree.TreeCellEditor; 
import javax.swing.tree.TreeCellRenderer; 

public class Test { 

    public Test() { 

     JTree tree = createTree(); 
     tree.setToggleClickCount(0); 
     tree.setCellRenderer(new StateRenderer()); 
     tree.setCellEditor(new StateEditor()); 
     tree.setEditable(true); 

     JFrame f = new JFrame(); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     f.add(new JScrollPane(tree)); 

     f.pack(); 
     f.setLocationRelativeTo(null); 
     f.setVisible(true); 
    } 

    private JTree createTree() { 
     int children = 4; 
     int grandChildren = 2; 
     DefaultMutableTreeNode root = new DefaultMutableTreeNode(new State("Films", false)); 
     DefaultMutableTreeNode node; 

     String[] cat = {"Sci-Fi", "Fantasy", "Action", "Comedy"}; 
     String[][] films = { 
      {"Star Wars", "Star Trek"}, 
      {"Lord of the Rings", "Conan"}, 
      {"Terminator", "Transformers"}, 
      {"Cheaper by the Doze", "Father of the Bride"} 
     }; 
     for (int j = 0; j < children; j++) { 
      node = new DefaultMutableTreeNode(new State(cat[j], false)); 
      root.add(node); 
      for (int k = 0; k < grandChildren; k++) { 
       node.add(new DefaultMutableTreeNode(new State(films[j][k], false))); 
      } 
     } 
     DefaultTreeModel model = new DefaultTreeModel(root); 
     return new JTree(model); 
    } 

    public static void main(String[] args) { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
        ex.printStackTrace(); 
       } 
       new Test(); 
      } 
     }); 
    } 

    public class State { 

     private String text; 
     private boolean selected; 

     public State(String text, boolean selected) { 
      this.text = text; 
      this.selected = selected; 
     } 

     public String getText() { 
      return text; 
     } 

     public boolean isSelected() { 
      return selected; 
     } 

     public void setSelected(boolean selected) { 
      this.selected = selected; 
     } 

    } 

    public class StateEditor extends AbstractCellEditor implements TreeCellEditor { 

     //JPanel panel; 
     private JCheckBox checkBox; 

     private State editorValue; 

     public StateEditor() { 
      checkBox = new JCheckBox(); 
      checkBox.setOpaque(false); 
     } 

     @Override 
     public Object getCellEditorValue() { 
      editorValue.setSelected(checkBox.isSelected()); 
      return editorValue; 
     } 

     @Override 
     public Component getTreeCellEditorComponent(JTree tree, Object value, boolean isSelected, boolean expanded, boolean leaf, int row) { 

      System.out.println("..."); 

      if (value instanceof DefaultMutableTreeNode) { 
       DefaultMutableTreeNode node = (DefaultMutableTreeNode) value; 
       State state = (State) node.getUserObject(); 
       editorValue = state; 
       checkBox.setText(state.getText()); 
       checkBox.setSelected(state.isSelected()); 
      } else { 
       checkBox.setText("??"); 
       checkBox.setSelected(false); 
      } 

      return checkBox; 

     } 

    } 

    public class StateRenderer implements TreeCellRenderer { 

     private JCheckBox checkBox; 

     public StateRenderer() { 
      checkBox = new JCheckBox(); 
      checkBox.setOpaque(false); 
     } 

     @Override 
     public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, 
         boolean leaf, int row, boolean hasFocus) { 

      if (value instanceof DefaultMutableTreeNode) { 
       DefaultMutableTreeNode node = (DefaultMutableTreeNode) value; 
       State state = (State) node.getUserObject(); 
       checkBox.setText(state.getText()); 
       checkBox.setSelected(state.isSelected()); 
      } else { 
       checkBox.setText("??"); 
       checkBox.setSelected(false); 
      } 

      if (selected) { 
       checkBox.setBackground(UIManager.getColor("Tree.selectionBackground")); 
       checkBox.setForeground(UIManager.getColor("Tree.selectionForeground")); 
      } else { 
       checkBox.setForeground(tree.getForeground()); 
      } 

      checkBox.setOpaque(selected); 

      return checkBox; 
     } 
    } 
}