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

JTree DnD conflicts with JTree.setUI(..)

XMLWordPrintable

    • x86
    • windows_nt, windows_2000

        Name: sv35042 Date: 10/09/2002


        FULL PRODUCT VERSION :
        java version "1.4.0"
        Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-
        b92)
        Java HotSpot(TM) Client VM (build 1.4.0-b92, mixed mode)

        FULL OPERATING SYSTEM VERSION :
        Microsoft Windows 2000 [Version
        5.00.2195]

        ADDITIONAL OPERATING SYSTEMS :
        Also on Linux

        A DESCRIPTION OF THE PROBLEM :
        JTrees with enabled drop support produce NullPointerExceptions when
        setUI() was called on them.
        It doesn't matter which TreeUI is used
        (Windows, Metal, Basic, as soon as the TreeUI is changed the failure
        appears.
        This bug appears on Windows and Linux.

        STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
        1.Compile and execute the program
        2.Select with a click a component of
        the left JTree
        3.Drag this component to the textarea
        4.Do steps 2+3
        with the right JTree
        5.You will see a NullPointerException on the
        console

        EXPECTED VERSUS ACTUAL BEHAVIOR :
        The left JTree is working properly, whereas the right JTree produces
        NullPointerExceptions when drags are moved out of the JTree.
        Code is
        working so far but there are NullPointerExceptions.

        ERROR MESSAGES/STACK TRACES THAT OCCUR :
        java.lang.NullPointerException
                at
        javax.swing.plaf.basic.BasicTreeUI$TreeDropTargetListener.restoreComponentState(BasicTreeUI.java:3680)
         
               at
        javax.swing.plaf.basic.BasicDropTargetListener.dragExit(BasicDropTargetListener.java:249)
         
               at javax.swing.TransferHandler$SwingDropTarget.dragExit(TransferHandler.java:579)
                
        at
        sun.awt.dnd.SunDropTargetContextPeer.processExitMessage(SunDropTargetContextPeer.java:396)
         
               at
        sun.awt.dnd.SunDropTargetContextPeer.access$700(SunDropTargetContextPeer.java:52)
         
               at
        sun.awt.dnd.SunDropTargetContextPeer$EventDispatcher.dispatchExitEvent(SunDropTargetContextPeer.java:793)
         
               at
        sun.awt.dnd.SunDropTargetContextPeer$EventDispatcher.dispatchEvent(SunDropTargetContextPeer.java:741)
         
               at sun.awt.dnd.SunDropTargetEvent.dispatch(SunDropTargetEvent.java:29)
                at
        java.awt.Component.dispatchEventImpl(Component.java:3384)
                at
        java.awt.Container.dispatchEventImpl(Container.java:1437)
                at
        java.awt.Component.dispatchEvent(Component.java:3367)
                at
        java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:3214)
                at
        java.awt.LightweightDispatcher.trackMouseEnterExit(Container.java:3046)
                at
        java.awt.LightweightDispatcher.processDropTargetEvent(Container.java:2992)
                at
        java.awt.LightweightDispatcher.dispatchEvent(Container.java:2854)
                at
        java.awt.Container.dispatchEventImpl(Container.java:1423)
                at
        java.awt.Window.dispatchEventImpl(Window.java:1566)
                at
        java.awt.Component.dispatchEvent(Component.java:3367)
                at
        java.awt.EventQueue.dispatchEvent(EventQueue.java:445)
                at
        java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:190)
         
               at
        java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:144)
         
               at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
                at
        java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:130)
                at
        java.awt.EventDispatchThread.run(EventDispatchThread.java:98)

        This bug can be reproduced always.

        ---------- BEGIN SOURCE ----------
        import java.awt.*;
        import java.awt.dnd.*;
        import java.awt.datatransfer.*;
        import
        java.awt.event.*;

        import javax.swing.*;
        import javax.swing.event.*;
        import
        javax.swing.tree.*;
        import javax.swing.plaf.metal.MetalTreeUI;


        public class
        PanTree extends JFrame {
          private JTree jtree;
          private JTree ofjtree;
          private
        JScrollPane jscp;
          private JScrollPane ofjscp;
        public static void main(String args[]){
          
        PanTree pt = new PanTree();
        }
        public PanTree(){
          super();
          try{
            
        UIManager.setLookAndFeel(new javax.swing.plaf.metal.MetalLookAndFeel());
          }catch
        (Exception e){
            System.err.println(e);
          }
          getContentPane().setLayout(new
        FlowLayout());
          setSize(800,500);
          jtree = new JTree();
          
        jtree.setDragEnabled(true);
          jtree.setTransferHandler(new TreeTransferHandler());
          
        jtree.setScrollsOnExpand(true);
          
        jtree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
         
         jscp = new JScrollPane(jtree);
          
          
          ofjtree = new JTree();
          
        ofjtree.setDragEnabled(true);
          ofjtree.setTransferHandler(new
        TreeTransferHandler());
          ofjtree.setScrollsOnExpand(true);
          
        ofjtree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
         
         ofjtree.setUI(new MetalTreeUI()); // this causes NullPointerExceptions
          ofjscp = new
        JScrollPane(ofjtree);
          JTextArea textarea = new JTextArea(30,30);
          
        textarea.setDragEnabled(true);

          getContentPane().add(jscp);
          
        getContentPane().add(textarea);
          getContentPane().add(ofjscp);
          
        addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
              
        System.out.println("trying to exit");
              System.exit(0);
            }
          });
          pack();
          
        setVisible(true);
        }

          class TreeTransferHandler extends TransferHandler{
            private
        DataFlavor[] plainFlavors = null;
            
            TreeTransferHandler(){
              super();
              try {
                
        plainFlavors = new DataFlavor[1];
                plainFlavors[0] = new
        DataFlavor("text/plain;class=java.lang.String");
              }catch (ClassNotFoundException
        cle){
                System.err.println("error initializing TreeTransferable");
              }
            }
            protected
        Transferable createTransferable(JComponent c) {
              if (c instanceof JTree) {
                JTree tree =
        (JTree) c;
                TreePath path = tree.getSelectionPath();
                return new TreeTransferable(tree,
        path);
              }
              return null;
            }

            public int getSourceActions(JComponent c) {
              return
        COPY;
            }
            
            public boolean canImport(JComponent comp, DataFlavor[] transferFlavors) {
              
        return true;
            }
         
            class TreeTransferable implements Transferable{
              private TreePath
        path;
              private JTree tree;

              TreeTransferable(JTree tree, TreePath path) {
                this.path =
        path;
                this.tree = tree;
              }

              public DataFlavor[] getTransferDataFlavors() {
                return
        plainFlavors;
              }

              public boolean isDataFlavorSupported(DataFlavor flavor) {
                for (int
        i = 0; i < plainFlavors.length; i++) {
                  if (plainFlavors[i].equals(flavor)) {
                    return
        true;
                  }
                }
                return false;
              }

              public Object getTransferData(DataFlavor flavor)
        throws UnsupportedFlavorException{
                String data = getPlainData();
                data = (data == null) ?
        "" : data;
                if (String.class.equals(flavor.getRepresentationClass())) {
                  return data;
                
        }
                throw new UnsupportedFlavorException(flavor);
              }

              protected String getPlainData()
        {
                TreeModel model = tree.getModel();
                Object node = path.getLastPathComponent();
                
        return path.toString()+"\n";
              }
            }
          }
        }
        ---------- END SOURCE ----------

        CUSTOMER WORKAROUND :
        Do not call setUI() on JTrees when using dop!

        Release Regression From : 1.4
        The above release value was the last known release where this
        bug was known to work. Since then there has been a regression.

        (Review ID: 144125)
        ======================================================================

              shickeysunw Shannon Hickey (Inactive)
              svioletsunw Scott Violet (Inactive)
              Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

                Created:
                Updated:
                Resolved:
                Imported:
                Indexed: