1 19 20 package org.netbeans.swing.popupswitcher; 21 22 import java.awt.Color ; 23 import java.awt.Component ; 24 import java.awt.Dimension ; 25 import java.awt.Font ; 26 import java.awt.FontMetrics ; 27 import java.awt.Graphics ; 28 import java.awt.Graphics2D ; 29 import java.awt.image.BufferedImage ; 30 import java.lang.ref.SoftReference ; 31 import javax.swing.BorderFactory ; 32 import javax.swing.Icon ; 33 import javax.swing.JTable ; 34 import javax.swing.UIManager ; 35 import javax.swing.border.Border ; 36 import javax.swing.table.DefaultTableCellRenderer ; 37 import javax.swing.table.TableCellRenderer ; 38 import org.openide.util.Utilities; 39 40 50 public class SwitcherTable extends JTable { 51 52 private static final Border rendererBorder = 53 BorderFactory.createEmptyBorder(2, 5, 0, 5); 54 55 private Icon nullIcon = new NullIcon(); 56 private Color foreground; 57 private Color background; 58 private Color selForeground; 59 private Color selBackground; 60 61 62 private Dimension prefSize; 63 64 65 69 private boolean needCalcRowHeight = true; 70 71 75 public SwitcherTable(SwitcherTableItem[] items) { 76 this(items, 0); 77 } 78 79 84 public SwitcherTable(SwitcherTableItem[] items, int y) { 85 super(); 86 init(); 87 int gap = (y == 0 ? 10 : 5); 89 int height = Utilities.getUsableScreenBounds().height - y - gap; 90 setModel(new SwitcherTableModel(items, getRowHeight(), height)); 91 getSelectionModel().clearSelection(); 92 getSelectionModel().setAnchorSelectionIndex(-1); 93 getSelectionModel().setLeadSelectionIndex(-1); 94 } 95 96 private void init() { 97 setBorder(BorderFactory.createLineBorder(getForeground())); 98 setShowHorizontalLines(false); 99 calcRowHeight(getOffscreenGraphics()); 101 } 102 103 public void updateUI() { 104 needCalcRowHeight = true; 105 super.updateUI(); 106 } 107 108 public void setFont(Font f) { 109 needCalcRowHeight = true; 110 super.setFont(f); 111 } 112 113 public Component prepareRenderer( 114 TableCellRenderer renderer, 115 int row, 116 int column) { 117 118 SwitcherTableItem item 119 = (SwitcherTableItem) getSwitcherTableModel().getValueAt(row, column); 120 121 boolean selected = row == getSelectedRow() && 122 column == getSelectedColumn() && item != null; 123 124 DefaultTableCellRenderer ren = (DefaultTableCellRenderer ) 125 renderer.getTableCellRendererComponent(this, item, 126 selected, selected, row, column); 127 128 if (item == null) { 129 ren.setOpaque(false); 131 ren.setIcon(null); 132 return ren; 133 } 134 135 Icon icon = item.getIcon(); 136 if (icon == null ) { 137 icon = nullIcon; 138 } 139 ren.setText(selected || item.isActive() ? item.getName() : item.getHtmlName()); 140 ren.setIcon(icon); 141 ren.setBorder(rendererBorder); 142 ren.setIconTextGap(26 - icon.getIconWidth()); 143 144 if (item.isActive()) { 145 ren.setFont(new Font (getFont().getName(), Font.BOLD, getFont().getSize())); 147 } 148 149 ren.setOpaque(true); 150 151 return ren; 152 } 153 154 private static class NullIcon implements Icon { 155 public int getIconWidth() { return 0; } 156 public int getIconHeight() { return 0; } 157 public void paintIcon(Component c, Graphics g, int x, int y) {} 158 } 159 160 public Color getForeground() { 161 if (foreground == null) { 162 foreground = UIManager.getColor("ComboBox.foreground"); 163 } 164 return foreground != null ? foreground : super.getForeground(); 165 } 166 167 public Color getBackground() { 168 if (background == null) { 169 background = UIManager.getColor("ComboBox.background"); 170 } 171 return background != null ? background : super.getBackground(); 172 } 173 174 public Color getSelectionForeground() { 175 if (selForeground == null) { 176 selForeground = UIManager.getColor("ComboBox.selectionForeground"); 177 } 178 return selForeground != null ? selForeground : super.getSelectionForeground(); 179 } 180 181 public Color getSelectionBackground() { 182 if (selBackground == null) { 183 selBackground = UIManager.getColor("ComboBox.selectionBackground"); 184 } 185 return selBackground != null ? selBackground : super.getSelectionBackground(); 186 } 187 188 195 private void calcRowHeight(Graphics g) { 196 Font f = getFont(); 197 FontMetrics fm = g.getFontMetrics(f); 198 int rowHeight = Math.max(fm.getHeight(), 16) + 4; 200 needCalcRowHeight = false; 201 setRowHeight(rowHeight); 202 } 203 204 private static SoftReference <BufferedImage > ctx = null; 205 206 210 private static Graphics2D getOffscreenGraphics() { 211 BufferedImage result = null; 212 if (ctx != null) { 215 result = ctx.get(); 216 } 217 if (result == null) { 218 result = new BufferedImage (10, 10, BufferedImage.TYPE_INT_RGB); 219 ctx = new SoftReference <BufferedImage >(result); 220 } 221 return (Graphics2D ) result.getGraphics(); 222 } 223 224 229 public Dimension getPreferredSize() { 230 if (prefSize == null) { 231 int cols = getColumnCount(); 232 int rows = getRowCount(); 233 234 int columnWidth = 0; 236 for (int i = 0; i < cols; i++) { 237 for (int j = 0; j < rows; j++) { 238 TableCellRenderer ren = getCellRenderer(j,i); 239 Component c = prepareRenderer(ren, j, i); 240 columnWidth = Math.max( 242 c.getPreferredSize().width + 1, columnWidth); 243 } 244 } 245 columnWidth = Math.min(columnWidth, 250); 246 for (int i = 0; i < cols; i++) { 248 getColumnModel().getColumn(i).setPreferredWidth(columnWidth); 249 } 250 prefSize = new Dimension (columnWidth * cols, rows * getRowHeight()); 252 } 253 return prefSize; 254 } 255 256 private SwitcherTableModel getSwitcherTableModel() { 257 return (SwitcherTableModel) getModel(); 258 } 259 260 public SwitcherTableItem getSelectedItem() { 261 return (SwitcherTableItem) getValueAt(getSelectedRow(), getSelectedColumn()); 262 } 263 264 public void paint(Graphics g) { 265 if (needCalcRowHeight) { 266 calcRowHeight(g); 267 } 268 super.paint(g); 269 } 270 271 277 public int getLastValidRow() { 278 int lastColIdx = getColumnCount() - 1; 279 for (int i = getRowCount() - 1; i >= 0; i--) { 280 if (getValueAt(i, lastColIdx) != null) { 281 return i; 282 } 283 } 284 return -1; 285 } 286 } 287 | Popular Tags |