001    package org.pbjar.jxlayer.demo;
002    
003    import java.awt.BorderLayout;
004    import java.awt.Component;
005    import java.awt.Graphics;
006    import java.util.ArrayList;
007    import java.util.Arrays;
008    import java.util.Collections;
009    import java.util.List;
010    
011    import javax.swing.Icon;
012    import javax.swing.JComponent;
013    import javax.swing.JFrame;
014    import javax.swing.JLabel;
015    import javax.swing.JPanel;
016    import javax.swing.JScrollPane;
017    import javax.swing.JTable;
018    import javax.swing.SwingUtilities;
019    import javax.swing.border.EtchedBorder;
020    import javax.swing.table.DefaultTableCellRenderer;
021    import javax.swing.table.DefaultTableModel;
022    import javax.swing.table.JTableHeader;
023    import javax.swing.table.TableCellRenderer;
024    import javax.swing.table.TableColumnModel;
025    import javax.swing.table.TableModel;
026    
027    import org.jdesktop.jxlayer.JXLayer;
028    import org.pbjar.jxlayer.plaf.ext.TransformUI;
029    import org.pbjar.jxlayer.plaf.ext.transform.DefaultTransformModel;
030    
031    /**
032     * A table with vertical table headers, rotated by {@link TransformUI}.
033     */
034    public class RotatedTableHeaderRenderer extends DefaultTableCellRenderer {
035    
036        private static final long serialVersionUID = 1L;
037    
038        /**
039         * Run a demo.
040         * 
041         * @param args
042         *            not used
043         */
044        public static void main(String[] args) {
045            TransformUI.prepareForJTextComponent();
046            SwingUtilities.invokeLater(new Runnable() {
047    
048                @Override
049                public void run() {
050    
051                    List<Integer> rowList = new ArrayList<Integer>(Arrays
052                            .asList(new Integer[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }));
053                    Integer[][] data = new Integer[40][];
054                    for (int index = 0; index < data.length; index++) {
055                        Collections.shuffle(rowList);
056                        data[index] = rowList.toArray(new Integer[rowList.size()]);
057                    }
058                    String[] header = { " Column One  ", " Column Two ",
059                            " Column Three ", " Column Four ", " Column Five ",
060                            " Column Six ", " Column Seven ", " Column Eight ",
061                            " Column Nine ", " Column Ten " };
062                    TableModel model = new DefaultTableModel(data, header);
063                    JTable table = new JTable(model);
064                    table.setAutoCreateRowSorter(true);
065                    TableCellRenderer renderer = new RotatedTableHeaderRenderer();
066                    TableColumnModel columnModel = table.getColumnModel();
067                    for (int index = 0; index < columnModel.getColumnCount(); index++) {
068                        columnModel.getColumn(index).setHeaderRenderer(renderer);
069                    }
070                    JFrame frame = new JFrame("Test");
071                    frame.add(new JScrollPane(table));
072                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
073                    frame.pack();
074                    frame.setLocationRelativeTo(null);
075                    frame.setVisible(true);
076                }
077            });
078        }
079    
080        private final JPanel actualRenderer;
081    
082        private final JLabel iconLabel;
083    
084        private final JXLayer<JComponent> layer;
085    
086        private final Icon dummyIcon = new Icon() {
087    
088            @Override
089            public int getIconHeight() {
090                return 16;
091            }
092    
093            @Override
094            public int getIconWidth() {
095                return 16;
096            }
097    
098            @Override
099            public void paintIcon(Component c, Graphics g, int x, int y) {
100                g.setColor(c.getBackground());
101                g.fillRect(x, y, 16, 16);
102    
103            }
104        };
105    
106        public RotatedTableHeaderRenderer() {
107            super();
108            this.setHorizontalAlignment(JLabel.LEADING);
109            DefaultTransformModel model = new DefaultTransformModel();
110            model.setQuadrantRotation(1);
111            layer = TransformUtils.createTransformJXLayer((JComponent) this, model);
112    
113            actualRenderer = new JPanel(new BorderLayout());
114            iconLabel = new JLabel(dummyIcon, JLabel.CENTER);
115            actualRenderer.add(layer, BorderLayout.PAGE_START);
116            actualRenderer.add(iconLabel, BorderLayout.PAGE_END);
117            actualRenderer.setOpaque(true);
118            actualRenderer.setBorder(new EtchedBorder(EtchedBorder.LOWERED));
119        }
120    
121        @Override
122        public Component getTableCellRendererComponent(JTable table, Object value,
123                boolean isSelected, boolean hasFocus, int row, int column) {
124            JTableHeader tableHeader = table.getTableHeader();
125            JComponent preparedRenderer = (JComponent) tableHeader
126                    .getDefaultRenderer().getTableCellRendererComponent(table,
127                            value, isSelected, hasFocus, row, column);
128            layer.setView(preparedRenderer);
129            actualRenderer.setBackground(preparedRenderer.getBackground());
130            if (preparedRenderer instanceof JLabel) {
131                Icon actualIcon = ((JLabel) preparedRenderer).getIcon();
132                if (actualIcon == null) {
133                    iconLabel.setIcon(dummyIcon);
134                } else {
135                    iconLabel.setIcon(actualIcon);
136                    ((JLabel) preparedRenderer).setIcon(null);
137                }
138            }
139            preparedRenderer.setBorder(null);
140            return actualRenderer;
141        }
142    }