mirror of
https://github.com/openjdk/jdk.git
synced 2026-06-05 02:02:31 +00:00
7027698: /jfc/SampleTree demo needs to be improved
Reviewed-by: rupashka
This commit is contained in:
parent
466a172faf
commit
a9452d32b7
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
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;
|
||||
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
|
||||
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. */
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* 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
|
||||
{
|
||||
/**
|
||||
* 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();
|
||||
* ReloadAction is used to reload from the selected node. If nothing
|
||||
* is selected, reload is not issued.
|
||||
*/
|
||||
class ReloadAction extends Object implements ActionListener {
|
||||
|
||||
if(lastItem != null)
|
||||
/**
|
||||
* 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();
|
||||
|
||||
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;
|
||||
}
|
||||
private class PositionComparator implements Comparator<TreePath> {
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
return super.equals(obj);
|
||||
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
|
||||
{
|
||||
public void stateChanged(ChangeEvent e) {
|
||||
tree.setShowsRootHandles(((JCheckBox)e.getSource()).isSelected());
|
||||
}
|
||||
* 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());
|
||||
}
|
||||
} // 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
|
||||
{
|
||||
public void stateChanged(ChangeEvent e) {
|
||||
tree.setRootVisible(((JCheckBox)e.getSource()).isSelected());
|
||||
}
|
||||
* 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());
|
||||
}
|
||||
} // 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
|
||||
{
|
||||
public void stateChanged(ChangeEvent e) {
|
||||
tree.setEditable(((JCheckBox)e.getSource()).isSelected());
|
||||
}
|
||||
* 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());
|
||||
}
|
||||
} // 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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
public class SampleTreeModel extends DefaultTreeModel
|
||||
{
|
||||
/**
|
||||
* 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 {
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user