Solved

JTree custom renderer - the icons are clipped and bunched up in Windows Look and Feel

Posted on 2006-11-23
5
735 Views
Last Modified: 2013-11-23
Hi
I have a JTree with custom renderer.
The icons displayed (non-leaf nodes btw) are 24x24 gifs.
On any Metal LaF the spacing between nodes is fine, but on any Windows LaF,
the spacing seems to ignore the size of the icons and bunches them up to roughly
the size of the text plust a smallgap (about 16 pixels).
A couple of points:
What the dickens is going on here?
How do I get lists and properties of Swing UIDefaults for components like JTree?
Thanks

 
0
Comment
Question by:richard_fairall
  • 3
  • 2
5 Comments
 
LVL 14

Accepted Solution

by:
hoomanv earned 500 total points
ID: 18001615
// UIDefaults

import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.plaf.*;
import javax.swing.table.TableCellRenderer;

public class ShowUIDefaults extends JFrame implements ActionListener
{
      JFrame frame;
      JTabbedPane tabbedPane;
      SampleRenderer sampleRenderer;

      public ShowUIDefaults(String title)
      {
            super(title);
            frame = this;

            sampleRenderer = new SampleRenderer();

            getContentPane().setLayout( new BorderLayout() );
            tabbedPane = getTabbedPane();
            getContentPane().add( tabbedPane );

            JPanel buttons = new JPanel();
            buttons.setLayout( new GridLayout( 1, 3) );
            getContentPane().add(buttons, BorderLayout.SOUTH);

            JButton metal = new JButton( "Metal" );
            metal.setActionCommand( "javax.swing.plaf.metal.MetalLookAndFeel" );
            metal.addActionListener( this );
            buttons.add(metal);

            JButton windows = new JButton( "Windows" );
            windows.setActionCommand( "com.sun.java.swing.plaf.windows.WindowsLookAndFeel" );
            windows.addActionListener( this );
            buttons.add(windows);

            JButton motif = new JButton( "Motif" );
            motif.setActionCommand( "com.sun.java.swing.plaf.motif.MotifLookAndFeel" );
            motif.addActionListener( this );
            buttons.add(motif);

      }

      public void actionPerformed(ActionEvent e)
      {
            try
            {
                     UIManager.setLookAndFeel(e.getActionCommand());
            }
            catch (Exception e2)
            {
                  System.out.println(e2);
            }

            getContentPane().remove(tabbedPane);
            tabbedPane = getTabbedPane();
            getContentPane().add( tabbedPane );
            SwingUtilities.updateComponentTreeUI(frame);
            frame.pack();
      }

      private JTabbedPane getTabbedPane()
      {
            Map components = new TreeMap();
            UIDefaults defaults = UIManager.getLookAndFeelDefaults();

            //  Build of Map of attributes for each component

            for ( Enumeration enum = defaults.keys(); enum.hasMoreElements(); )
            {
                  Object key = enum.nextElement();
                  Object value = defaults.get( key );

                  Map componentMap = getComponentMap( components, key.toString() );

                  if ( componentMap != null )
                        componentMap.put( key, value );
            }

            JTabbedPane pane = new JTabbedPane( SwingConstants.BOTTOM );
            pane.setPreferredSize( new Dimension( 800, 400 ) );
            addComponentTabs( pane, components );

            return pane;
      }

      private Map getComponentMap( Map components, String key )
      {
            if ( key.startsWith("class") | key.startsWith("javax") )
                  return null;

            //  Component name is found before the first "."

            String componentName;

            int pos = key.indexOf( "." );

            if (pos == -1)
                  if (key.endsWith( "UI" ) )
                        componentName = key.substring( 0, key.length() - 2 );
                  else
                        componentName = "System Colors";
            else
                  componentName = key.substring( 0, pos );

            //  Fix inconsistency

            if (componentName.equals("Checkbox"))
                  componentName = "CheckBox";

            //  Get the Map for this particular component

            Object componentMap = components.get( componentName );

            if (componentMap == null)
            {
                  componentMap = new TreeMap();
                  components.put( componentName, componentMap );
            }

            return (Map)componentMap;
      }

      private void addComponentTabs(JTabbedPane pane, Map components)
      {
            String[ ] colName = {"Key", "Value", "Sample"};
            Set c = components.keySet();

            for (Iterator ci = c.iterator(); ci.hasNext();)
            {
                  String component = (String)ci.next();
                  Map attributes = (Map)components.get( component );

                  Object[ ][ ] rowData = new Object[ attributes.size() ][ 3 ];
                  int i = 0;

                  Set a = attributes.keySet();

                  for(Iterator ai = a.iterator(); ai.hasNext(); i++)

                  {
                        String attribute = (String)ai.next();
                        rowData[ i ] [ 0 ] = attribute;
                        Object o = attributes.get(attribute);

                        if (o != null)
                        {
                              rowData[ i ] [ 1 ] = o.toString();
                              rowData[ i ] [ 2 ] = o;
                        }
                        else
                        {
                              rowData[ i ] [ 1 ] = "null";
                              rowData[ i ] [ 2 ] = "";
                        }

                  }

                  JTable table = new JTable(rowData, colName);
                  table.getColumnModel().getColumn(2).setCellRenderer( sampleRenderer );
                  table.getColumnModel().getColumn(0).setPreferredWidth(250);
                  table.getColumnModel().getColumn(1).setPreferredWidth(500);
                  table.getColumnModel().getColumn(2).setPreferredWidth(50);

                  pane.addTab( component, new JScrollPane( table ) );
            }
      }

      class SampleRenderer extends JLabel implements TableCellRenderer
      {
            public SampleRenderer()
            {
                  super();
                  setHorizontalAlignment( SwingConstants.CENTER );
                  setOpaque(true); //MUST do this for background to show up.
            }

            public Component getTableCellRendererComponent(JTable table,
                                                                                     Object sample,
                                                                                     boolean isSelected,
                                                                                     boolean hasFocus,
                                                                                     int row,
                                                                                     int column)
            {
                  setBackground( null );
                  setBorder( null );
                  setIcon( null );
                  setText( "" );

                  if ( sample instanceof Color )
                  {
                        setBackground( (Color)sample );
                  }
                  else if ( sample instanceof Border )
                  {
                        setBorder( (Border)sample );
                  }
                  else if ( sample instanceof Font )
                  {
                        setText( "Sample" );
                        setFont( (Font)sample );
                  }
                  else if ( sample instanceof Icon )
                  {
                        setIcon( (Icon)sample );
                  }

                  return this;
            }

            public void paint(Graphics g)
            {
                  try
                  {
                        super.paint(g);
                  }
                  catch(Exception e)
                  {
//                        System.out.println(e);
//                        System.out.println(e.getStackTrace()[0]);
                  }
            }
      }

      public static void main(String[] args)
      {
            JFrame f = new ShowUIDefaults( "UI Defaults" );
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            f.pack();
            f.setLocationRelativeTo( null );
            f.setVisible(true);
      }

}
0
 

Author Comment

by:richard_fairall
ID: 18001700
Thanks Hoomanv
That's a great little tool, any idea on the JTree problem?
0
 
LVL 14

Expert Comment

by:hoomanv
ID: 18001720
Hmm, Try another L&F :)
Have you seen Quaqua ? http://www.randelshofer.ch/quaqua/download.html
0
 

Author Comment

by:richard_fairall
ID: 18001752
That's not a solution for me, I need Windows, Metal and other Native LaFs
This one would not have extensions we need (Jidesoft)
0
 

Author Comment

by:richard_fairall
ID: 18091618
Well, no takers for the main question.
This will teach me never to ask 2 questions at once!
I'll just wrap it up
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
Updating Java 9 87
pairstar challenge 2 42
endX challenge 2 50
Java array passed to SQL where clause 23 43
Jaspersoft Studio is a plugin for Eclipse that lets you create reports from a datasource.  In this article, we'll go over creating a report from a default template and setting up a datasource that connects to your database.
Introduction This article is the first of three articles that explain why and how the Experts Exchange QA Team does test automation for our web site. This article explains our test automation goals. Then rationale is given for the tools we use to a…
Viewers learn how to read error messages and identify possible mistakes that could cause hours of frustration. Coding is as much about debugging your code as it is about writing it. Define Error Message: Line Numbers: Type of Error: Break Down…
The viewer will learn how to implement Singleton Design Pattern in Java.

757 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now