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