我有一个JTree。树节点应包含带选项卡的面板。选项卡应包含带滚动窗格的textarea。问题是我能够在树节点中添加带有选项卡的面板,但问题是我无法从一个选项卡转到另一个选项卡。面板似乎已禁用。任何帮助或建议表示赞赏。提前致谢。以下是我的代码:
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 :(得分:2)
单元格渲染器是“快照”并且不是真实的实时组件
请参阅Concepts: Editors and Renderers
每次根据原始节点的内容激活编辑器时,您必须为节点提供自定义编辑器并构建其内容。
您不应该使用组件作为节点的userObject
属性,而是将信息传递给节点,渲染器和编辑器都可以使用它来构建各自的视图。
看看:
举个例子......