JDK-6453451 : JTree is not visible with GTK and Right-to-Left component orientation
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 6
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • OS: generic,solaris
  • CPU: generic,sparc
  • Submitted: 2006-07-27
  • Updated: 2011-03-07
  • Resolved: 2011-03-07
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 6 JDK 7
6u1Fixed 7 b03Fixed
Related Reports
Duplicate :  
Description
FULL PRODUCT VERSION :
Mustang b91

A DESCRIPTION OF THE PROBLEM :
JTree is invisible with combination of Right-to-Left component orientation and GTK LaF.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile and run. You don't see the JTree. Notice that with commented out "scroll.applyComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);" it works ok. It works ok as well with the uncommented "ComponentOrientation.RIGHT_TO_LEFT" code but with another LaF, say Motif.


EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
JTree displays.
ACTUAL -
JTree does not display.

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------

import java.awt.*;
import javax.swing.*;
import javax.swing.tree.*;
import java.lang.reflect.InvocationTargetException;

public class GTKTreeRTLTest {
    
    private static JFrame mainFrame;
    
    public static void main(String[] args) throws InterruptedException, InvocationTargetException {
        SwingUtilities.invokeAndWait(new Runnable(){
            
            public void run() {
                mainFrame = new JFrame("GTKTreeRTLTest");
                mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                try {
                    // ???
                    UIManager.setLookAndFeel("com.sun.java.swing.plaf.gtk.GTKLookAndFeel");
//                    UIManager.setLookAndFeel("com.sun.java.swing.plaf.motif.MotifLookAndFeel");
                    
                    SwingUtilities.updateComponentTreeUI(mainFrame);
                } catch (Exception e) {
                    throw new RuntimeException("Test failed: ", e);
                }
                
                JTree tree = new JTree(getDefaultTreeModel());
                tree.setShowsRootHandles(true);
                tree.getSelectionModel().setSelectionMode(TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION);
                JPanel mainPanel = new JPanel(new BorderLayout());
                JScrollPane scroll = new JScrollPane(tree);
                mainPanel.add(scroll, BorderLayout.CENTER);
                mainFrame.setContentPane(mainPanel);
                
                // ???
                scroll.applyComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
                
                mainFrame.pack();
                mainFrame.setLocationRelativeTo(null);
                mainFrame.setVisible(true);
            }
        
        });
        
        mainFrame.validate();
    }
    
    private static DefaultTreeModel getDefaultTreeModel() {
        DefaultMutableTreeNode root = new DefaultMutableTreeNode("JTree");
        DefaultMutableTreeNode parent;

        parent = new DefaultMutableTreeNode("colors");
        root.add(parent);
        parent.add(new DefaultMutableTreeNode("blue"));
        parent.add(new DefaultMutableTreeNode("violet"));
        parent.add(new DefaultMutableTreeNode("red"));
        parent.add(new DefaultMutableTreeNode("yellow"));

        parent = new DefaultMutableTreeNode("sports");
        root.add(parent);
        parent.add(new DefaultMutableTreeNode("basketball"));
        parent.add(new DefaultMutableTreeNode("soccer"));
        parent.add(new DefaultMutableTreeNode("football"));

        DefaultMutableTreeNode nparent = new DefaultMutableTreeNode("hockey");
        parent.add(nparent);
        nparent.add(new DefaultMutableTreeNode("ice hockey"));
        nparent.add(new DefaultMutableTreeNode("roller hockey"));
        nparent.add(new DefaultMutableTreeNode("floor hockey"));
        nparent.add(new DefaultMutableTreeNode("road hockey"));

        return new DefaultTreeModel(root);
    }
    
}

---------- END SOURCE ----------

Comments
SUGGESTED FIX http://javaweb.sfbay/jcg/1.7.0-dolphin/swing/6453451/
19-09-2006

EVALUATION For testing, I attached TreeTest.java. 1.4.2 - it works fine under GTK L&F with RTL. 5.0 - JTree shows something when you switch to GTK RTL. But there is an issue with positioning. Try resizing the window. 6.0 - Same is 1.5
14-08-2006

EVALUATION BasicTreeUI and BasicListUI make cached copies of several component properties, like isLeftToRight and width. Those copies are updated by code in several random places that does not necessarily get invoked from Synth UI classes. E.g. tree width is updated in BasicTreeUI.paint() which is overridden in SynthTreeUI. The solution is to nuke these cached copies and retrieve properties directly from components.
09-08-2006