001 /*
002 * Copyright 2002-2006 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
005 * use this file except in compliance with the License. You may obtain a copy
006 * of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
012 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
013 * License for the specific language governing permissions and limitations
014 * under the License.
015 */
016 package org.springframework.richclient.list;
017
018 import java.awt.BorderLayout;
019 import java.awt.Component;
020 import java.awt.Rectangle;
021
022 import javax.swing.DefaultListCellRenderer;
023 import javax.swing.JComboBox;
024 import javax.swing.JList;
025 import javax.swing.JPanel;
026 import javax.swing.JTable;
027 import javax.swing.ListCellRenderer;
028 import javax.swing.ListSelectionModel;
029 import javax.swing.UIManager;
030 import javax.swing.border.Border;
031 import javax.swing.border.EmptyBorder;
032 import javax.swing.event.TableModelListener;
033 import javax.swing.table.JTableHeader;
034 import javax.swing.table.TableColumnModel;
035 import javax.swing.table.TableModel;
036
037 import org.springframework.util.Assert;
038
039 /**
040 * ListCellRenderer which renders table cells in a list cell.
041 * <p>
042 * can be used in a {@link JComboBox} to render a table as a popup.
043 *
044 * @author Mathias Broekelmann
045 *
046 */
047 public class TableListCellRenderer extends JTable implements ListCellRenderer {
048
049 protected static Border noFocusBorder = new EmptyBorder(1, 1, 1, 1);
050
051 private static final Border SAFE_NO_FOCUS_BORDER = new EmptyBorder(1, 1, 1, 1);
052
053 private ListCellRenderer cellRenderer = new DefaultListCellRenderer();
054
055 private final JPanel headerPanel = new JPanel(new BorderLayout(0, 0));
056
057 private static class TableListCellRendererModel implements TableModel {
058
059 private int row;
060
061 private TableListModel listModel;
062
063 public TableListCellRendererModel(TableListModel model) {
064 listModel = model;
065 }
066
067 /**
068 * @return the listModel
069 */
070 public TableListModel getListModel() {
071 return listModel;
072 }
073
074 public void setListModel(TableListModel model) {
075 listModel = model;
076 }
077
078 public int getRowCount() {
079 return 1;
080 }
081
082 public void setRow(int row) {
083 this.row = row;
084 }
085
086 public Object getValueAt(int aRow, int aColumn) {
087 return listModel.getValueAt(row, aColumn);
088 }
089
090 public boolean isCellEditable(int row, int column) {
091 return false;
092 }
093
094 public int getColumnCount() {
095 return listModel.getColumnCount();
096 }
097
098 public void addTableModelListener(TableModelListener l) {
099 }
100
101 public Class getColumnClass(int columnIndex) {
102 return listModel.getColumnClass(columnIndex);
103 }
104
105 public String getColumnName(int columnIndex) {
106 return listModel.getColumnName(columnIndex);
107 }
108
109 public void removeTableModelListener(TableModelListener l) {
110 }
111
112 public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
113 }
114
115 }
116
117 public TableListCellRenderer() {
118 this(new DefaultTableListModel());
119 }
120
121 public TableListCellRenderer(TableListModel model) {
122 this(model, null);
123 }
124
125 public TableListCellRenderer(TableListModel model, TableColumnModel columnModel) {
126 super(new TableListCellRendererModel(model), columnModel);
127 setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
128 setOpaque(true);
129 setBorder(getNoFocusBorder());
130 headerPanel.add(getTableHeader(), BorderLayout.NORTH);
131 }
132
133 public TableListModel getTableListModel() {
134 return getTableListCellRendererModel().getListModel();
135 }
136
137 public void setTableListModel(TableListModel model) {
138 getTableListCellRendererModel().setListModel(model);
139 }
140
141 public void setModel(TableModel dataModel) {
142 Assert.isInstanceOf(TableListCellRendererModel.class, dataModel);
143 super.setModel(dataModel);
144 }
145
146 private TableListCellRendererModel getTableListCellRendererModel() {
147 return (TableListCellRendererModel) super.getModel();
148 }
149
150 private static Border getNoFocusBorder() {
151 if (System.getSecurityManager() != null) {
152 return SAFE_NO_FOCUS_BORDER;
153 } else {
154 return noFocusBorder;
155 }
156 }
157
158 public void setTableHeader(JTableHeader tableHeader) {
159 super.setTableHeader(tableHeader);
160 if (headerPanel != null) {
161 if (tableHeader == null)
162 headerPanel.removeAll();
163 else
164 headerPanel.add(tableHeader, BorderLayout.NORTH);
165 }
166 }
167
168 public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected,
169 boolean cellHasFocus) {
170 if (index == -1) {
171 Component comp = cellRenderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
172 return comp;
173 }
174 getTableListCellRendererModel().setRow(index);
175
176 setComponentOrientation(list.getComponentOrientation());
177 if (isSelected) {
178 setBackground(list.getSelectionBackground());
179 setForeground(list.getSelectionForeground());
180 } else {
181 setBackground(list.getBackground());
182 setForeground(list.getForeground());
183 }
184
185 setEnabled(list.isEnabled());
186 setFont(list.getFont());
187
188 Border border = null;
189 if (cellHasFocus) {
190 if (isSelected) {
191 border = UIManager.getBorder("List.focusSelectedCellHighlightBorder");
192 }
193 if (border == null) {
194 border = UIManager.getBorder("List.focusCellHighlightBorder");
195 }
196 } else {
197 border = getNoFocusBorder();
198 }
199 setBorder(border);
200
201 if (index == 0) {
202 headerPanel.add(this);
203 return headerPanel;
204 }
205
206 return this;
207 }
208
209 /**
210 * Overridden for performance reasons.
211 */
212 public void validate() {
213 }
214
215 /**
216 * Overridden for performance reasons.
217 */
218 protected void validateTree() {
219 }
220
221 /**
222 * Overridden for performance reasons.
223 */
224 public void revalidate() {
225 }
226
227 /**
228 * Overridden for performance reasons.
229 */
230 public void repaint(long tm, int x, int y, int width, int height) {
231 }
232
233 /**
234 * Overridden for performance reasons.
235 */
236 public void repaint(Rectangle r) {
237 }
238
239 /**
240 * Overridden for performance reasons.
241 */
242 protected void firePropertyChange(String propertyName, Object oldValue,
243 Object newValue) {
244 }
245
246 /**
247 * Overridden for performance reasons.
248 */
249 public void firePropertyChange(String propertyName, byte oldValue,
250 byte newValue) {
251 }
252
253 /**
254 * Overridden for performance reasons.
255 */
256 public void firePropertyChange(String propertyName, char oldValue,
257 char newValue) {
258 }
259
260 /**
261 * Overridden for performance reasons.
262 */
263 public void firePropertyChange(String propertyName, short oldValue,
264 short newValue) {
265 }
266
267 /**
268 * Overridden for performance reasons.
269 */
270 public void firePropertyChange(String propertyName, int oldValue,
271 int newValue) {
272 }
273
274 /**
275 * Overridden for performance reasons.
276 */
277 public void firePropertyChange(String propertyName, long oldValue,
278 long newValue) {
279 }
280
281 /**
282 * Overridden for performance reasons.
283 */
284 public void firePropertyChange(String propertyName, float oldValue,
285 float newValue) {
286 }
287
288 /**
289 * Overridden for performance reasons.
290 */
291 public void firePropertyChange(String propertyName, double oldValue,
292 double newValue) {
293 }
294
295 /**
296 * Overridden for performance reasons.
297 */
298 public void firePropertyChange(String propertyName, boolean oldValue,
299 boolean newValue) {
300 }
301 }