Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4335789

Bogus definite assignment error and crash, likely related to 4306909

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P4 P4
    • 1.4.0
    • 1.3.0
    • tools
    • 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()

            gafter Neal Gafter (Inactive)
            rlewis Roger Lewis (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: