View Javadoc

1   package com.explosion.utilities;
2   
3   /***
4    * This code came from JGuru - complements of Maksim Kovalenko. Thanks Maksim :)
5    * 
6    * 
7    * Assuming that JTable resides in JScrollPane, we set row header of that
8    * JScrollPane and show list there..... (long story). run and study if you want.
9    * just call RowHeaderUtil.setRowHeader(table);
10   */
11  
12  import java.awt.Component;
13  import java.awt.Container;
14  import java.awt.Font;
15  import java.awt.Rectangle;
16  import java.awt.event.MouseEvent;
17  
18  import javax.swing.AbstractListModel;
19  import javax.swing.BorderFactory;
20  import javax.swing.JLabel;
21  import javax.swing.JList;
22  import javax.swing.JScrollPane;
23  import javax.swing.JTable;
24  import javax.swing.JViewport;
25  import javax.swing.ListCellRenderer;
26  import javax.swing.UIManager;
27  import javax.swing.border.Border;
28  import javax.swing.table.JTableHeader;
29  
30  public class RowHeaderUtil
31  {
32  
33      public RowHeaderUtil()
34      {}
35  
36      public static boolean isRowHeaderVisible(JTable table)
37      {
38          Container p = table.getParent();
39          if (p instanceof JViewport)
40          {
41              Container gp = p.getParent();
42              if (gp instanceof JScrollPane)
43              {
44                  JScrollPane scrollPane = (JScrollPane) gp;
45                  JViewport rowHeaderViewPort = scrollPane.getRowHeader();
46                  if (rowHeaderViewPort != null)
47                      return rowHeaderViewPort.getView() != null;
48              }
49          }
50          return false;
51      }
52  
53      /***
54       * * Creates row header for table with row number (starting with 1)
55       * displayed
56       */
57      public static void removeRowHeader(JTable table)
58      {
59          Container p = table.getParent();
60          if (p instanceof JViewport)
61          {
62              Container gp = p.getParent();
63              if (gp instanceof JScrollPane)
64              {
65                  JScrollPane scrollPane = (JScrollPane) gp;
66                  scrollPane.setRowHeader(null);
67              }
68          }
69      }
70  
71      /***
72       * * Creates row header for table with row number (starting with 1)
73       * displayed
74       */
75      public void setRowHeader(JTable table, boolean showRowNumber)
76      {
77          Container p = table.getParent();
78          if (p instanceof JViewport)
79          {
80              Container gp = p.getParent();
81              if (gp instanceof JScrollPane)
82              {
83                  JScrollPane scrollPane = (JScrollPane) gp;
84                  scrollPane.setRowHeaderView(new TableRowHeader(table, showRowNumber));
85                  scrollPane.setCorner(JScrollPane.UPPER_LEFT_CORNER,new UpperLeftComponent(table));
86              }
87          }
88      }
89  }
90  
91  class TableRowHeader extends JList
92  {
93  
94      private JTable table;
95  
96      public TableRowHeader(JTable table, boolean showRowNumber)
97      {
98          super(new TableRowHeaderModel(table));
99          this.table = table;
100         this.setBackground(table.getParent().getBackground());
101         setFixedCellHeight(table.getRowHeight());
102         setFixedCellWidth(preferredHeaderWidth());
103         setCellRenderer(new RowHeaderRenderer(table, showRowNumber));
104         setSelectionModel(table.getSelectionModel());
105     }
106 
107     /****************************************************************************
108      * * Returns the bounds of the specified range of items in JList
109      * coordinates. Returns null if index isn't valid. * *
110      * 
111      * @param index0 the index of the first JList cell in the range *
112      * @param index1 the index of the last JList cell in the range *
113      * @return the bounds of the indexed cells in pixels
114      */
115     public Rectangle getCellBounds(int index0, int index1)
116     {
117         Rectangle rect0 = table.getCellRect(index0, 0, true);
118         Rectangle rect1 = table.getCellRect(index1, 0, true);
119         int y, height;
120         if (rect0.y < rect1.y)
121         {
122             y = rect0.y;
123             height = rect1.y + rect1.height - y;
124         }
125         else
126         {
127             y = rect1.y;
128             height = rect0.y + rect0.height - y;
129         }
130         return new Rectangle(0, y, getFixedCellWidth(), height);
131     }
132 
133     // assume that row header width should be big enough to display row number
134     // Integer.MAX_VALUE completely
135     private int preferredHeaderWidth()
136     {
137         JLabel longestRowLabel = new JLabel("999");//
138         JTableHeader header = table.getTableHeader();
139         longestRowLabel.setBorder(header.getBorder());//UIManager.getBorder("TableHeader.cellBorder"));
140         longestRowLabel.setHorizontalAlignment(JLabel.CENTER);
141         longestRowLabel.setFont(header.getFont());
142         return longestRowLabel.getPreferredSize().width;
143     }
144 }
145 
146 class TableRowHeaderModel extends AbstractListModel
147 {
148 
149     private JTable table;
150 
151     public TableRowHeaderModel(JTable table)
152     {
153         this.table = table;
154     }
155 
156     public int getSize()
157     {
158         return table.getRowCount();
159     }
160 
161     public Object getElementAt(int index)
162     {
163         return null;
164     }
165 }
166 
167 class RowHeaderRenderer extends JLabel implements ListCellRenderer
168 {
169     private boolean showRowNumber = false;
170     private JTable table;
171     private Border selectedBorder;
172     private Border normalBorder;
173     private Font selectedFont;
174     private Font normalFont;
175 
176     RowHeaderRenderer(JTable table, boolean showRowNumber)
177     {
178         this.table = table;
179         this.showRowNumber = showRowNumber;
180         normalBorder = UIManager.getBorder("TableHeader.cellBorder");
181         selectedBorder = BorderFactory.createRaisedBevelBorder();
182         JTableHeader header = table.getTableHeader();
183         normalFont = header.getFont();
184         selectedFont = normalFont.deriveFont(normalFont.getStyle() | Font.BOLD);
185         setForeground(header.getForeground());
186         setBackground(header.getBackground());
187         setOpaque(true);
188         setHorizontalAlignment(CENTER);
189     }
190 
191     public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus)
192     {
193         if (table.getSelectionModel().isSelectedIndex(index))
194         {
195             setFont(selectedFont);
196             setBorder(selectedBorder);
197         }
198         else
199         {
200             setFont(normalFont);
201             setBorder(normalBorder);
202         }
203         String label = String.valueOf(index + 1);
204         if (showRowNumber)
205            setText(label);
206         else
207            setText("");
208         return this;
209     }
210 }
211 
212 class UpperLeftComponent extends JLabel
213 {
214     public UpperLeftComponent(final JTable table)
215     {
216         Border normalBorder = UIManager.getBorder("TableHeader.cellBorder");
217         Border selectedBorder = BorderFactory.createRaisedBevelBorder();
218         setBorder(normalBorder);
219         JTableHeader header = table.getTableHeader();
220         setForeground(header.getForeground());
221         setBackground(header.getBackground());
222         setOpaque(true);
223         setHorizontalAlignment(CENTER);
224         this.addMouseListener(new java.awt.event.MouseAdapter()
225         {
226 
227             public void mouseClicked(MouseEvent e)
228             {
229                 table.selectAll();                 
230             }
231         });
232     }
233 }