-
Bug
-
Resolution: Fixed
-
P4
-
1.3.0
-
merlin
-
x86
-
linux, windows_98, windows_nt
* Given a source object, creates a root node for the local
* tree model and sets the factory that will to be used to
* create the children. The default implementation creates
* a slow default factory.
*/
protected DefaultMutableTreeNode createRoot(Object source) {
TreeNodeFactory fac = new DefaultTreeNodeFactory();
factory = new SlowTreeNodeFactory(fac, 1000);
return new DefaultMutableTreeNode("Thread Tree", true);
}
// requestHalt()
// Can be called to terminate the internal worker Thread
public void requestHalt() {
noHaltRequested = false; // update the flag
if (backgndThread != null) {
backgndThread.interrupt(); // nudge
internal thread to notice
}
}
// isAlive()
// Can be called to test whether backgnd worker Thread is running (yet
or still)
public boolean isAlive() {
return backgndThread.isAlive();
}
// debug()
// Call to display current status + a text message
public void debug(String message) {
String output;
java.util.Date dateTime = new java.util.Date();
output = dateTime.toString();
output += ": ";
output += Thread.currentThread();
output += ": ";
output += message;
System.out.println(output);
}
/*
* main() for testing
*/
public static void main(String[] args) {
// Set to the platform-native look & feel
try {
UIManager.setLookAndFeel
(UIManager.getSystemLookAndFeelClassName());
} catch (Throwable exception)
{
System.err.println("Exception occurred in main() of
UserPanel");
exception.printStackTrace(System.out);
} // End of catch
// Instantiate our self-running widget
final ThreadTree tt = new ThreadTree() {
// Override of createRoot() to install a slow file
system factory.
protected DefaultMutableTreeNode createRoot(Object
source) {
// String path = "Z:\\";
String path = "E:\\Java\\";
TreeNodeFactory fac = new FileSystemNodeFactory
(path);
tt.factory = new SlowTreeNodeFactory(fac, 2);
// factory = new DefaultTreeNodeFactory();
return new DefaultMutableTreeNode(path, true);
}
};
// Create a screen presence
JFrame f = new JFrame("ThreadTree Demo");
// Handle killing this process if screen presence is dismissed
by user
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent event) {
tt.requestHalt();
System.exit(0);
}
});
f.setContentPane(tt.getContentPane());
f.pack();
f.setVisible(true);
}
}
***********************************************************
A brief description of what's been going on here.
***********************************************************
About 15 lines from the end of the code sample above is a reference to
tt.factory. This is the line that produced the compiler errors in the included
compiler output.
This line isn't really supposed to be a reference to tt.factory; it should
instead just be "factory". When it was just "factory", it compiled fine under
1.2.2. But when it was just "factory" it would not compile under and of the
1.3.x compilers. They all state that the non-static variable "factory" cannot
be referenced in a static context.
Note that this is not really a static context. This is an override of a method
during instantiation of the object. "factory" is a data member of ThreadTree,
so the "factory" reference is to the data member of the instance.
So, my code is not syntactically correct. Thus, I really have 2 problems. The
first is that I cannot do what I want to do under 1.3.x, because I get this
apparently inaccurate compiler error. The second problem is that I blew off
your -javac- application while searching for a work-around to my original
problem.
If you have trouble figuring this thing out from the amount of context that I
was able to provide with this error report, please do not hesitate to contact
me.
Thanks.
(Review ID: 104472)
======================================================================
Name: ks88420 Date: 08/25/2000
java version "1.3.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0-C)
Java HotSpot(TM) Client VM (build 1.3.0-C mixed mode)
Compiling error.
Source code:
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.plaf.basic.*;
import java.awt.*;
import java.awt.event.*;
public class c03_04 extends JApplet {
private String s = new String();
public void init() {
Container contentPane = getContentPane();
JButton button = new JButton(new ImageIcon("punch.gif"));
button.setUI(new PopOutButtonUI());
contentPane.setLayout(new FlowLayout());
contentPane.add(button);
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
showStatus(s += '+');
}
});
}
}
class PopOutButtonUI extends BasicButtonUI {
public void installUI(JComponent c) {
AbstractButton button = (AbstractButton)c;
Border border = button.getBorder();
ImageIcon icon = (ImageIcon)button.getIcon();
int iconW = icon.getIconWidth();
int iconH = icon.getIconHeight();
Image scaled = icon.getImage().getScaledInstance(
iconW + (iconW/3),
iconH + (iconH/3),
Image.SCALE_SMOOTH);
c.putClientProperty("oldBorder", border);
c.setBorder(null);
button.setRolloverIcon(new ImageIcon(scaled));
installListeners(button);
}
public void uninstallUI(JComponent c) {
Border border = (Border)c.getClientProperty("oldBorder");
c.putClientProperty("oldBorder", null);
c.setBorder(border);
uninstallListeners((AbstractButton)c);
}
public Dimension getPreferredSize(JComponent c) {
Dimension ps = super.getPreferredSize(c);
ps.width += ps.width/3;
ps.height += ps.height/3;
return ps;
}
public boolean contains(JComponent c, int x, int y) {
AbstractButton button = (AbstractButton)c;
ButtonModel model = button.getModel();
Icon icon = getIcon(button, model);
Rectangle iconBounds = new Rectangle(
0,0,icon.getIconWidth(),icon.getIconHeight());
return iconBounds.contains(x,y);
}
public void paint(Graphics g, JComponent c) {
AbstractButton button = (AbstractButton)c;
ButtonModel model = button.getModel();
Icon icon = getIcon(button, model);
Insets insets = c.getInsets();
icon.paintIcon(c,g,insets.left,insets.top);
}
private Icon getIcon(AbstractButton b, ButtonModel m) {
return (m.isRollover() && ! m.isPressed()) ?
b.getRolloverIcon() : b.getIcon();
}
}
--------------------------- Compiler Output ---------------------------
An exception has occurred in the compiler (1.3.0). Please file a bug at
the Java Developer Connection (http://java.sun.com/cgi-bin/bugreport.cgi).
Include your program and the following diagnostic in your report. Thank you.
java.lang.InternalError: assertion failed
at com.sun.tools.javac.v8.util.Util.assert(Util.java:25)
at com.sun.tools.javac.v8.code.Code.emitop(Code.java:365)
at com.sun.tools.javac.v8.comp.Items$MemberItem.invoke(Items.java:507)
at com.sun.tools.javac.v8.comp.Gen._case(Gen.java:929)
at com.sun.tools.javac.v8.tree.Tree$Apply.visit(Tree.java:785)
at com.sun.tools.javac.v8.comp.Gen.genExpr(Gen.java:418)
at com.sun.tools.javac.v8.comp.Gen._case(Gen.java:873)
at com.sun.tools.javac.v8.tree.Tree$Exec.visit(Tree.java:699)
at com.sun.tools.javac.v8.comp.Gen.genDef(Gen.java:375)
at com.sun.tools.javac.v8.comp.Gen.genStat(Gen.java:392)
at com.sun.tools.javac.v8.comp.Gen.genStats(Gen.java:401)
at com.sun.tools.javac.v8.comp.Gen._case(Gen.java:507)
at com.sun.tools.javac.v8.tree.Tree$Block.visit(Tree.java:492)
at com.sun.tools.javac.v8.comp.Gen.genDef(Gen.java:375)
at com.sun.tools.javac.v8.comp.Gen.genStat(Gen.java:392)
at com.sun.tools.javac.v8.comp.Gen.genMethod(Gen.java:477)
at com.sun.tools.javac.v8.comp.Gen._case(Gen.java:452)
at com.sun.tools.javac.v8.tree.Tree$MethodDef.visit(Tree.java:441)
at com.sun.tools.javac.v8.comp.Gen.genDef(Gen.java:375)
at com.sun.tools.javac.v8.comp.Gen.genClass(Gen.java:1366)
at com.sun.tools.javac.v8.JavaCompiler.genCode(JavaCompiler.java:302)
at com.sun.tools.javac.v8.JavaCompiler.compile(JavaCompiler.java:407)
at com.sun.tools.javac.v8.Main.compile(Main.java:247)
at com.sun.tools.javac.Main.main(Main.java:16)
(Review ID: 108944)
======================================================================
Name: skT45625 Date: 09/05/2000
java version "1.3.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0-C)
Java HotSpot(TM) Client VM (build 1.3.0-C, mixed mode)
An exception has occurred in the compiler (1.3.0). Please file a bug at the Java
Developer Connection (http://java.sun.com/cgi-bin/bugreport.cgi). Include your
program and the following diagnostic in your report. Thank you.
java.lang.InternalError: assertion failed
at com.sun.tools.javac.v8.util.Util.assert(Util.java:25)
at com.sun.tools.javac.v8.comp.Items$LocalItem.<init>(Items.java:375)
at com.sun.tools.javac.v8.comp.Items.makeLocalItem(Items.java:97)
at com.sun.tools.javac.v8.comp.Gen._case(Gen.java:1286)
at com.sun.tools.javac.v8.tree.Tree$Ident.visit(Tree.java:983)
at com.sun.tools.javac.v8.comp.Gen.genExpr(Gen.java:418)
at com.sun.tools.javac.v8.comp.Gen.genArgs(Gen.java:440)
at com.sun.tools.javac.v8.comp.Gen._case(Gen.java:928)
at com.sun.tools.javac.v8.tree.Tree$Apply.visit(Tree.java:785)
at com.sun.tools.javac.v8.comp.Gen.genExpr(Gen.java:418)
at com.sun.tools.javac.v8.comp.Gen._case(Gen.java:873)
at com.sun.tools.javac.v8.tree.Tree$Exec.visit(Tree.java:699)
at com.sun.tools.javac.v8.comp.Gen.genDef(Gen.java:375)
at com.sun.tools.javac.v8.comp.Gen.genStat(Gen.java:392)
at com.sun.tools.javac.v8.comp.Gen.genStats(Gen.java:401)
at com.sun.tools.javac.v8.comp.Gen._case(Gen.java:507)
at com.sun.tools.javac.v8.tree.Tree$Block.visit(Tree.java:492)
at com.sun.tools.javac.v8.comp.Gen.genDef(Gen.java:375)
at com.sun.tools.javac.v8.comp.Gen.genStat(Gen.java:392)
at com.sun.tools.javac.v8.comp.Gen.genMethod(Gen.java:477)
at com.sun.tools.javac.v8.comp.Gen._case(Gen.java:452)
at com.sun.tools.javac.v8.tree.Tree$MethodDef.visit(Tree.java:441)
at com.sun.tools.javac.v8.comp.Gen.genDef(Gen.java:375)
at com.sun.tools.javac.v8.comp.Gen.genClass(Gen.java:1366)
at com.sun.tools.javac.v8.JavaCompiler.genCode(JavaCompiler.java:302)
at com.sun.tools.javac.v8.JavaCompiler.compile(JavaCompiler.java:407)
at com.sun.tools.javac.v8.Main.compile(Main.java:247)
at com.sun.tools.javac.Main.main(Main.java:16)
the code looked like this below. Turning on -verbose showed that it died trying
to compile the anonymous class nested within the inner class below.
class X {
public void method() {
class LogListDialog extends ListDialog{
public LogListDialog (
Component owner,
String title,
int rows,
int cols,
ListModel model,
int sMode,
ListSelectionModel sModel,
ObjectActionListener hAction,
Translator ret
) {
super(owner,title,rows,cols,model,sMode,sModel,hAction,ret);
PVButton detailButton = new PVButton("Details", 8,8,8);
ActionListener l = new ActionListener() {
public void actionPerformed(ActionEvent e) {
showDetailBatch(results,selModel);
}
};
detailButton.addActionListener(l);
buttonPane.add(detailButton);
buttonPane.add(StrutFactory.hglue(2));
pack();
}
}
}
}
(Review ID: 109282)
======================================================================
Name: krC82822 Date: 11/23/2000
java version "1.3.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0)
Java HotSpot(TM) Server VM (build 1.3.0, mixed mode)
This is the message i get from the VM
#
# HotSpot Virtual Machine Error, Internal Error
# Please report this error at
# http://java.sun.com/cgi-bin/bugreport.cgi
#
# Error ID: 53484152454432554E54494D450E4350500146
#
# Problematic Thread: prio=1 tid=0x80a1bd0 nid=0x228f suspended
#
The error occurs when a J2EE server (Orion http://www.orionserver.com) is under
heavy load. So it's very hard for me to know what code is causing the error.
I thought that mayby the Error ID might help, otherwise you can throw away the
bug report.
Pleas feel free to contact me about any more questions about the error.
(Review ID: 112755)
======================================================================
Name: rlT66838 Date: 05/04/2000
java version "1.3.0rc3"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0rc3-Z)
Java HotSpot(TM) Client VM (build 1.3.0rc3-Z, mixed mode)
***********************************************************
Here's the compiler output
***********************************************************
--------------------------- Compiler Output ---------------------------
ThreadTree.java:417: variable tt might not have been initialized
tt.factory = new SlowTreeNodeFactory(fac, 2);
^
ThreadTree.java:417: variable fac might not have been initialized
tt.factory = new SlowTreeNodeFactory(fac, 2);
^
An exception has occurred in the compiler (1.3.0rc3). Please file a bug at the
Java Developer Connection (http://java.sun.com/cgi-bin/bugreport.cgi). Include
your program and the following diagnostic in your report. Thank you.
java.lang.InternalError: assertion failed
at com.sun.tools.javac.v8.util.Util.assert(Util.java:25)
at com.sun.tools.javac.v8.util.Bits.incl(Bits.java:65)
at com.sun.tools.javac.v8.comp.Flow.checkInit(Flow.java:184)
at com.sun.tools.javac.v8.comp.Flow._case(Flow.java:843)
at com.sun.tools.javac.v8.tree.Tree$Ident.visit(Tree.java:983)
at com.sun.tools.javac.v8.comp.Flow.analyze(Flow.java:321)
at com.sun.tools.javac.v8.comp.Flow.analyzeExpr(Flow.java:339)
at com.sun.tools.javac.v8.comp.Flow.analyzeExprs(Flow.java:404)
at com.sun.tools.javac.v8.comp.Flow._case(Flow.java:753)
at com.sun.tools.javac.v8.tree.Tree$NewClass.visit(Tree.java:810)
at com.sun.tools.javac.v8.comp.Flow.analyze(Flow.java:321)
at com.sun.tools.javac.v8.comp.Flow.analyzeExpr(Flow.java:339)
at com.sun.tools.javac.v8.comp.Flow._case(Flow.java:766)
at com.sun.tools.javac.v8.tree.Tree$Assign.visit(Tree.java:848)
at com.sun.tools.javac.v8.comp.Flow.analyze(Flow.java:321)
at com.sun.tools.javac.v8.comp.Flow.analyzeExpr(Flow.java:339)
at com.sun.tools.javac.v8.comp.Flow._case(Flow.java:719)
at com.sun.tools.javac.v8.tree.Tree$Exec.visit(Tree.java:699)
at com.sun.tools.javac.v8.comp.Flow.analyze(Flow.java:321)
at com.sun.tools.javac.v8.comp.Flow.analyzeStat(Flow.java:394)
at com.sun.tools.javac.v8.comp.Flow.analyzeStats(Flow.java:413)
at com.sun.tools.javac.v8.comp.Flow._case(Flow.java:520)
at com.sun.tools.javac.v8.tree.Tree$Block.visit(Tree.java:492)
at com.sun.tools.javac.v8.comp.Flow.analyze(Flow.java:321)
at com.sun.tools.javac.v8.comp.Flow.analyzeStat(Flow.java:394)
at com.sun.tools.javac.v8.comp.Flow._case(Flow.java:488)
at com.sun.tools.javac.v8.tree.Tree$MethodDef.visit(Tree.java:441)
at com.sun.tools.javac.v8.comp.Flow.analyze(Flow.java:321)
at com.sun.tools.javac.v8.comp.Flow.analyzeDef(Flow.java:379)
at com.sun.tools.javac.v8.comp.Flow._case(Flow.java:456)
at com.sun.tools.javac.v8.tree.Tree$ClassDef.visit(Tree.java:402)
at com.sun.tools.javac.v8.comp.Flow.analyze(Flow.java:321)
at com.sun.tools.javac.v8.comp.Flow.analyzeDef(Flow.java:379)
at com.sun.tools.javac.v8.comp.Flow._case(Flow.java:756)
at com.sun.tools.javac.v8.tree.Tree$NewClass.visit(Tree.java:810)
at com.sun.tools.javac.v8.comp.Flow.analyze(Flow.java:321)
at com.sun.tools.javac.v8.comp.Flow.analyzeExpr(Flow.java:339)
at com.sun.tools.javac.v8.comp.Flow._case(Flow.java:507)
at com.sun.tools.javac.v8.tree.Tree$VarDef.visit(Tree.java:470)
at com.sun.tools.javac.v8.comp.Flow.analyze(Flow.java:321)
at com.sun.tools.javac.v8.comp.Flow.analyzeStat(Flow.java:394)
at com.sun.tools.javac.v8.comp.Flow.analyzeStats(Flow.java:413)
at com.sun.tools.javac.v8.comp.Flow._case(Flow.java:520)
at com.sun.tools.javac.v8.tree.Tree$Block.visit(Tree.java:492)
at com.sun.tools.javac.v8.comp.Flow.analyze(Flow.java:321)
at com.sun.tools.javac.v8.comp.Flow.analyzeStat(Flow.java:394)
at com.sun.tools.javac.v8.comp.Flow._case(Flow.java:488)
at com.sun.tools.javac.v8.tree.Tree$MethodDef.visit(Tree.java:441)
at com.sun.tools.javac.v8.comp.Flow.analyze(Flow.java:321)
at com.sun.tools.javac.v8.comp.Flow.analyzeDef(Flow.java:379)
at com.sun.tools.javac.v8.comp.Flow._case(Flow.java:456)
at com.sun.tools.javac.v8.tree.Tree$ClassDef.visit(Tree.java:402)
at com.sun.tools.javac.v8.comp.Flow.analyze(Flow.java:321)
at com.sun.tools.javac.v8.comp.Flow.analyzeDef(Flow.java:379)
at com.sun.tools.javac.v8.JavaCompiler.compile(JavaCompiler.java:380)
at com.sun.tools.javac.v8.Main.compile(Main.java:247)
at com.sun.tools.javac.Main.main(Main.java:16)
***********************************************************
Here's the primary source file (~400 lines)
***********************************************************
/*
* ThreadTree
*
* Demonstrates use of self-running internal thread to automatically populate
* the tree.
*/
import java.awt.*;
import java.awt.event.*;
import java.text.*;
import java.lang.reflect.*;
import javax.swing.*;
import javax.swing.tree.*;
import java.lang.reflect.InvocationTargetException;
public class ThreadTree extends JApplet {
// Declare our components
private javax.swing.JScrollPane jScrollPane;
private javax.swing.JPanel jPanel;
private javax.swing.JTree jTree;
private javax.swing.JLabel
jlblStatus;
private Blip
blip;
/** Creates children for expanded nodes. */
private transient TreeNodeFactory factory;
/** Root node of our tree */
private transient DefaultMutableTreeNode rootNode;
/** 2 worker threads; 1 for backgnd populating, the other for demand
populating */
private transient Thread
backgndThread;
private transient SwingWorker demandThread;
/** flag // request made to halt backgnd thread */
private volatile boolean
noHaltRequested;
/**
* ThreadTree() constructor
* Initializes the form and sets a default source.
*/
public ThreadTree() {
initComponents();
setSource(null);
launchPopulator();
}
/* Methods */
/**
* initComponents()
* All component-related initializations
*/
public void initComponents() {
// Since we extent JApplet, we already have a content pane; set
its Layout
getContentPane().setLayout(new java.awt.BorderLayout());
// Add the scroll pane
jScrollPane = new javax.swing.JScrollPane();
jScrollPane.setPreferredSize(new java.awt.Dimension(320, 240));
// Add the internal tree itself, and set up its required methods
jTree = new javax.swing.JTree();
jTree.addTreeExpansionListener(new
javax.swing.event.TreeExpansionListener() {
public void treeCollapsed
(javax.swing.event.TreeExpansionEvent evt) {
jTreeTreeCollapsed(evt);
}
public void treeExpanded
(javax.swing.event.TreeExpansionEvent evt) {
jTreeTreeExpanded(evt);
}
});
jTree.addTreeSelectionListener(new
javax.swing.event.TreeSelectionListener() {
public void valueChanged
(javax.swing.event.TreeSelectionEvent evt) {
jTreeValueChanged(evt);
}
});
// ... add the tree to the scroll pane
jScrollPane.add(jTree);
jScrollPane.setViewportView(jTree);
getContentPane().add(jScrollPane, "Center");
// Create the panel that holds the status label & the activity indicator
jPanel = new javax.swing.JPanel();
jPanel.setLayout(new java.awt.BorderLayout());
// Add the status label
jlblStatus = new javax.swing.JLabel();
jlblStatus.setToolTipText("Status");
jlblStatus.setBorder(new javax.swing.border.CompoundBorder(
new javax.swing.border.CompoundBorder(
new javax.swing.border.EmptyBorder(new
java.awt.Insets(1, 1, 1, 1)),
new javax.swing.border.LineBorder
(java.awt.Color.gray)),
new javax.swing.border.EmptyBorder(new
java.awt.Insets(0, 2, 0, 0))));
jlblStatus.setText("Idle");
jPanel.add(jlblStatus, "Center");
// Add the activity indicator
blip = new Blip();
blip.setToolTipText("Activity Indicator");
blip.setPreferredSize(new java.awt.Dimension(23, 23));
blip.setOpaque(true);
blip.setBorder(new javax.swing.border.CompoundBorder(
new javax.swing.border.CompoundBorder(
new javax.swing.border.EmptyBorder(new
java.awt.Insets(1, 1, 1, 1)),
new javax.swing.border.LineBorder
(java.awt.Color.gray)),
new javax.swing.border.EmptyBorder(new
java.awt.Insets(1, 1, 1, 1))));
blip.setForeground(new java.awt.Color(153, 153, 204));
jPanel.add(blip, "East");
getContentPane().add(jPanel, "South");
}
/**
* launchPopulator()
* Create the internal Runnable for our backgnd populator Thread
*/
public void launchPopulator() {
noHaltRequested = true;
Runnable r = new Runnable() {
public void run() {
try {
// Simply invoke runWork()
runWork();
} catch (Exception x) {
// ... and catch any Exceptions that
occur
x.printStackTrace();
}
}
};
// Launch the backgnd worker Thread
backgndThread = new Thread(r, "Backgnd Populator");
// ... daemonize this Thread so it auto-terminates if it is the
last thread running
backgndThread.setDaemon(true);
// ... and knock down its priority by a single tick
// backgndThread.setPriority(backgndThread.getPriority()-1);
backgndThread.start();
debug("Just started backgndThread"); /// dga ///
}
/**
* jTreeTreeExpanded()
* Called when a node is expanded. Stops the active demandThread, if
any,
* and starts a new demandThread to create children for the expanded
node.
*/
private void jTreeTreeExpanded(javax.swing.event.TreeExpansionEvent
evt) {
stopWorker();
DefaultMutableTreeNode node =
(DefaultMutableTreeNode) evt.getPath
().getLastPathComponent();
if (node.getChildCount() <= 0) { // not yet
populated
if (factory != null) {
startWorker(factory, node);
} else {
jlblStatus.setText("Internal error");
}
} else {
jlblStatus.setText("Expanded "+node);
}
}
/**
* jTreeTreeCollapsed()
* Called when a node is collapsed. Stops the active demandThread, if
any,
* and removes all the children.
*/
private void jTreeTreeCollapsed(javax.swing.event.TreeExpansionEvent
evt) {
stopWorker();
DefaultMutableTreeNode node =
(DefaultMutableTreeNode) evt.getPath
().getLastPathComponent();
jlblStatus.setText("Collapsed "+node);
}
/*
* jTreeValueChanged()
* Updates the status line when a node is selected.
*/
private void jTreeValueChanged(javax.swing.event.TreeSelectionEvent
evt) {
Object node = evt.getPath().getLastPathComponent();
String s = evt.isAddedPath() ? "Selected "+node : "";
jlblStatus.setText(s);
}
/**
* startWorker()
* Given a node factory and an expanded node, starts a SwingWorker
* to create children for the expanded node and insert them into
* the tree.
*/
protected void startWorker(final TreeNodeFactory fac,
final
DefaultMutableTreeNode node) {
final Object userObject = node.getUserObject();
demandThread = new SwingWorker() {
/* public long getTimeout() { return 2500; } */
public Object construct() {
/* Create children for the expanded node. */
try {
return fac.createChildren(userObject);
} catch (Exception x) {
return null;
} /// dga /// for now, don't handle
exceptions
}
public void finished() {
/* Set the demandThread to null and stop the
animation,
but only if we are the active
demandThread. */
if (demandThread == this) {
demandThread = null;
blip.stop();
}
/* Get the children created by the factory and
insert them into the local tree model.
*/
DefaultMutableTreeNode[] children =
(DefaultMutableTreeNode[]) get();
for (int i = 0; i < children.length; i++) {
node.insert(children[i], i);
}
DefaultTreeModel model =
(DefaultTreeModel) jTree.getModel();
model.nodeStructureChanged(node);
jlblStatus.setText("Expanded "+node);
}
};
/* Update status line and start animation. */
jlblStatus.setText("Expanding "+node+"...");
blip.start();
}
/** Stops the active worker, if any. */
protected void stopWorker() {
if (demandThread != null) {
demandThread.interrupt();
// worker set to null in finished
}
}
/*
* setSource()
* Initializes the tree model given a source param. Override
* <code>createRoot</code> to create a root node and factory
* appropriate for the source.
*/
public void setSource(Object source) {
requestHalt();
// DefaultMutableTreeNode root = createRoot(source);
rootNode = createRoot(source);
if (rootNode == null) {
debug("rootNode null in setSource()");
}
DefaultTreeModel model = (DefaultTreeModel) jTree.getModel();
// model.setRoot(root);
model.setRoot(rootNode);
model.setAsksAllowsChildren(true);
}
/**
* runWork()
* This is the work done by the backgnd Thread
*/
private void runWork() {
if (rootNode == null) {
debug("rootNode null in runWork()");
}
if (factory == null) {
debug("factory null in runWork()");
}
populateNode(factory,rootNode);
}
/*
* populateNode()
* Add children to any given node, and all of its child nodes
*/
private void populateNode(final TreeNodeFactory fac,
final
DefaultMutableTreeNode node) {
DefaultTreeModel model = (DefaultTreeModel)
jTree.getModel();
int childCount = 0;
if (fac == null) {
debug("null factory in populateNode()");
}
if (node == null) {
debug("null node in populateNode()");
}
childCount = node.getChildCount();
debug("populating node: " + node);
if (childCount <= 0) { // not yet populated
final Object userObject = node.getUserObject();
// Get the children created by the factory and insert
them into the
// local tree model.
try {
DefaultMutableTreeNode[] children =
(DefaultMutableTreeNode[])
fac.createChildren(userObject);
debug("Found " + children.length + " children");
for (int i = 0; i < children.length; i++) {
node.insert(children[i], i);
}
// Update childCount to reflect new number of
children
childCount = node.getChildCount();
// Alert the tree model of the change
model.nodeStructureChanged(node);
} catch (InvocationTargetException ex) {
/* Handle exceptions thrown by the factory
method. */
String msg = "Failed expanding "+node+": ";
Throwable err = ex.getTargetException();
if (err instanceof InterruptedException) {
msg += "interrupted";
} else {
msg += err;
}
jlblStatus.setText(msg);
} catch (InterruptedException ex) {
// unreachable - result is ready
Thread.currentThread().interrupt();
} catch (Exception ex) {
String msg = "Failed expanding "+node+": ";
msg += ex;
jlblStatus.setText(msg);
}
} else {
debug("skipping node " + node + " (" + childCount + "
children)");
}
// Recursively populate all just-returned nodes
for (int i = 0; i < childCount; i++) {
DefaultMutableTreeNode thisChild =
(DefaultMutableTreeNode) model.getChild(node,i);
populateNode(fac,thisChild);
}
debug("Done populating node:" + node + " (" + childCount + "
children)");
}
/**
* createRoot()
* tree model and sets the factory that will to be used to
* create the children. The default implementation creates
* a slow default factory.
*/
protected DefaultMutableTreeNode createRoot(Object source) {
TreeNodeFactory fac = new DefaultTreeNodeFactory();
factory = new SlowTreeNodeFactory(fac, 1000);
return new DefaultMutableTreeNode("Thread Tree", true);
}
// requestHalt()
// Can be called to terminate the internal worker Thread
public void requestHalt() {
noHaltRequested = false; // update the flag
if (backgndThread != null) {
backgndThread.interrupt(); // nudge
internal thread to notice
}
}
// isAlive()
// Can be called to test whether backgnd worker Thread is running (yet
or still)
public boolean isAlive() {
return backgndThread.isAlive();
}
// debug()
// Call to display current status + a text message
public void debug(String message) {
String output;
java.util.Date dateTime = new java.util.Date();
output = dateTime.toString();
output += ": ";
output += Thread.currentThread();
output += ": ";
output += message;
System.out.println(output);
}
/*
* main() for testing
*/
public static void main(String[] args) {
// Set to the platform-native look & feel
try {
UIManager.setLookAndFeel
(UIManager.getSystemLookAndFeelClassName());
} catch (Throwable exception)
{
System.err.println("Exception occurred in main() of
UserPanel");
exception.printStackTrace(System.out);
} // End of catch
// Instantiate our self-running widget
final ThreadTree tt = new ThreadTree() {
// Override of createRoot() to install a slow file
system factory.
protected DefaultMutableTreeNode createRoot(Object
source) {
// String path = "Z:\\";
String path = "E:\\Java\\";
TreeNodeFactory fac = new FileSystemNodeFactory
(path);
tt.factory = new SlowTreeNodeFactory(fac, 2);
// factory = new DefaultTreeNodeFactory();
return new DefaultMutableTreeNode(path, true);
}
};
// Create a screen presence
JFrame f = new JFrame("ThreadTree Demo");
// Handle killing this process if screen presence is dismissed
by user
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent event) {
tt.requestHalt();
System.exit(0);
}
});
f.setContentPane(tt.getContentPane());
f.pack();
f.setVisible(true);
}
}
***********************************************************
A brief description of what's been going on here.
***********************************************************
About 15 lines from the end of the code sample above is a reference to
tt.factory. This is the line that produced the compiler errors in the included
compiler output.
This line isn't really supposed to be a reference to tt.factory; it should
instead just be "factory". When it was just "factory", it compiled fine under
1.2.2. But when it was just "factory" it would not compile under and of the
1.3.x compilers. They all state that the non-static variable "factory" cannot
be referenced in a static context.
Note that this is not really a static context. This is an override of a method
during instantiation of the object. "factory" is a data member of ThreadTree,
so the "factory" reference is to the data member of the instance.
So, my code is not syntactically correct. Thus, I really have 2 problems. The
first is that I cannot do what I want to do under 1.3.x, because I get this
apparently inaccurate compiler error. The second problem is that I blew off
your -javac- application while searching for a work-around to my original
problem.
If you have trouble figuring this thing out from the amount of context that I
was able to provide with this error report, please do not hesitate to contact
me.
Thanks.
(Review ID: 104472)
======================================================================
Name: ks88420 Date: 08/25/2000
java version "1.3.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0-C)
Java HotSpot(TM) Client VM (build 1.3.0-C mixed mode)
Compiling error.
Source code:
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.plaf.basic.*;
import java.awt.*;
import java.awt.event.*;
public class c03_04 extends JApplet {
private String s = new String();
public void init() {
Container contentPane = getContentPane();
JButton button = new JButton(new ImageIcon("punch.gif"));
button.setUI(new PopOutButtonUI());
contentPane.setLayout(new FlowLayout());
contentPane.add(button);
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
showStatus(s += '+');
}
});
}
}
class PopOutButtonUI extends BasicButtonUI {
public void installUI(JComponent c) {
AbstractButton button = (AbstractButton)c;
Border border = button.getBorder();
ImageIcon icon = (ImageIcon)button.getIcon();
int iconW = icon.getIconWidth();
int iconH = icon.getIconHeight();
Image scaled = icon.getImage().getScaledInstance(
iconW + (iconW/3),
iconH + (iconH/3),
Image.SCALE_SMOOTH);
c.putClientProperty("oldBorder", border);
c.setBorder(null);
button.setRolloverIcon(new ImageIcon(scaled));
installListeners(button);
}
public void uninstallUI(JComponent c) {
Border border = (Border)c.getClientProperty("oldBorder");
c.putClientProperty("oldBorder", null);
c.setBorder(border);
uninstallListeners((AbstractButton)c);
}
public Dimension getPreferredSize(JComponent c) {
Dimension ps = super.getPreferredSize(c);
ps.width += ps.width/3;
ps.height += ps.height/3;
return ps;
}
public boolean contains(JComponent c, int x, int y) {
AbstractButton button = (AbstractButton)c;
ButtonModel model = button.getModel();
Icon icon = getIcon(button, model);
Rectangle iconBounds = new Rectangle(
0,0,icon.getIconWidth(),icon.getIconHeight());
return iconBounds.contains(x,y);
}
public void paint(Graphics g, JComponent c) {
AbstractButton button = (AbstractButton)c;
ButtonModel model = button.getModel();
Icon icon = getIcon(button, model);
Insets insets = c.getInsets();
icon.paintIcon(c,g,insets.left,insets.top);
}
private Icon getIcon(AbstractButton b, ButtonModel m) {
return (m.isRollover() && ! m.isPressed()) ?
b.getRolloverIcon() : b.getIcon();
}
}
--------------------------- Compiler Output ---------------------------
An exception has occurred in the compiler (1.3.0). Please file a bug at
the Java Developer Connection (http://java.sun.com/cgi-bin/bugreport.cgi).
Include your program and the following diagnostic in your report. Thank you.
java.lang.InternalError: assertion failed
at com.sun.tools.javac.v8.util.Util.assert(Util.java:25)
at com.sun.tools.javac.v8.code.Code.emitop(Code.java:365)
at com.sun.tools.javac.v8.comp.Items$MemberItem.invoke(Items.java:507)
at com.sun.tools.javac.v8.comp.Gen._case(Gen.java:929)
at com.sun.tools.javac.v8.tree.Tree$Apply.visit(Tree.java:785)
at com.sun.tools.javac.v8.comp.Gen.genExpr(Gen.java:418)
at com.sun.tools.javac.v8.comp.Gen._case(Gen.java:873)
at com.sun.tools.javac.v8.tree.Tree$Exec.visit(Tree.java:699)
at com.sun.tools.javac.v8.comp.Gen.genDef(Gen.java:375)
at com.sun.tools.javac.v8.comp.Gen.genStat(Gen.java:392)
at com.sun.tools.javac.v8.comp.Gen.genStats(Gen.java:401)
at com.sun.tools.javac.v8.comp.Gen._case(Gen.java:507)
at com.sun.tools.javac.v8.tree.Tree$Block.visit(Tree.java:492)
at com.sun.tools.javac.v8.comp.Gen.genDef(Gen.java:375)
at com.sun.tools.javac.v8.comp.Gen.genStat(Gen.java:392)
at com.sun.tools.javac.v8.comp.Gen.genMethod(Gen.java:477)
at com.sun.tools.javac.v8.comp.Gen._case(Gen.java:452)
at com.sun.tools.javac.v8.tree.Tree$MethodDef.visit(Tree.java:441)
at com.sun.tools.javac.v8.comp.Gen.genDef(Gen.java:375)
at com.sun.tools.javac.v8.comp.Gen.genClass(Gen.java:1366)
at com.sun.tools.javac.v8.JavaCompiler.genCode(JavaCompiler.java:302)
at com.sun.tools.javac.v8.JavaCompiler.compile(JavaCompiler.java:407)
at com.sun.tools.javac.v8.Main.compile(Main.java:247)
at com.sun.tools.javac.Main.main(Main.java:16)
(Review ID: 108944)
======================================================================
Name: skT45625 Date: 09/05/2000
java version "1.3.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0-C)
Java HotSpot(TM) Client VM (build 1.3.0-C, mixed mode)
An exception has occurred in the compiler (1.3.0). Please file a bug at the Java
Developer Connection (http://java.sun.com/cgi-bin/bugreport.cgi). Include your
program and the following diagnostic in your report. Thank you.
java.lang.InternalError: assertion failed
at com.sun.tools.javac.v8.util.Util.assert(Util.java:25)
at com.sun.tools.javac.v8.comp.Items$LocalItem.<init>(Items.java:375)
at com.sun.tools.javac.v8.comp.Items.makeLocalItem(Items.java:97)
at com.sun.tools.javac.v8.comp.Gen._case(Gen.java:1286)
at com.sun.tools.javac.v8.tree.Tree$Ident.visit(Tree.java:983)
at com.sun.tools.javac.v8.comp.Gen.genExpr(Gen.java:418)
at com.sun.tools.javac.v8.comp.Gen.genArgs(Gen.java:440)
at com.sun.tools.javac.v8.comp.Gen._case(Gen.java:928)
at com.sun.tools.javac.v8.tree.Tree$Apply.visit(Tree.java:785)
at com.sun.tools.javac.v8.comp.Gen.genExpr(Gen.java:418)
at com.sun.tools.javac.v8.comp.Gen._case(Gen.java:873)
at com.sun.tools.javac.v8.tree.Tree$Exec.visit(Tree.java:699)
at com.sun.tools.javac.v8.comp.Gen.genDef(Gen.java:375)
at com.sun.tools.javac.v8.comp.Gen.genStat(Gen.java:392)
at com.sun.tools.javac.v8.comp.Gen.genStats(Gen.java:401)
at com.sun.tools.javac.v8.comp.Gen._case(Gen.java:507)
at com.sun.tools.javac.v8.tree.Tree$Block.visit(Tree.java:492)
at com.sun.tools.javac.v8.comp.Gen.genDef(Gen.java:375)
at com.sun.tools.javac.v8.comp.Gen.genStat(Gen.java:392)
at com.sun.tools.javac.v8.comp.Gen.genMethod(Gen.java:477)
at com.sun.tools.javac.v8.comp.Gen._case(Gen.java:452)
at com.sun.tools.javac.v8.tree.Tree$MethodDef.visit(Tree.java:441)
at com.sun.tools.javac.v8.comp.Gen.genDef(Gen.java:375)
at com.sun.tools.javac.v8.comp.Gen.genClass(Gen.java:1366)
at com.sun.tools.javac.v8.JavaCompiler.genCode(JavaCompiler.java:302)
at com.sun.tools.javac.v8.JavaCompiler.compile(JavaCompiler.java:407)
at com.sun.tools.javac.v8.Main.compile(Main.java:247)
at com.sun.tools.javac.Main.main(Main.java:16)
the code looked like this below. Turning on -verbose showed that it died trying
to compile the anonymous class nested within the inner class below.
class X {
public void method() {
class LogListDialog extends ListDialog{
public LogListDialog (
Component owner,
String title,
int rows,
int cols,
ListModel model,
int sMode,
ListSelectionModel sModel,
ObjectActionListener hAction,
Translator ret
) {
super(owner,title,rows,cols,model,sMode,sModel,hAction,ret);
PVButton detailButton = new PVButton("Details", 8,8,8);
ActionListener l = new ActionListener() {
public void actionPerformed(ActionEvent e) {
showDetailBatch(results,selModel);
}
};
detailButton.addActionListener(l);
buttonPane.add(detailButton);
buttonPane.add(StrutFactory.hglue(2));
pack();
}
}
}
}
(Review ID: 109282)
======================================================================
Name: krC82822 Date: 11/23/2000
java version "1.3.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0)
Java HotSpot(TM) Server VM (build 1.3.0, mixed mode)
This is the message i get from the VM
#
# HotSpot Virtual Machine Error, Internal Error
# Please report this error at
# http://java.sun.com/cgi-bin/bugreport.cgi
#
# Error ID: 53484152454432554E54494D450E4350500146
#
# Problematic Thread: prio=1 tid=0x80a1bd0 nid=0x228f suspended
#
The error occurs when a J2EE server (Orion http://www.orionserver.com) is under
heavy load. So it's very hard for me to know what code is causing the error.
I thought that mayby the Error ID might help, otherwise you can throw away the
bug report.
Pleas feel free to contact me about any more questions about the error.
(Review ID: 112755)
======================================================================
Name: rlT66838 Date: 05/04/2000
java version "1.3.0rc3"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0rc3-Z)
Java HotSpot(TM) Client VM (build 1.3.0rc3-Z, mixed mode)
***********************************************************
Here's the compiler output
***********************************************************
--------------------------- Compiler Output ---------------------------
ThreadTree.java:417: variable tt might not have been initialized
tt.factory = new SlowTreeNodeFactory(fac, 2);
^
ThreadTree.java:417: variable fac might not have been initialized
tt.factory = new SlowTreeNodeFactory(fac, 2);
^
An exception has occurred in the compiler (1.3.0rc3). Please file a bug at the
Java Developer Connection (http://java.sun.com/cgi-bin/bugreport.cgi). Include
your program and the following diagnostic in your report. Thank you.
java.lang.InternalError: assertion failed
at com.sun.tools.javac.v8.util.Util.assert(Util.java:25)
at com.sun.tools.javac.v8.util.Bits.incl(Bits.java:65)
at com.sun.tools.javac.v8.comp.Flow.checkInit(Flow.java:184)
at com.sun.tools.javac.v8.comp.Flow._case(Flow.java:843)
at com.sun.tools.javac.v8.tree.Tree$Ident.visit(Tree.java:983)
at com.sun.tools.javac.v8.comp.Flow.analyze(Flow.java:321)
at com.sun.tools.javac.v8.comp.Flow.analyzeExpr(Flow.java:339)
at com.sun.tools.javac.v8.comp.Flow.analyzeExprs(Flow.java:404)
at com.sun.tools.javac.v8.comp.Flow._case(Flow.java:753)
at com.sun.tools.javac.v8.tree.Tree$NewClass.visit(Tree.java:810)
at com.sun.tools.javac.v8.comp.Flow.analyze(Flow.java:321)
at com.sun.tools.javac.v8.comp.Flow.analyzeExpr(Flow.java:339)
at com.sun.tools.javac.v8.comp.Flow._case(Flow.java:766)
at com.sun.tools.javac.v8.tree.Tree$Assign.visit(Tree.java:848)
at com.sun.tools.javac.v8.comp.Flow.analyze(Flow.java:321)
at com.sun.tools.javac.v8.comp.Flow.analyzeExpr(Flow.java:339)
at com.sun.tools.javac.v8.comp.Flow._case(Flow.java:719)
at com.sun.tools.javac.v8.tree.Tree$Exec.visit(Tree.java:699)
at com.sun.tools.javac.v8.comp.Flow.analyze(Flow.java:321)
at com.sun.tools.javac.v8.comp.Flow.analyzeStat(Flow.java:394)
at com.sun.tools.javac.v8.comp.Flow.analyzeStats(Flow.java:413)
at com.sun.tools.javac.v8.comp.Flow._case(Flow.java:520)
at com.sun.tools.javac.v8.tree.Tree$Block.visit(Tree.java:492)
at com.sun.tools.javac.v8.comp.Flow.analyze(Flow.java:321)
at com.sun.tools.javac.v8.comp.Flow.analyzeStat(Flow.java:394)
at com.sun.tools.javac.v8.comp.Flow._case(Flow.java:488)
at com.sun.tools.javac.v8.tree.Tree$MethodDef.visit(Tree.java:441)
at com.sun.tools.javac.v8.comp.Flow.analyze(Flow.java:321)
at com.sun.tools.javac.v8.comp.Flow.analyzeDef(Flow.java:379)
at com.sun.tools.javac.v8.comp.Flow._case(Flow.java:456)
at com.sun.tools.javac.v8.tree.Tree$ClassDef.visit(Tree.java:402)
at com.sun.tools.javac.v8.comp.Flow.analyze(Flow.java:321)
at com.sun.tools.javac.v8.comp.Flow.analyzeDef(Flow.java:379)
at com.sun.tools.javac.v8.comp.Flow._case(Flow.java:756)
at com.sun.tools.javac.v8.tree.Tree$NewClass.visit(Tree.java:810)
at com.sun.tools.javac.v8.comp.Flow.analyze(Flow.java:321)
at com.sun.tools.javac.v8.comp.Flow.analyzeExpr(Flow.java:339)
at com.sun.tools.javac.v8.comp.Flow._case(Flow.java:507)
at com.sun.tools.javac.v8.tree.Tree$VarDef.visit(Tree.java:470)
at com.sun.tools.javac.v8.comp.Flow.analyze(Flow.java:321)
at com.sun.tools.javac.v8.comp.Flow.analyzeStat(Flow.java:394)
at com.sun.tools.javac.v8.comp.Flow.analyzeStats(Flow.java:413)
at com.sun.tools.javac.v8.comp.Flow._case(Flow.java:520)
at com.sun.tools.javac.v8.tree.Tree$Block.visit(Tree.java:492)
at com.sun.tools.javac.v8.comp.Flow.analyze(Flow.java:321)
at com.sun.tools.javac.v8.comp.Flow.analyzeStat(Flow.java:394)
at com.sun.tools.javac.v8.comp.Flow._case(Flow.java:488)
at com.sun.tools.javac.v8.tree.Tree$MethodDef.visit(Tree.java:441)
at com.sun.tools.javac.v8.comp.Flow.analyze(Flow.java:321)
at com.sun.tools.javac.v8.comp.Flow.analyzeDef(Flow.java:379)
at com.sun.tools.javac.v8.comp.Flow._case(Flow.java:456)
at com.sun.tools.javac.v8.tree.Tree$ClassDef.visit(Tree.java:402)
at com.sun.tools.javac.v8.comp.Flow.analyze(Flow.java:321)
at com.sun.tools.javac.v8.comp.Flow.analyzeDef(Flow.java:379)
at com.sun.tools.javac.v8.JavaCompiler.compile(JavaCompiler.java:380)
at com.sun.tools.javac.v8.Main.compile(Main.java:247)
at com.sun.tools.javac.Main.main(Main.java:16)
***********************************************************
Here's the primary source file (~400 lines)
***********************************************************
/*
* ThreadTree
*
* Demonstrates use of self-running internal thread to automatically populate
* the tree.
*/
import java.awt.*;
import java.awt.event.*;
import java.text.*;
import java.lang.reflect.*;
import javax.swing.*;
import javax.swing.tree.*;
import java.lang.reflect.InvocationTargetException;
public class ThreadTree extends JApplet {
// Declare our components
private javax.swing.JScrollPane jScrollPane;
private javax.swing.JPanel jPanel;
private javax.swing.JTree jTree;
private javax.swing.JLabel
jlblStatus;
private Blip
blip;
/** Creates children for expanded nodes. */
private transient TreeNodeFactory factory;
/** Root node of our tree */
private transient DefaultMutableTreeNode rootNode;
/** 2 worker threads; 1 for backgnd populating, the other for demand
populating */
private transient Thread
backgndThread;
private transient SwingWorker demandThread;
/** flag // request made to halt backgnd thread */
private volatile boolean
noHaltRequested;
/**
* ThreadTree() constructor
* Initializes the form and sets a default source.
*/
public ThreadTree() {
initComponents();
setSource(null);
launchPopulator();
}
/* Methods */
/**
* initComponents()
* All component-related initializations
*/
public void initComponents() {
// Since we extent JApplet, we already have a content pane; set
its Layout
getContentPane().setLayout(new java.awt.BorderLayout());
// Add the scroll pane
jScrollPane = new javax.swing.JScrollPane();
jScrollPane.setPreferredSize(new java.awt.Dimension(320, 240));
// Add the internal tree itself, and set up its required methods
jTree = new javax.swing.JTree();
jTree.addTreeExpansionListener(new
javax.swing.event.TreeExpansionListener() {
public void treeCollapsed
(javax.swing.event.TreeExpansionEvent evt) {
jTreeTreeCollapsed(evt);
}
public void treeExpanded
(javax.swing.event.TreeExpansionEvent evt) {
jTreeTreeExpanded(evt);
}
});
jTree.addTreeSelectionListener(new
javax.swing.event.TreeSelectionListener() {
public void valueChanged
(javax.swing.event.TreeSelectionEvent evt) {
jTreeValueChanged(evt);
}
});
// ... add the tree to the scroll pane
jScrollPane.add(jTree);
jScrollPane.setViewportView(jTree);
getContentPane().add(jScrollPane, "Center");
// Create the panel that holds the status label & the activity indicator
jPanel = new javax.swing.JPanel();
jPanel.setLayout(new java.awt.BorderLayout());
// Add the status label
jlblStatus = new javax.swing.JLabel();
jlblStatus.setToolTipText("Status");
jlblStatus.setBorder(new javax.swing.border.CompoundBorder(
new javax.swing.border.CompoundBorder(
new javax.swing.border.EmptyBorder(new
java.awt.Insets(1, 1, 1, 1)),
new javax.swing.border.LineBorder
(java.awt.Color.gray)),
new javax.swing.border.EmptyBorder(new
java.awt.Insets(0, 2, 0, 0))));
jlblStatus.setText("Idle");
jPanel.add(jlblStatus, "Center");
// Add the activity indicator
blip = new Blip();
blip.setToolTipText("Activity Indicator");
blip.setPreferredSize(new java.awt.Dimension(23, 23));
blip.setOpaque(true);
blip.setBorder(new javax.swing.border.CompoundBorder(
new javax.swing.border.CompoundBorder(
new javax.swing.border.EmptyBorder(new
java.awt.Insets(1, 1, 1, 1)),
new javax.swing.border.LineBorder
(java.awt.Color.gray)),
new javax.swing.border.EmptyBorder(new
java.awt.Insets(1, 1, 1, 1))));
blip.setForeground(new java.awt.Color(153, 153, 204));
jPanel.add(blip, "East");
getContentPane().add(jPanel, "South");
}
/**
* launchPopulator()
* Create the internal Runnable for our backgnd populator Thread
*/
public void launchPopulator() {
noHaltRequested = true;
Runnable r = new Runnable() {
public void run() {
try {
// Simply invoke runWork()
runWork();
} catch (Exception x) {
// ... and catch any Exceptions that
occur
x.printStackTrace();
}
}
};
// Launch the backgnd worker Thread
backgndThread = new Thread(r, "Backgnd Populator");
// ... daemonize this Thread so it auto-terminates if it is the
last thread running
backgndThread.setDaemon(true);
// ... and knock down its priority by a single tick
// backgndThread.setPriority(backgndThread.getPriority()-1);
backgndThread.start();
debug("Just started backgndThread"); /// dga ///
}
/**
* jTreeTreeExpanded()
* Called when a node is expanded. Stops the active demandThread, if
any,
* and starts a new demandThread to create children for the expanded
node.
*/
private void jTreeTreeExpanded(javax.swing.event.TreeExpansionEvent
evt) {
stopWorker();
DefaultMutableTreeNode node =
(DefaultMutableTreeNode) evt.getPath
().getLastPathComponent();
if (node.getChildCount() <= 0) { // not yet
populated
if (factory != null) {
startWorker(factory, node);
} else {
jlblStatus.setText("Internal error");
}
} else {
jlblStatus.setText("Expanded "+node);
}
}
/**
* jTreeTreeCollapsed()
* Called when a node is collapsed. Stops the active demandThread, if
any,
* and removes all the children.
*/
private void jTreeTreeCollapsed(javax.swing.event.TreeExpansionEvent
evt) {
stopWorker();
DefaultMutableTreeNode node =
(DefaultMutableTreeNode) evt.getPath
().getLastPathComponent();
jlblStatus.setText("Collapsed "+node);
}
/*
* jTreeValueChanged()
* Updates the status line when a node is selected.
*/
private void jTreeValueChanged(javax.swing.event.TreeSelectionEvent
evt) {
Object node = evt.getPath().getLastPathComponent();
String s = evt.isAddedPath() ? "Selected "+node : "";
jlblStatus.setText(s);
}
/**
* startWorker()
* Given a node factory and an expanded node, starts a SwingWorker
* to create children for the expanded node and insert them into
* the tree.
*/
protected void startWorker(final TreeNodeFactory fac,
final
DefaultMutableTreeNode node) {
final Object userObject = node.getUserObject();
demandThread = new SwingWorker() {
/* public long getTimeout() { return 2500; } */
public Object construct() {
/* Create children for the expanded node. */
try {
return fac.createChildren(userObject);
} catch (Exception x) {
return null;
} /// dga /// for now, don't handle
exceptions
}
public void finished() {
/* Set the demandThread to null and stop the
animation,
but only if we are the active
demandThread. */
if (demandThread == this) {
demandThread = null;
blip.stop();
}
/* Get the children created by the factory and
insert them into the local tree model.
*/
DefaultMutableTreeNode[] children =
(DefaultMutableTreeNode[]) get();
for (int i = 0; i < children.length; i++) {
node.insert(children[i], i);
}
DefaultTreeModel model =
(DefaultTreeModel) jTree.getModel();
model.nodeStructureChanged(node);
jlblStatus.setText("Expanded "+node);
}
};
/* Update status line and start animation. */
jlblStatus.setText("Expanding "+node+"...");
blip.start();
}
/** Stops the active worker, if any. */
protected void stopWorker() {
if (demandThread != null) {
demandThread.interrupt();
// worker set to null in finished
}
}
/*
* setSource()
* Initializes the tree model given a source param. Override
* <code>createRoot</code> to create a root node and factory
* appropriate for the source.
*/
public void setSource(Object source) {
requestHalt();
// DefaultMutableTreeNode root = createRoot(source);
rootNode = createRoot(source);
if (rootNode == null) {
debug("rootNode null in setSource()");
}
DefaultTreeModel model = (DefaultTreeModel) jTree.getModel();
// model.setRoot(root);
model.setRoot(rootNode);
model.setAsksAllowsChildren(true);
}
/**
* runWork()
* This is the work done by the backgnd Thread
*/
private void runWork() {
if (rootNode == null) {
debug("rootNode null in runWork()");
}
if (factory == null) {
debug("factory null in runWork()");
}
populateNode(factory,rootNode);
}
/*
* populateNode()
* Add children to any given node, and all of its child nodes
*/
private void populateNode(final TreeNodeFactory fac,
final
DefaultMutableTreeNode node) {
DefaultTreeModel model = (DefaultTreeModel)
jTree.getModel();
int childCount = 0;
if (fac == null) {
debug("null factory in populateNode()");
}
if (node == null) {
debug("null node in populateNode()");
}
childCount = node.getChildCount();
debug("populating node: " + node);
if (childCount <= 0) { // not yet populated
final Object userObject = node.getUserObject();
// Get the children created by the factory and insert
them into the
// local tree model.
try {
DefaultMutableTreeNode[] children =
(DefaultMutableTreeNode[])
fac.createChildren(userObject);
debug("Found " + children.length + " children");
for (int i = 0; i < children.length; i++) {
node.insert(children[i], i);
}
// Update childCount to reflect new number of
children
childCount = node.getChildCount();
// Alert the tree model of the change
model.nodeStructureChanged(node);
} catch (InvocationTargetException ex) {
/* Handle exceptions thrown by the factory
method. */
String msg = "Failed expanding "+node+": ";
Throwable err = ex.getTargetException();
if (err instanceof InterruptedException) {
msg += "interrupted";
} else {
msg += err;
}
jlblStatus.setText(msg);
} catch (InterruptedException ex) {
// unreachable - result is ready
Thread.currentThread().interrupt();
} catch (Exception ex) {
String msg = "Failed expanding "+node+": ";
msg += ex;
jlblStatus.setText(msg);
}
} else {
debug("skipping node " + node + " (" + childCount + "
children)");
}
// Recursively populate all just-returned nodes
for (int i = 0; i < childCount; i++) {
DefaultMutableTreeNode thisChild =
(DefaultMutableTreeNode) model.getChild(node,i);
populateNode(fac,thisChild);
}
debug("Done populating node:" + node + " (" + childCount + "
children)");
}
/**
* createRoot()