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
134
135 private int preferredHeaderWidth()
136 {
137 JLabel longestRowLabel = new JLabel("999");
138 JTableHeader header = table.getTableHeader();
139 longestRowLabel.setBorder(header.getBorder());
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 }