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 }