提交 a2f14590 编写于 作者: M mrkam

7027698: /jfc/SampleTree demo needs to be improved

Reviewed-by: rupashka
上级 1080aa8f
/* /*
* Copyright (c) 1997, 1998, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
...@@ -29,154 +29,154 @@ ...@@ -29,154 +29,154 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
/*
*/
import javax.swing.tree.DefaultMutableTreeNode;
import java.awt.Color; import java.awt.Color;
import java.awt.Font; import java.awt.Font;
import java.awt.Toolkit; import java.awt.GraphicsEnvironment;
import java.util.Random; import java.util.Random;
import javax.swing.tree.DefaultMutableTreeNode;
/**
* DynamicTreeNode illustrates one of the possible ways in which dynamic
* loading can be used in tree. The basic premise behind this is that
* getChildCount() will be messaged from JTreeModel before any children
* are asked for. So, the first time getChildCount() is issued the
* children are loaded.<p>
* It should be noted that isLeaf will also be messaged from the model.
* The default behavior of TreeNode is to message getChildCount to
* determine this. As such, isLeaf is subclassed to always return false.<p>
* There are others ways this could be accomplished as well. Instead of
* subclassing TreeNode you could subclass JTreeModel and do the same
* thing in getChildCount(). Or, if you aren't using TreeNode you could
* write your own TreeModel implementation.
* Another solution would be to listen for TreeNodeExpansion events and
* the first time a node has been expanded post the appropriate insertion
* events. I would not recommend this approach though, the other two
* are much simpler and cleaner (and are faster from the perspective of
* how tree deals with it).
*
* NOTE: getAllowsChildren() can be messaged before getChildCount().
* For this example the nodes always allow children, so it isn't
* a problem, but if you do support true leaf nodes you may want
* to check for loading in getAllowsChildren too.
*
* @author Scott Violet
*/
public class DynamicTreeNode extends DefaultMutableTreeNode /**
{ * DynamicTreeNode illustrates one of the possible ways in which dynamic
* loading can be used in tree. The basic premise behind this is that
* getChildCount() will be messaged from JTreeModel before any children
* are asked for. So, the first time getChildCount() is issued the
* children are loaded.<p>
* It should be noted that isLeaf will also be messaged from the model.
* The default behavior of TreeNode is to message getChildCount to
* determine this. As such, isLeaf is subclassed to always return false.<p>
* There are others ways this could be accomplished as well. Instead of
* subclassing TreeNode you could subclass JTreeModel and do the same
* thing in getChildCount(). Or, if you aren't using TreeNode you could
* write your own TreeModel implementation.
* Another solution would be to listen for TreeNodeExpansion events and
* the first time a node has been expanded post the appropriate insertion
* events. I would not recommend this approach though, the other two
* are much simpler and cleaner (and are faster from the perspective of
* how tree deals with it).
*
* NOTE: getAllowsChildren() can be messaged before getChildCount().
* For this example the nodes always allow children, so it isn't
* a problem, but if you do support true leaf nodes you may want
* to check for loading in getAllowsChildren too.
*
* @author Scott Violet
*/
@SuppressWarnings("serial")
public class DynamicTreeNode extends DefaultMutableTreeNode {
// Class stuff. // Class stuff.
/** Number of names. */
static protected float nameCount;
/** Number of names. */
protected static float nameCount;
/** Names to use for children. */ /** Names to use for children. */
static protected String[] names; protected static final String[] NAMES;
/** Potential fonts used to draw with. */ /** Potential fonts used to draw with. */
static protected Font[] fonts; protected static Font[] fonts;
/** Used to generate the names. */ /** Used to generate the names. */
static protected Random nameGen; protected static Random nameGen;
/** Number of children to create for each node. */ /** Number of children to create for each node. */
static protected final int DefaultChildrenCount = 7; protected static final int DEFAULT_CHILDREN_COUNT = 7;
static { static {
String[] fontNames; String[] fontNames;
try { try {
fontNames = Toolkit.getDefaultToolkit().getFontList(); fontNames = GraphicsEnvironment.getLocalGraphicsEnvironment().
getAvailableFontFamilyNames();
} catch (Exception e) { } catch (Exception e) {
fontNames = null; fontNames = null;
} }
if(fontNames == null || fontNames.length == 0) { if (fontNames == null || fontNames.length == 0) {
names = new String[] {"Mark Andrews", "Tom Ball", "Alan Chung", NAMES = new String[] { "Mark Andrews", "Tom Ball", "Alan Chung",
"Rob Davis", "Jeff Dinkins", "Rob Davis", "Jeff Dinkins",
"Amy Fowler", "James Gosling", "Amy Fowler", "James Gosling",
"David Karlton", "Dave Kloba", "David Karlton", "Dave Kloba",
"Dave Moore", "Hans Muller", "Dave Moore", "Hans Muller",
"Rick Levenson", "Tim Prinzing", "Rick Levenson", "Tim Prinzing",
"Chester Rose", "Ray Ryan", "Chester Rose", "Ray Ryan",
"Georges Saab", "Scott Violet", "Georges Saab", "Scott Violet",
"Kathy Walrath", "Arnaud Weber" }; "Kathy Walrath", "Arnaud Weber" };
} } else {
else {
/* Create the Fonts, creating fonts is slow, much better to /* Create the Fonts, creating fonts is slow, much better to
do it once. */ do it once. */
int fontSize = 12; int fontSize = 12;
names = fontNames; NAMES = fontNames;
fonts = new Font[names.length]; fonts = new Font[NAMES.length];
for(int counter = 0, maxCounter = names.length; for (int counter = 0, maxCounter = NAMES.length;
counter < maxCounter; counter++) { counter < maxCounter; counter++) {
try { try {
fonts[counter] = new Font(fontNames[counter], 0, fontSize); fonts[counter] = new Font(fontNames[counter], 0, fontSize);
} } catch (Exception e) {
catch (Exception e) {
fonts[counter] = null; fonts[counter] = null;
} }
fontSize = ((fontSize + 2 - 12) % 12) + 12; fontSize = ((fontSize + 2 - 12) % 12) + 12;
} }
} }
nameCount = (float)names.length; nameCount = (float) NAMES.length;
nameGen = new Random(System.currentTimeMillis()); nameGen = new Random(System.currentTimeMillis());
} }
/** Have the children of this node been loaded yet? */ /** Have the children of this node been loaded yet? */
protected boolean hasLoaded; protected boolean hasLoaded;
/** /**
* Constructs a new DynamicTreeNode instance with o as the user * Constructs a new DynamicTreeNode instance with o as the user
* object. * object.
*/ */
public DynamicTreeNode(Object o) { public DynamicTreeNode(Object o) {
super(o); super(o);
} }
@Override
public boolean isLeaf() { public boolean isLeaf() {
return false; return false;
} }
/** /**
* If hasLoaded is false, meaning the children have not yet been * If hasLoaded is false, meaning the children have not yet been
* loaded, loadChildren is messaged and super is messaged for * loaded, loadChildren is messaged and super is messaged for
* the return value. * the return value.
*/ */
@Override
public int getChildCount() { public int getChildCount() {
if(!hasLoaded) { if (!hasLoaded) {
loadChildren(); loadChildren();
} }
return super.getChildCount(); return super.getChildCount();
} }
/** /**
* Messaged the first time getChildCount is messaged. Creates * Messaged the first time getChildCount is messaged. Creates
* children with random names from names. * children with random names from names.
*/ */
protected void loadChildren() { protected void loadChildren() {
DynamicTreeNode newNode; DynamicTreeNode newNode;
Font font; Font font;
int randomIndex; int randomIndex;
SampleData data; SampleData data;
for(int counter = 0; counter < DynamicTreeNode.DefaultChildrenCount; for (int counter = 0; counter < DynamicTreeNode.DEFAULT_CHILDREN_COUNT;
counter++) { counter++) {
randomIndex = (int)(nameGen.nextFloat() * nameCount); randomIndex = (int) (nameGen.nextFloat() * nameCount);
if(fonts != null) String displayString = NAMES[randomIndex];
font = fonts[randomIndex]; if (fonts == null || fonts[randomIndex].canDisplayUpTo(displayString)
else != -1) {
font = null; font = null;
if(counter % 2 == 0) } else {
data = new SampleData(font, Color.red, names[randomIndex]); font = fonts[randomIndex];
else }
data = new SampleData(font, Color.blue, names[randomIndex]);
if (counter % 2 == 0) {
data = new SampleData(font, Color.red, displayString);
} else {
data = new SampleData(font, Color.blue, displayString);
}
newNode = new DynamicTreeNode(data); newNode = new DynamicTreeNode(data);
/* Don't use add() here, add calls insert(newNode, getChildCount()) /* Don't use add() here, add calls insert(newNode, getChildCount())
so if you want to use add, just be sure to set hasLoaded = true so if you want to use add, just be sure to set hasLoaded = true
first. */ first. */
insert(newNode, counter); insert(newNode, counter);
} }
/* This node has now been loaded, mark it so. */ /* This node has now been loaded, mark it so. */
......
/* /*
* Copyright (c) 1997, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
...@@ -29,32 +29,27 @@ ...@@ -29,32 +29,27 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
/*
*/
import java.awt.Color; import java.awt.Color;
import java.awt.Font; import java.awt.Font;
/** /**
* @author Scott Violet * @author Scott Violet
*/ */
public class SampleData extends Object {
public class SampleData extends Object
{
/** Font used for drawing. */ /** Font used for drawing. */
protected Font font; protected Font font;
/** Color used for text. */ /** Color used for text. */
protected Color color; protected Color color;
/** Value to display. */ /** Value to display. */
protected String string; protected String string;
/** /**
* Constructs a new instance of SampleData with the passed in * Constructs a new instance of SampleData with the passed in
* arguments. * arguments.
*/ */
public SampleData(Font newFont, Color newColor, String newString) { public SampleData(Font newFont, Color newColor, String newString) {
font = newFont; font = newFont;
color = newColor; color = newColor;
...@@ -62,47 +57,48 @@ public class SampleData extends Object ...@@ -62,47 +57,48 @@ public class SampleData extends Object
} }
/** /**
* Sets the font that is used to represent this object. * Sets the font that is used to represent this object.
*/ */
public void setFont(Font newFont) { public void setFont(Font newFont) {
font = newFont; font = newFont;
} }
/** /**
* Returns the Font used to represent this object. * Returns the Font used to represent this object.
*/ */
public Font getFont() { public Font getFont() {
return font; return font;
} }
/** /**
* Sets the color used to draw the text. * Sets the color used to draw the text.
*/ */
public void setColor(Color newColor) { public void setColor(Color newColor) {
color = newColor; color = newColor;
} }
/** /**
* Returns the color used to draw the text. * Returns the color used to draw the text.
*/ */
public Color getColor() { public Color getColor() {
return color; return color;
} }
/** /**
* Sets the string to display for this object. * Sets the string to display for this object.
*/ */
public void setString(String newString) { public void setString(String newString) {
string = newString; string = newString;
} }
/** /**
* Returnes the string to display for this object. * Returnes the string to display for this object.
*/ */
public String string() { public String string() {
return string; return string;
} }
@Override
public String toString() { public String toString() {
return string; return string;
} }
......
/* /*
* Copyright (c) 1997, 2004, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
...@@ -29,9 +29,10 @@ ...@@ -29,9 +29,10 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
/*
*/
import java.lang.reflect.InvocationTargetException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*; import javax.swing.*;
import javax.swing.event.*; import javax.swing.event.*;
import java.awt.BorderLayout; import java.awt.BorderLayout;
...@@ -40,58 +41,57 @@ import java.awt.Dimension; ...@@ -40,58 +41,57 @@ import java.awt.Dimension;
import java.awt.FlowLayout; import java.awt.FlowLayout;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.*; import java.util.*;
import javax.swing.UIManager.LookAndFeelInfo;
import javax.swing.border.*; import javax.swing.border.*;
import javax.swing.tree.*; import javax.swing.tree.*;
/** /**
* A demo for illustrating how to do different things with JTree. * A demo for illustrating how to do different things with JTree.
* The data that this displays is rather boring, that is each node will * The data that this displays is rather boring, that is each node will
* have 7 children that have random names based on the fonts. Each node * have 7 children that have random names based on the fonts. Each node
* is then drawn with that font and in a different color. * is then drawn with that font and in a different color.
* While the data isn't interesting the example illustrates a number * While the data isn't interesting the example illustrates a number
* of things: * of things:
* *
* For an example of dynamicaly loading children refer to DynamicTreeNode. * For an example of dynamicaly loading children refer to DynamicTreeNode.
* For an example of adding/removing/inserting/reloading refer to the inner * For an example of adding/removing/inserting/reloading refer to the inner
* classes of this class, AddAction, RemovAction, InsertAction and * classes of this class, AddAction, RemovAction, InsertAction and
* ReloadAction. * ReloadAction.
* For an example of creating your own cell renderer refer to * For an example of creating your own cell renderer refer to
* SampleTreeCellRenderer. * SampleTreeCellRenderer.
* For an example of subclassing JTreeModel for editing refer to * For an example of subclassing JTreeModel for editing refer to
* SampleTreeModel. * SampleTreeModel.
* *
* @author Scott Violet * @author Scott Violet
*/ */
public final class SampleTree {
public class SampleTree
{
/** Window for showing Tree. */ /** Window for showing Tree. */
protected JFrame frame; protected JFrame frame;
/** Tree used for the example. */ /** Tree used for the example. */
protected JTree tree; protected JTree tree;
/** Tree model. */ /** Tree model. */
protected DefaultTreeModel treeModel; protected DefaultTreeModel treeModel;
/** /**
* Constructs a new instance of SampleTree. * Constructs a new instance of SampleTree.
*/ */
public SampleTree() { public SampleTree() {
// Force SampleTree to come up in the Cross Platform L&F // Trying to set Nimbus look and feel
try { try {
UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName()); for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
// If you want the System L&F instead, comment out the above line and if ("Nimbus".equals(info.getName())) {
// uncomment the following: UIManager.setLookAndFeel(info.getClassName());
// UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); break;
} catch (Exception exc) { }
System.err.println("Error loading L&F: " + exc); }
} catch (Exception ignored) {
} }
JMenuBar menuBar = constructMenuBar();
JMenuBar menuBar = constructMenuBar(); JPanel panel = new JPanel(true);
JPanel panel = new JPanel(true);
frame = new JFrame("SampleTree"); frame = new JFrame("SampleTree");
frame.getContentPane().add("Center", panel); frame.getContentPane().add("Center", panel);
...@@ -106,18 +106,18 @@ public class SampleTree ...@@ -106,18 +106,18 @@ public class SampleTree
tree = new JTree(treeModel); tree = new JTree(treeModel);
/* Enable tool tips for the tree, without this tool tips will not /* Enable tool tips for the tree, without this tool tips will not
be picked up. */ be picked up. */
ToolTipManager.sharedInstance().registerComponent(tree); ToolTipManager.sharedInstance().registerComponent(tree);
/* Make the tree use an instance of SampleTreeCellRenderer for /* Make the tree use an instance of SampleTreeCellRenderer for
drawing. */ drawing. */
tree.setCellRenderer(new SampleTreeCellRenderer()); tree.setCellRenderer(new SampleTreeCellRenderer());
/* Make tree ask for the height of each row. */ /* Make tree ask for the height of each row. */
tree.setRowHeight(-1); tree.setRowHeight(-1);
/* Put the Tree in a scroller. */ /* Put the Tree in a scroller. */
JScrollPane sp = new JScrollPane(); JScrollPane sp = new JScrollPane();
sp.setPreferredSize(new Dimension(300, 300)); sp.setPreferredSize(new Dimension(300, 300));
sp.getViewport().add(tree); sp.getViewport().add(tree);
...@@ -126,19 +126,18 @@ public class SampleTree ...@@ -126,19 +126,18 @@ public class SampleTree
panel.add("Center", sp); panel.add("Center", sp);
panel.add("South", constructOptionsPanel()); panel.add("South", constructOptionsPanel());
frame.addWindowListener( new WindowAdapter() { frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
public void windowClosing(WindowEvent e) {System.exit(0);}});
frame.pack(); frame.pack();
frame.show(); frame.setVisible(true);
} }
/** Constructs a JPanel containing check boxes for the different /** Constructs a JPanel containing check boxes for the different
* options that tree supports. */ * options that tree supports. */
@SuppressWarnings("serial")
private JPanel constructOptionsPanel() { private JPanel constructOptionsPanel() {
JCheckBox aCheckbox; JCheckBox aCheckbox;
JPanel retPanel = new JPanel(false); JPanel retPanel = new JPanel(false);
JPanel borderPane = new JPanel(false); JPanel borderPane = new JPanel(false);
borderPane.setLayout(new BorderLayout()); borderPane.setLayout(new BorderLayout());
retPanel.setLayout(new FlowLayout()); retPanel.setLayout(new FlowLayout());
...@@ -162,39 +161,54 @@ public class SampleTree ...@@ -162,39 +161,54 @@ public class SampleTree
borderPane.add(retPanel, BorderLayout.CENTER); borderPane.add(retPanel, BorderLayout.CENTER);
/* Create a set of radio buttons that dictate what selection should /* Create a set of radio buttons that dictate what selection should
be allowed in the tree. */ be allowed in the tree. */
ButtonGroup group = new ButtonGroup(); ButtonGroup group = new ButtonGroup();
JPanel buttonPane = new JPanel(false); JPanel buttonPane = new JPanel(false);
JRadioButton button; JRadioButton button;
buttonPane.setLayout(new FlowLayout()); buttonPane.setLayout(new FlowLayout());
buttonPane.setBorder(new TitledBorder("Selection Mode")); buttonPane.setBorder(new TitledBorder("Selection Mode"));
button = new JRadioButton("Single"); button = new JRadioButton("Single");
button.addActionListener(new AbstractAction() { button.addActionListener(new AbstractAction() {
public boolean isEnabled() { return true; }
@Override
public boolean isEnabled() {
return true;
}
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
tree.getSelectionModel().setSelectionMode tree.getSelectionModel().setSelectionMode(
(TreeSelectionModel.SINGLE_TREE_SELECTION); TreeSelectionModel.SINGLE_TREE_SELECTION);
} }
}); });
group.add(button); group.add(button);
buttonPane.add(button); buttonPane.add(button);
button = new JRadioButton("Contiguous"); button = new JRadioButton("Contiguous");
button.addActionListener(new AbstractAction() { button.addActionListener(new AbstractAction() {
public boolean isEnabled() { return true; }
@Override
public boolean isEnabled() {
return true;
}
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
tree.getSelectionModel().setSelectionMode tree.getSelectionModel().setSelectionMode(
(TreeSelectionModel.CONTIGUOUS_TREE_SELECTION); TreeSelectionModel.CONTIGUOUS_TREE_SELECTION);
} }
}); });
group.add(button); group.add(button);
buttonPane.add(button); buttonPane.add(button);
button = new JRadioButton("Discontiguous"); button = new JRadioButton("Discontiguous");
button.addActionListener(new AbstractAction() { button.addActionListener(new AbstractAction() {
public boolean isEnabled() { return true; }
@Override
public boolean isEnabled() {
return true;
}
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
tree.getSelectionModel().setSelectionMode tree.getSelectionModel().setSelectionMode(
(TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION); TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION);
} }
}); });
button.setSelected(true); button.setSelected(true);
...@@ -209,33 +223,33 @@ public class SampleTree ...@@ -209,33 +223,33 @@ public class SampleTree
/* /*
JPanel clickPanel = new JPanel(); JPanel clickPanel = new JPanel();
Object[] values = { "Never", new Integer(1), Object[] values = { "Never", new Integer(1),
new Integer(2), new Integer(3) }; new Integer(2), new Integer(3) };
final JComboBox clickCBox = new JComboBox(values); final JComboBox clickCBox = new JComboBox(values);
clickPanel.setLayout(new FlowLayout()); clickPanel.setLayout(new FlowLayout());
clickPanel.add(new JLabel("Click count to expand:")); clickPanel.add(new JLabel("Click count to expand:"));
clickCBox.setSelectedIndex(2); clickCBox.setSelectedIndex(2);
clickCBox.addActionListener(new ActionListener() { clickCBox.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) { public void actionPerformed(ActionEvent ae) {
Object selItem = clickCBox.getSelectedItem(); Object selItem = clickCBox.getSelectedItem();
if(selItem instanceof Integer) if(selItem instanceof Integer)
tree.setToggleClickCount(((Integer)selItem).intValue()); tree.setToggleClickCount(((Integer)selItem).intValue());
else // Don't toggle else // Don't toggle
tree.setToggleClickCount(0); tree.setToggleClickCount(0);
} }
}); });
clickPanel.add(clickCBox); clickPanel.add(clickCBox);
borderPane.add(clickPanel, BorderLayout.NORTH); borderPane.add(clickPanel, BorderLayout.NORTH);
*/ */
return borderPane; return borderPane;
} }
/** Construct a menu. */ /** Construct a menu. */
private JMenuBar constructMenuBar() { private JMenuBar constructMenuBar() {
JMenu menu; JMenu menu;
JMenuBar menuBar = new JMenuBar(); JMenuBar menuBar = new JMenuBar();
JMenuItem menuItem; JMenuItem menuItem;
/* Good ol exit. */ /* Good ol exit. */
menu = new JMenu("File"); menu = new JMenu("File");
...@@ -243,9 +257,11 @@ public class SampleTree ...@@ -243,9 +257,11 @@ public class SampleTree
menuItem = menu.add(new JMenuItem("Exit")); menuItem = menu.add(new JMenuItem("Exit"));
menuItem.addActionListener(new ActionListener() { menuItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
System.exit(0); System.exit(0);
}}); }
});
/* Tree related stuff. */ /* Tree related stuff. */
menu = new JMenu("Tree"); menu = new JMenu("Tree");
...@@ -267,14 +283,15 @@ public class SampleTree ...@@ -267,14 +283,15 @@ public class SampleTree
} }
/** /**
* Returns the TreeNode instance that is selected in the tree. * Returns the TreeNode instance that is selected in the tree.
* If nothing is selected, null is returned. * If nothing is selected, null is returned.
*/ */
protected DefaultMutableTreeNode getSelectedNode() { protected DefaultMutableTreeNode getSelectedNode() {
TreePath selPath = tree.getSelectionPath(); TreePath selPath = tree.getSelectionPath();
if(selPath != null) if (selPath != null) {
return (DefaultMutableTreeNode)selPath.getLastPathComponent(); return (DefaultMutableTreeNode) selPath.getLastPathComponent();
}
return null; return null;
} }
...@@ -290,133 +307,136 @@ public class SampleTree ...@@ -290,133 +307,136 @@ public class SampleTree
return new DynamicTreeNode(new SampleData(null, Color.black, name)); return new DynamicTreeNode(new SampleData(null, Color.black, name));
} }
/** /**
* AddAction is used to add a new item after the selected item. * AddAction is used to add a new item after the selected item.
*/ */
class AddAction extends Object implements ActionListener class AddAction extends Object implements ActionListener {
{
/** Number of nodes that have been added. */ /** Number of nodes that have been added. */
public int addCount; public int addCount;
/** /**
* Messaged when the user clicks on the Add menu item. * Messaged when the user clicks on the Add menu item.
* Determines the selection from the Tree and adds an item * Determines the selection from the Tree and adds an item
* after that. If nothing is selected, an item is added to * after that. If nothing is selected, an item is added to
* the root. * the root.
*/ */
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
DefaultMutableTreeNode lastItem = getSelectedNode(); DefaultMutableTreeNode lastItem = getSelectedNode();
DefaultMutableTreeNode parent; DefaultMutableTreeNode parent;
/* Determine where to create the new node. */ /* Determine where to create the new node. */
if(lastItem != null) { if (lastItem != null) {
parent = (DefaultMutableTreeNode)lastItem.getParent(); parent = (DefaultMutableTreeNode) lastItem.getParent();
if(parent == null) { if (parent == null) {
parent = (DefaultMutableTreeNode)treeModel.getRoot(); parent = (DefaultMutableTreeNode) treeModel.getRoot();
lastItem = null; lastItem = null;
} }
} else {
parent = (DefaultMutableTreeNode) treeModel.getRoot();
} }
else
parent = (DefaultMutableTreeNode)treeModel.getRoot();
if (parent == null) { if (parent == null) {
// new root // new root
treeModel.setRoot(createNewNode("Added " + treeModel.setRoot(createNewNode("Added " + Integer.toString(
Integer.toString(addCount++))); addCount++)));
} } else {
else { int newIndex;
int newIndex; if (lastItem == null) {
if(lastItem == null)
newIndex = treeModel.getChildCount(parent); newIndex = treeModel.getChildCount(parent);
else } else {
newIndex = parent.getIndex(lastItem) + 1; newIndex = parent.getIndex(lastItem) + 1;
}
/* Let the treemodel know. */ /* Let the treemodel know. */
treeModel.insertNodeInto(createNewNode("Added " + treeModel.insertNodeInto(createNewNode("Added " + Integer.
Integer.toString(addCount++)), toString(addCount++)),
parent, newIndex); parent, newIndex);
} }
} }
} // End of SampleTree.AddAction } // End of SampleTree.AddAction
/** /**
* InsertAction is used to insert a new item before the selected item. * InsertAction is used to insert a new item before the selected item.
*/ */
class InsertAction extends Object implements ActionListener class InsertAction extends Object implements ActionListener {
{
/** Number of nodes that have been added. */ /** Number of nodes that have been added. */
public int insertCount; public int insertCount;
/** /**
* Messaged when the user clicks on the Insert menu item. * Messaged when the user clicks on the Insert menu item.
* Determines the selection from the Tree and inserts an item * Determines the selection from the Tree and inserts an item
* after that. If nothing is selected, an item is added to * after that. If nothing is selected, an item is added to
* the root. * the root.
*/ */
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
DefaultMutableTreeNode lastItem = getSelectedNode(); DefaultMutableTreeNode lastItem = getSelectedNode();
DefaultMutableTreeNode parent; DefaultMutableTreeNode parent;
/* Determine where to create the new node. */ /* Determine where to create the new node. */
if(lastItem != null) { if (lastItem != null) {
parent = (DefaultMutableTreeNode)lastItem.getParent(); parent = (DefaultMutableTreeNode) lastItem.getParent();
if(parent == null) { if (parent == null) {
parent = (DefaultMutableTreeNode)treeModel.getRoot(); parent = (DefaultMutableTreeNode) treeModel.getRoot();
lastItem = null; lastItem = null;
} }
} else {
parent = (DefaultMutableTreeNode) treeModel.getRoot();
} }
else
parent = (DefaultMutableTreeNode)treeModel.getRoot();
if (parent == null) { if (parent == null) {
// new root // new root
treeModel.setRoot(createNewNode("Inserted " + treeModel.setRoot(createNewNode("Inserted " + Integer.toString(
Integer.toString(insertCount++))); insertCount++)));
} } else {
else { int newIndex;
int newIndex;
if(lastItem == null) if (lastItem == null) {
newIndex = treeModel.getChildCount(parent); newIndex = treeModel.getChildCount(parent);
else } else {
newIndex = parent.getIndex(lastItem); newIndex = parent.getIndex(lastItem);
}
/* Let the treemodel know. */ /* Let the treemodel know. */
treeModel.insertNodeInto(createNewNode("Inserted " + treeModel.insertNodeInto(createNewNode("Inserted " + Integer.
Integer.toString(insertCount++)), toString(insertCount++)),
parent, newIndex); parent, newIndex);
} }
} }
} // End of SampleTree.InsertAction } // End of SampleTree.InsertAction
/** /**
* ReloadAction is used to reload from the selected node. If nothing * ReloadAction is used to reload from the selected node. If nothing
* is selected, reload is not issued. * is selected, reload is not issued.
*/ */
class ReloadAction extends Object implements ActionListener class ReloadAction extends Object implements ActionListener {
{
/** /**
* Messaged when the user clicks on the Reload menu item. * Messaged when the user clicks on the Reload menu item.
* Determines the selection from the Tree and asks the treemodel * Determines the selection from the Tree and asks the treemodel
* to reload from that node. * to reload from that node.
*/ */
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
DefaultMutableTreeNode lastItem = getSelectedNode(); DefaultMutableTreeNode lastItem = getSelectedNode();
if(lastItem != null) if (lastItem != null) {
treeModel.reload(lastItem); treeModel.reload(lastItem);
}
} }
} // End of SampleTree.ReloadAction } // End of SampleTree.ReloadAction
/** /**
* RemoveAction removes the selected node from the tree. If * RemoveAction removes the selected node from the tree. If
* The root or nothing is selected nothing is removed. * The root or nothing is selected nothing is removed.
*/ */
class RemoveAction extends Object implements ActionListener class RemoveAction extends Object implements ActionListener {
{
/** /**
* Removes the selected item as long as it isn't root. * Removes the selected item as long as it isn't root.
*/ */
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
TreePath[] selected = getSelectedPaths(); TreePath[] selected = getSelectedPaths();
...@@ -451,19 +471,17 @@ public class SampleTree ...@@ -451,19 +471,17 @@ public class SampleTree
paths[counter] = null; paths[counter] = null;
} }
treeModel.setRoot(null); treeModel.setRoot(null);
} } else {
else {
// Find the siblings of path. // Find the siblings of path.
TreePath parent = path.getParentPath(); TreePath parent = path.getParentPath();
MutableTreeNode parentNode = (MutableTreeNode)parent. MutableTreeNode parentNode = (MutableTreeNode) parent.
getLastPathComponent(); getLastPathComponent();
ArrayList toRemove = new ArrayList(); ArrayList<TreePath> toRemove = new ArrayList<TreePath>();
int depth = parent.getPathCount();
// First pass, find paths with a parent TreePath of parent // First pass, find paths with a parent TreePath of parent
for (int counter = paths.length - 1; counter >= 0; counter--) { for (int counter = paths.length - 1; counter >= 0; counter--) {
if (paths[counter] != null && paths[counter]. if (paths[counter] != null && paths[counter].getParentPath().
getParentPath().equals(parent)) { equals(parent)) {
toRemove.add(paths[counter]); toRemove.add(paths[counter]);
paths[counter] = null; paths[counter] = null;
} }
...@@ -477,9 +495,9 @@ public class SampleTree ...@@ -477,9 +495,9 @@ public class SampleTree
for (int counter = paths.length - 1; counter >= 0; counter--) { for (int counter = paths.length - 1; counter >= 0; counter--) {
if (paths[counter] != null) { if (paths[counter] != null) {
for (int rCounter = rCount - 1; rCounter >= 0; for (int rCounter = rCount - 1; rCounter >= 0;
rCounter--) { rCounter--) {
if (((TreePath)toRemove.get(rCounter)). if ((toRemove.get(rCounter)).isDescendant(
isDescendant(paths[counter])) { paths[counter])) {
paths[counter] = null; paths[counter] = null;
} }
} }
...@@ -493,10 +511,10 @@ public class SampleTree ...@@ -493,10 +511,10 @@ public class SampleTree
int[] indices = new int[rCount]; int[] indices = new int[rCount];
Object[] removedNodes = new Object[rCount]; Object[] removedNodes = new Object[rCount];
for (int counter = rCount - 1; counter >= 0; counter--) { for (int counter = rCount - 1; counter >= 0; counter--) {
removedNodes[counter] = ((TreePath)toRemove.get(counter)). removedNodes[counter] = (toRemove.get(counter)).
getLastPathComponent(); getLastPathComponent();
indices[counter] = treeModel.getIndexOfChild indices[counter] = treeModel.getIndexOfChild(parentNode,
(parentNode, removedNodes[counter]); removedNodes[counter]);
parentNode.remove(indices[counter]); parentNode.remove(indices[counter]);
} }
treeModel.nodesWereRemoved(parentNode, indices, removedNodes); treeModel.nodesWereRemoved(parentNode, indices, removedNodes);
...@@ -522,8 +540,7 @@ public class SampleTree ...@@ -522,8 +540,7 @@ public class SampleTree
return shallowestPath; return shallowestPath;
} }
} }
} } else {
else {
shallowestPath = paths[counter]; shallowestPath = paths[counter];
shallowest = paths[counter].getPathCount(); shallowest = paths[counter].getPathCount();
} }
...@@ -540,67 +557,70 @@ public class SampleTree ...@@ -540,67 +557,70 @@ public class SampleTree
* This is actually rather expensive, it would be more efficient * This is actually rather expensive, it would be more efficient
* to extract the indices and then do the comparision. * to extract the indices and then do the comparision.
*/ */
private class PositionComparator implements Comparator { private class PositionComparator implements Comparator<TreePath> {
public int compare(Object o1, Object o2) {
TreePath p1 = (TreePath)o1; public int compare(TreePath p1, TreePath p2) {
int o1Index = treeModel.getIndexOfChild(p1.getParentPath(). int p1Index = treeModel.getIndexOfChild(p1.getParentPath().
getLastPathComponent(), p1.getLastPathComponent()); getLastPathComponent(), p1.getLastPathComponent());
TreePath p2 = (TreePath)o2; int p2Index = treeModel.getIndexOfChild(p2.getParentPath().
int o2Index = treeModel.getIndexOfChild(p2.getParentPath(). getLastPathComponent(), p2.getLastPathComponent());
getLastPathComponent(), p2.getLastPathComponent()); return p1Index - p2Index;
return o1Index - o2Index;
}
public boolean equals(Object obj) {
return super.equals(obj);
} }
} }
} // End of SampleTree.RemoveAction } // End of SampleTree.RemoveAction
/** /**
* ShowHandlesChangeListener implements the ChangeListener interface * ShowHandlesChangeListener implements the ChangeListener interface
* to toggle the state of showing the handles in the tree. * to toggle the state of showing the handles in the tree.
*/ */
class ShowHandlesChangeListener extends Object implements ChangeListener class ShowHandlesChangeListener extends Object implements ChangeListener {
{
public void stateChanged(ChangeEvent e) { public void stateChanged(ChangeEvent e) {
tree.setShowsRootHandles(((JCheckBox)e.getSource()).isSelected()); tree.setShowsRootHandles(((JCheckBox) e.getSource()).isSelected());
} }
} // End of class SampleTree.ShowHandlesChangeListener } // End of class SampleTree.ShowHandlesChangeListener
/** /**
* ShowRootChangeListener implements the ChangeListener interface * ShowRootChangeListener implements the ChangeListener interface
* to toggle the state of showing the root node in the tree. * to toggle the state of showing the root node in the tree.
*/ */
class ShowRootChangeListener extends Object implements ChangeListener class ShowRootChangeListener extends Object implements ChangeListener {
{
public void stateChanged(ChangeEvent e) { public void stateChanged(ChangeEvent e) {
tree.setRootVisible(((JCheckBox)e.getSource()).isSelected()); tree.setRootVisible(((JCheckBox) e.getSource()).isSelected());
} }
} // End of class SampleTree.ShowRootChangeListener } // End of class SampleTree.ShowRootChangeListener
/** /**
* TreeEditableChangeListener implements the ChangeListener interface * TreeEditableChangeListener implements the ChangeListener interface
* to toggle between allowing editing and now allowing editing in * to toggle between allowing editing and now allowing editing in
* the tree. * the tree.
*/ */
class TreeEditableChangeListener extends Object implements ChangeListener class TreeEditableChangeListener extends Object implements ChangeListener {
{
public void stateChanged(ChangeEvent e) { public void stateChanged(ChangeEvent e) {
tree.setEditable(((JCheckBox)e.getSource()).isSelected()); tree.setEditable(((JCheckBox) e.getSource()).isSelected());
} }
} // End of class SampleTree.TreeEditableChangeListener } // End of class SampleTree.TreeEditableChangeListener
public static void main(String args[]) {
try {
SwingUtilities.invokeAndWait(new Runnable() {
static public void main(String args[]) { @SuppressWarnings(value = "ResultOfObjectAllocationIgnored")
new SampleTree(); public void run() {
new SampleTree();
}
});
} catch (InterruptedException ex) {
Logger.getLogger(SampleTree.class.getName()).log(Level.SEVERE, null,
ex);
} catch (InvocationTargetException ex) {
Logger.getLogger(SampleTree.class.getName()).log(Level.SEVERE, null,
ex);
}
} }
} }
/* /*
* Copyright (c) 1997, 2005, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
...@@ -29,8 +29,6 @@ ...@@ -29,8 +29,6 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
/*
*/
import javax.swing.Icon; import javax.swing.Icon;
import javax.swing.ImageIcon; import javax.swing.ImageIcon;
...@@ -42,48 +40,56 @@ import java.awt.Component; ...@@ -42,48 +40,56 @@ import java.awt.Component;
import java.awt.Color; import java.awt.Color;
import java.awt.Font; import java.awt.Font;
import java.awt.Graphics; import java.awt.Graphics;
import javax.swing.UIManager;
@SuppressWarnings("serial")
public class SampleTreeCellRenderer extends JLabel implements TreeCellRenderer {
public class SampleTreeCellRenderer extends JLabel implements TreeCellRenderer
{
/** Font used if the string to be displayed isn't a font. */ /** Font used if the string to be displayed isn't a font. */
static protected Font defaultFont; protected static Font defaultFont;
/** Icon to use when the item is collapsed. */ /** Icon to use when the item is collapsed. */
static protected ImageIcon collapsedIcon; protected static ImageIcon collapsedIcon;
/** Icon to use when the item is expanded. */ /** Icon to use when the item is expanded. */
static protected ImageIcon expandedIcon; protected static ImageIcon expandedIcon;
/** Color to use for the background when selected. */ /** Color to use for the background when selected. */
static protected final Color SelectedBackgroundColor = Color.yellow;//new Color(0, 0, 128); protected static final Color SELECTED_BACKGROUND_COLOR;
static static {
{ if ("Nimbus".equals(UIManager.getLookAndFeel().getName())) {
SELECTED_BACKGROUND_COLOR = new Color(0, 0,
0, 0);
} else {
SELECTED_BACKGROUND_COLOR = Color.YELLOW;
}
try { try {
defaultFont = new Font("SansSerif", 0, 12); defaultFont = new Font("SansSerif", 0, 12);
} catch (Exception e) {} } catch (Exception e) {
}
try { try {
collapsedIcon = new ImageIcon(SampleTreeCellRenderer.class.getResource("/resources/images/collapsed.gif")); collapsedIcon = new ImageIcon(SampleTreeCellRenderer.class.
expandedIcon = new ImageIcon(SampleTreeCellRenderer.class.getResource("/resources/images/expanded.gif")); getResource("/resources/images/collapsed.gif"));
expandedIcon = new ImageIcon(SampleTreeCellRenderer.class.
getResource("/resources/images/expanded.gif"));
} catch (Exception e) { } catch (Exception e) {
System.out.println("Couldn't load images: " + e); System.out.println("Couldn't load images: " + e);
} }
} }
/** Whether or not the item that was last configured is selected. */ /** Whether or not the item that was last configured is selected. */
protected boolean selected; protected boolean selected;
/** /**
* This is messaged from JTree whenever it needs to get the size * This is messaged from JTree whenever it needs to get the size
* of the component or it wants to draw it. * of the component or it wants to draw it.
* This attempts to set the font based on value, which will be * This attempts to set the font based on value, which will be
* a TreeNode. * a TreeNode.
*/ */
public Component getTreeCellRendererComponent(JTree tree, Object value, public Component getTreeCellRendererComponent(JTree tree, Object value,
boolean selected, boolean expanded, boolean selected, boolean expanded,
boolean leaf, int row, boolean leaf, int row,
boolean hasFocus) { boolean hasFocus) {
Font font; String stringValue = tree.convertValueToText(value, selected,
String stringValue = tree.convertValueToText(value, selected, expanded, leaf, row, hasFocus);
expanded, leaf, row, hasFocus);
/* Set the text. */ /* Set the text. */
setText(stringValue); setText(stringValue);
...@@ -91,24 +97,27 @@ public class SampleTreeCellRenderer extends JLabel implements TreeCellRenderer ...@@ -91,24 +97,27 @@ public class SampleTreeCellRenderer extends JLabel implements TreeCellRenderer
setToolTipText(stringValue); setToolTipText(stringValue);
/* Set the image. */ /* Set the image. */
if(expanded) if (expanded) {
setIcon(expandedIcon); setIcon(expandedIcon);
else if(!leaf) } else if (!leaf) {
setIcon(collapsedIcon); setIcon(collapsedIcon);
else } else {
setIcon(null); setIcon(null);
}
/* Set the color and the font based on the SampleData userObject. */ /* Set the color and the font based on the SampleData userObject. */
SampleData userObject = (SampleData)((DefaultMutableTreeNode)value) SampleData userObject = (SampleData) ((DefaultMutableTreeNode) value).
.getUserObject(); getUserObject();
if(hasFocus) if (hasFocus) {
setForeground(Color.cyan); setForeground(UIManager.getColor("Tree.selectionForeground"));
else } else {
setForeground(userObject.getColor()); setForeground(userObject.getColor());
if(userObject.getFont() == null) }
if (userObject.getFont() == null) {
setFont(defaultFont); setFont(defaultFont);
else } else {
setFont(userObject.getFont()); setFont(userObject.getFont());
}
/* Update the selected flag for the next paint. */ /* Update the selected flag for the next paint. */
this.selected = selected; this.selected = selected;
...@@ -117,36 +126,36 @@ public class SampleTreeCellRenderer extends JLabel implements TreeCellRenderer ...@@ -117,36 +126,36 @@ public class SampleTreeCellRenderer extends JLabel implements TreeCellRenderer
} }
/** /**
* paint is subclassed to draw the background correctly. JLabel * paint is subclassed to draw the background correctly. JLabel
* currently does not allow backgrounds other than white, and it * currently does not allow backgrounds other than white, and it
* will also fill behind the icon. Something that isn't desirable. * will also fill behind the icon. Something that isn't desirable.
*/ */
@Override
public void paint(Graphics g) { public void paint(Graphics g) {
Color bColor; Color bColor;
Icon currentI = getIcon(); Icon currentI = getIcon();
if(selected) if (selected) {
bColor = SelectedBackgroundColor; bColor = SELECTED_BACKGROUND_COLOR;
else if(getParent() != null) } else if (getParent() != null) /* Pick background color up from parent (which will come from
/* Pick background color up from parent (which will come from the JTree we're contained in). */ {
the JTree we're contained in). */
bColor = getParent().getBackground(); bColor = getParent().getBackground();
else } else {
bColor = getBackground(); bColor = getBackground();
}
g.setColor(bColor); g.setColor(bColor);
if(currentI != null && getText() != null) { if (currentI != null && getText() != null) {
int offset = (currentI.getIconWidth() + getIconTextGap()); int offset = (currentI.getIconWidth() + getIconTextGap());
if (getComponentOrientation().isLeftToRight()) { if (getComponentOrientation().isLeftToRight()) {
g.fillRect(offset, 0, getWidth() - 1 - offset, g.fillRect(offset, 0, getWidth() - 1 - offset,
getHeight() - 1); getHeight() - 1);
} } else {
else {
g.fillRect(0, 0, getWidth() - 1 - offset, getHeight() - 1); g.fillRect(0, 0, getWidth() - 1 - offset, getHeight() - 1);
} }
} else {
g.fillRect(0, 0, getWidth() - 1, getHeight() - 1);
} }
else
g.fillRect(0, 0, getWidth()-1, getHeight()-1);
super.paint(g); super.paint(g);
} }
} }
/* /*
* Copyright (c) 1997, 1998, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
...@@ -29,8 +29,6 @@ ...@@ -29,8 +29,6 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
/*
*/
import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeNode; import javax.swing.tree.TreeNode;
...@@ -38,40 +36,43 @@ import javax.swing.tree.TreePath; ...@@ -38,40 +36,43 @@ import javax.swing.tree.TreePath;
import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultMutableTreeNode;
import java.awt.Color; import java.awt.Color;
/** /**
* SampleTreeModel extends JTreeModel to extends valueForPathChanged. * SampleTreeModel extends JTreeModel to extends valueForPathChanged.
* This method is called as a result of the user editing a value in * This method is called as a result of the user editing a value in
* the tree. If you allow editing in your tree, are using TreeNodes * the tree. If you allow editing in your tree, are using TreeNodes
* and the user object of the TreeNodes is not a String, then you're going * and the user object of the TreeNodes is not a String, then you're going
* to have to subclass JTreeModel as this example does. * to have to subclass JTreeModel as this example does.
* *
* @author Scott Violet * @author Scott Violet
*/ */
@SuppressWarnings("serial")
public class SampleTreeModel extends DefaultTreeModel {
public class SampleTreeModel extends DefaultTreeModel
{
/** /**
* Creates a new instance of SampleTreeModel with newRoot set * Creates a new instance of SampleTreeModel with newRoot set
* to the root of this model. * to the root of this model.
*/ */
public SampleTreeModel(TreeNode newRoot) { public SampleTreeModel(TreeNode newRoot) {
super(newRoot); super(newRoot);
} }
/** /**
* Subclassed to message setString() to the changed path item. * Subclassed to message setString() to the changed path item.
*/ */
@Override
public void valueForPathChanged(TreePath path, Object newValue) { public void valueForPathChanged(TreePath path, Object newValue) {
/* Update the user object. */ /* Update the user object. */
DefaultMutableTreeNode aNode = (DefaultMutableTreeNode)path.getLastPathComponent(); DefaultMutableTreeNode aNode = (DefaultMutableTreeNode) path.
SampleData sampleData = (SampleData)aNode.getUserObject(); getLastPathComponent();
SampleData sampleData = (SampleData) aNode.getUserObject();
sampleData.setString((String)newValue); sampleData.setString((String) newValue);
/* UUUhhhhh, pretty colors. */ /* UUUhhhhh, pretty colors. */
sampleData.setColor(Color.green); sampleData.setColor(Color.green);
/* Since we've changed how the data is to be displayed, message /* Since we've changed how the data is to be displayed, message
nodeChanged. */ nodeChanged. */
nodeChanged(aNode); nodeChanged(aNode);
} }
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册