1 7 8 package javax.swing.plaf.basic; 9 10 import javax.swing.table.*; 11 import javax.swing.*; 12 import javax.swing.event.*; 13 import java.util.Enumeration ; 14 import java.awt.event.*; 15 import java.awt.*; 16 import javax.swing.plaf.*; 17 18 25 public class BasicTableHeaderUI extends TableHeaderUI { 26 27 private static Cursor resizeCursor = Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR); 28 29 33 34 protected JTableHeader header; 35 protected CellRendererPane rendererPane; 36 37 protected MouseInputListener mouseInputListener; 39 40 45 public class MouseInputHandler implements MouseInputListener { 46 47 private int mouseXOffset; 48 private Cursor otherCursor = resizeCursor; 49 50 public void mouseClicked(MouseEvent e) {} 51 52 private boolean canResize(TableColumn column) { 53 return (column != null) && header.getResizingAllowed() && column.getResizable(); 54 } 55 56 private TableColumn getResizingColumn(Point p) { 57 return getResizingColumn(p, header.columnAtPoint(p)); 58 } 59 60 private TableColumn getResizingColumn(Point p, int column) { 61 if (column == -1) { 62 return null; 63 } 64 Rectangle r = header.getHeaderRect(column); 65 r.grow(-3, 0); 66 if (r.contains(p)) { 67 return null; 68 } 69 int midPoint = r.x + r.width/2; 70 int columnIndex; 71 if( header.getComponentOrientation().isLeftToRight() ) { 72 columnIndex = (p.x < midPoint) ? column - 1 : column; 73 } else { 74 columnIndex = (p.x < midPoint) ? column : column - 1; 75 } 76 if (columnIndex == -1) { 77 return null; 78 } 79 return header.getColumnModel().getColumn(columnIndex); 80 } 81 82 public void mousePressed(MouseEvent e) { 83 header.setDraggedColumn(null); 84 header.setResizingColumn(null); 85 header.setDraggedDistance(0); 86 87 Point p = e.getPoint(); 88 89 TableColumnModel columnModel = header.getColumnModel(); 91 int index = header.columnAtPoint(p); 92 93 if (index != -1) { 94 TableColumn resizingColumn = getResizingColumn(p, index); 96 if (canResize(resizingColumn)) { 97 header.setResizingColumn(resizingColumn); 98 if( header.getComponentOrientation().isLeftToRight() ) { 99 mouseXOffset = p.x - resizingColumn.getWidth(); 100 } else { 101 mouseXOffset = p.x + resizingColumn.getWidth(); 102 } 103 } 104 else if (header.getReorderingAllowed()) { 105 TableColumn hitColumn = columnModel.getColumn(index); 106 header.setDraggedColumn(hitColumn); 107 mouseXOffset = p.x; 108 } 109 } 110 } 111 112 private void swapCursor() { 113 Cursor tmp = header.getCursor(); 114 header.setCursor(otherCursor); 115 otherCursor = tmp; 116 } 117 118 public void mouseMoved(MouseEvent e) { 119 if (canResize(getResizingColumn(e.getPoint())) != 120 (header.getCursor() == resizeCursor)) { 121 swapCursor(); 122 } 123 } 124 125 public void mouseDragged(MouseEvent e) { 126 int mouseX = e.getX(); 127 128 TableColumn resizingColumn = header.getResizingColumn(); 129 TableColumn draggedColumn = header.getDraggedColumn(); 130 131 boolean headerLeftToRight = header.getComponentOrientation().isLeftToRight(); 132 133 if (resizingColumn != null) { 134 int oldWidth = resizingColumn.getWidth(); 135 int newWidth; 136 if (headerLeftToRight) { 137 newWidth = mouseX - mouseXOffset; 138 } else { 139 newWidth = mouseXOffset - mouseX; 140 } 141 resizingColumn.setWidth(newWidth); 142 143 Container container; 144 if ((header.getParent() == null) || 145 ((container = header.getParent().getParent()) == null) || 146 !(container instanceof JScrollPane)) { 147 return; 148 } 149 150 if (!container.getComponentOrientation().isLeftToRight() && 151 !headerLeftToRight) { 152 JTable table = header.getTable(); 153 if (table != null) { 154 JViewport viewport = ((JScrollPane)container).getViewport(); 155 int viewportWidth = viewport.getWidth(); 156 int diff = newWidth - oldWidth; 157 int newHeaderWidth = table.getWidth() + diff; 158 159 160 Dimension tableSize = table.getSize(); 161 tableSize.width += diff; 162 table.setSize(tableSize); 163 164 168 if ((newHeaderWidth >= viewportWidth) && 169 (table.getAutoResizeMode() == JTable.AUTO_RESIZE_OFF)) { 170 Point p = viewport.getViewPosition(); 171 p.x = Math.max(0, Math.min(newHeaderWidth - viewportWidth, p.x + diff)); 172 viewport.setViewPosition(p); 173 174 175 mouseXOffset += diff; 176 } 177 } 178 } 179 } 180 else if (draggedColumn != null) { 181 TableColumnModel cm = header.getColumnModel(); 182 int draggedDistance = mouseX - mouseXOffset; 183 int direction = (draggedDistance < 0) ? -1 : 1; 184 int columnIndex = viewIndexForColumn(draggedColumn); 185 int newColumnIndex = columnIndex + (headerLeftToRight ? direction : -direction); 186 if (0 <= newColumnIndex && newColumnIndex < cm.getColumnCount()) { 187 int width = cm.getColumn(newColumnIndex).getWidth(); 188 if (Math.abs(draggedDistance) > (width / 2)) { 189 mouseXOffset = mouseXOffset + direction * width; 190 header.setDraggedDistance(draggedDistance - direction * width); 191 cm.moveColumn(columnIndex, newColumnIndex); 192 return; 193 } 194 } 195 setDraggedDistance(draggedDistance, columnIndex); 196 } 197 } 198 199 public void mouseReleased(MouseEvent e) { 200 setDraggedDistance(0, viewIndexForColumn(header.getDraggedColumn())); 201 202 header.setResizingColumn(null); 203 header.setDraggedColumn(null); 204 } 205 206 public void mouseEntered(MouseEvent e) {} 207 208 public void mouseExited(MouseEvent e) {} 209 213 private void setDraggedDistance(int draggedDistance, int column) { 214 header.setDraggedDistance(draggedDistance); 215 if (column != -1) { 216 header.getColumnModel().moveColumn(column, column); 217 } 218 } 219 } 220 221 225 228 protected MouseInputListener createMouseInputListener() { 229 return new MouseInputHandler(); 230 } 231 232 236 public static ComponentUI createUI(JComponent h) { 237 return new BasicTableHeaderUI (); 238 } 239 240 242 public void installUI(JComponent c) { 243 header = (JTableHeader)c; 244 245 rendererPane = new CellRendererPane(); 246 header.add(rendererPane); 247 248 installDefaults(); 249 installListeners(); 250 installKeyboardActions(); 251 } 252 253 261 protected void installDefaults() { 262 LookAndFeel.installColorsAndFont(header, "TableHeader.background", 263 "TableHeader.foreground", "TableHeader.font"); 264 LookAndFeel.installProperty(header, "opaque", Boolean.TRUE); 265 } 266 267 270 protected void installListeners() { 271 mouseInputListener = createMouseInputListener(); 272 273 header.addMouseListener(mouseInputListener); 274 header.addMouseMotionListener(mouseInputListener); 275 } 276 277 280 protected void installKeyboardActions() { } 281 282 284 public void uninstallUI(JComponent c) { 285 uninstallDefaults(); 286 uninstallListeners(); 287 uninstallKeyboardActions(); 288 289 header.remove(rendererPane); 290 rendererPane = null; 291 header = null; 292 } 293 294 protected void uninstallDefaults() {} 295 296 protected void uninstallListeners() { 297 header.removeMouseListener(mouseInputListener); 298 header.removeMouseMotionListener(mouseInputListener); 299 300 mouseInputListener = null; 301 } 302 303 protected void uninstallKeyboardActions() {} 304 305 309 public void paint(Graphics g, JComponent c) { 310 if (header.getColumnModel().getColumnCount() <= 0) { 311 return; 312 } 313 boolean ltr = header.getComponentOrientation().isLeftToRight(); 314 315 Rectangle clip = g.getClipBounds(); 316 Point left = clip.getLocation(); 317 Point right = new Point( clip.x + clip.width - 1, clip.y ); 318 TableColumnModel cm = header.getColumnModel(); 319 int cMin = header.columnAtPoint( ltr ? left : right ); 320 int cMax = header.columnAtPoint( ltr ? right : left ); 321 if (cMin == -1) { 323 cMin = 0; 324 } 325 if (cMax == -1) { 328 cMax = cm.getColumnCount()-1; 329 } 330 331 TableColumn draggedColumn = header.getDraggedColumn(); 332 int columnWidth; 333 Rectangle cellRect = header.getHeaderRect(ltr ? cMin : cMax); 334 TableColumn aColumn; 335 if (ltr) { 336 for(int column = cMin; column <= cMax ; column++) { 337 aColumn = cm.getColumn(column); 338 columnWidth = aColumn.getWidth(); 339 cellRect.width = columnWidth; 340 if (aColumn != draggedColumn) { 341 paintCell(g, cellRect, column); 342 } 343 cellRect.x += columnWidth; 344 } 345 } else { 346 for(int column = cMax; column >= cMin; column--) { 347 aColumn = cm.getColumn(column); 348 columnWidth = aColumn.getWidth(); 349 cellRect.width = columnWidth; 350 if (aColumn != draggedColumn) { 351 paintCell(g, cellRect, column); 352 } 353 cellRect.x += columnWidth; 354 } 355 } 356 357 if (draggedColumn != null) { 359 int draggedColumnIndex = viewIndexForColumn(draggedColumn); 360 Rectangle draggedCellRect = header.getHeaderRect(draggedColumnIndex); 361 362 g.setColor(header.getParent().getBackground()); 364 g.fillRect(draggedCellRect.x, draggedCellRect.y, 365 draggedCellRect.width, draggedCellRect.height); 366 367 draggedCellRect.x += header.getDraggedDistance(); 368 369 g.setColor(header.getBackground()); 371 g.fillRect(draggedCellRect.x, draggedCellRect.y, 372 draggedCellRect.width, draggedCellRect.height); 373 374 paintCell(g, draggedCellRect, draggedColumnIndex); 375 } 376 377 rendererPane.removeAll(); 379 } 380 381 private Component getHeaderRenderer(int columnIndex) { 382 TableColumn aColumn = header.getColumnModel().getColumn(columnIndex); 383 TableCellRenderer renderer = aColumn.getHeaderRenderer(); 384 if (renderer == null) { 385 renderer = header.getDefaultRenderer(); 386 } 387 return renderer.getTableCellRendererComponent(header.getTable(), 388 aColumn.getHeaderValue(), false, false, 389 -1, columnIndex); 390 } 391 392 private void paintCell(Graphics g, Rectangle cellRect, int columnIndex) { 393 Component component = getHeaderRenderer(columnIndex); 394 rendererPane.paintComponent(g, component, header, cellRect.x, cellRect.y, 395 cellRect.width, cellRect.height, true); 396 } 397 398 private int viewIndexForColumn(TableColumn aColumn) { 399 TableColumnModel cm = header.getColumnModel(); 400 for (int column = 0; column < cm.getColumnCount(); column++) { 401 if (cm.getColumn(column) == aColumn) { 402 return column; 403 } 404 } 405 return -1; 406 } 407 408 412 private int getHeaderHeight() { 413 int height = 0; 414 boolean accomodatedDefault = false; 415 TableColumnModel columnModel = header.getColumnModel(); 416 for(int column = 0; column < columnModel.getColumnCount(); column++) { 417 TableColumn aColumn = columnModel.getColumn(column); 418 if (aColumn.getHeaderRenderer() != null || !accomodatedDefault) { 421 Component comp = getHeaderRenderer(column); 422 int rendererHeight = comp.getPreferredSize().height; 423 height = Math.max(height, rendererHeight); 424 if (rendererHeight > 0) { 434 accomodatedDefault = true; 435 } 436 } 437 } 438 return height; 439 } 440 441 private Dimension createHeaderSize(long width) { 442 TableColumnModel columnModel = header.getColumnModel(); 443 if (width > Integer.MAX_VALUE) { 445 width = Integer.MAX_VALUE; 446 } 447 return new Dimension((int)width, getHeaderHeight()); 448 } 449 450 451 455 public Dimension getMinimumSize(JComponent c) { 456 long width = 0; 457 Enumeration enumeration = header.getColumnModel().getColumns(); 458 while (enumeration.hasMoreElements()) { 459 TableColumn aColumn = (TableColumn)enumeration.nextElement(); 460 width = width + aColumn.getMinWidth(); 461 } 462 return createHeaderSize(width); 463 } 464 465 471 public Dimension getPreferredSize(JComponent c) { 472 long width = 0; 473 Enumeration enumeration = header.getColumnModel().getColumns(); 474 while (enumeration.hasMoreElements()) { 475 TableColumn aColumn = (TableColumn)enumeration.nextElement(); 476 width = width + aColumn.getPreferredWidth(); 477 } 478 return createHeaderSize(width); 479 } 480 481 485 public Dimension getMaximumSize(JComponent c) { 486 long width = 0; 487 Enumeration enumeration = header.getColumnModel().getColumns(); 488 while (enumeration.hasMoreElements()) { 489 TableColumn aColumn = (TableColumn)enumeration.nextElement(); 490 width = width + aColumn.getMaxWidth(); 491 } 492 return createHeaderSize(width); 493 } 494 495 } 497 498 | Popular Tags |