提交 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, 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.
先完成此消息的编辑!
想要评论请 注册