1 30 package com.genimen.djeneric.ui; 31 32 import java.awt.Component ; 33 import java.awt.event.ActionEvent ; 34 import java.awt.event.ActionListener ; 35 import java.awt.event.FocusEvent ; 36 import java.awt.event.FocusListener ; 37 import java.awt.event.KeyEvent ; 38 import java.awt.event.KeyListener ; 39 40 import javax.swing.AbstractAction ; 41 import javax.swing.CellEditor ; 42 import javax.swing.ComboBoxModel ; 43 import javax.swing.JCheckBox ; 44 import javax.swing.JComboBox ; 45 import javax.swing.JComponent ; 46 import javax.swing.JTable ; 47 import javax.swing.JTextField ; 48 import javax.swing.KeyStroke ; 49 import javax.swing.ListSelectionModel ; 50 import javax.swing.event.ChangeEvent ; 51 import javax.swing.event.TableModelEvent ; 52 import javax.swing.table.DefaultTableCellRenderer ; 53 import javax.swing.table.JTableHeader ; 54 import javax.swing.table.TableCellEditor ; 55 import javax.swing.table.TableCellRenderer ; 56 import javax.swing.table.TableColumn ; 57 import javax.swing.table.TableModel ; 58 59 import com.genimen.djeneric.language.Messages; 60 import com.genimen.djeneric.repository.exceptions.DjenericException; 61 import com.genimen.djeneric.tools.specifier.components.DjChooserField; 62 import com.genimen.djeneric.util.DjLogger; 63 64 public class DjTable extends JTable implements FocusListener 65 { 66 private static final long serialVersionUID = 1L; 67 protected CancelEditAction cea = new CancelEditAction(this); 68 protected TabAction tab = new TabAction(this, true); 69 protected TabAction prevTab = new TabAction(this, false); 70 protected ComboboxAction comboEnter = new ComboboxAction(this); 71 72 static boolean _onJdk13 = System.getProperty("java.specification.version").startsWith("1.3"); 73 74 public DjTable() 75 { 76 setAutoCreateColumnsFromModel(false); 77 setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 78 JTableHeader header = getTableHeader(); 79 header.setUpdateTableInRealTime(false); 80 setAutoResizeMode(JTable.AUTO_RESIZE_OFF); 81 82 registerKeyboardAction(new DeleteRowAction(this), 83 KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, ActionEvent.CTRL_MASK), JComponent.WHEN_FOCUSED); 84 registerKeyboardAction(new InsertRowAction(this), 85 KeyStroke.getKeyStroke(KeyEvent.VK_INSERT, ActionEvent.CTRL_MASK), JComponent.WHEN_FOCUSED); 86 unregisterKeyboardAction(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0)); 87 ActionListener act = getActionForKeyStroke(KeyStroke.getKeyStroke(KeyEvent.VK_F2, 0)); 88 registerKeyboardAction(act, KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), JComponent.WHEN_FOCUSED); 89 90 if (!_onJdk13) 91 { 92 setRowHeight(19); 93 } 94 95 } 96 97 public boolean shouldIgnoreKey(int keyCode) 98 { 99 switch (keyCode) 100 { 101 case KeyEvent.VK_F1 : 102 case KeyEvent.VK_F2 : 103 case KeyEvent.VK_F3 : 104 case KeyEvent.VK_F4 : 105 case KeyEvent.VK_F5 : 106 case KeyEvent.VK_F6 : 107 case KeyEvent.VK_F7 : 108 case KeyEvent.VK_F8 : 109 case KeyEvent.VK_F9 : 110 case KeyEvent.VK_F10 : 111 case KeyEvent.VK_F11 : 112 case KeyEvent.VK_F12 : 113 case KeyEvent.VK_F13 : 114 case KeyEvent.VK_F14 : 115 case KeyEvent.VK_F15 : 116 case KeyEvent.VK_F16 : 117 case KeyEvent.VK_F17 : 118 case KeyEvent.VK_F18 : 119 case KeyEvent.VK_F19 : 120 case KeyEvent.VK_F20 : 121 case KeyEvent.VK_F21 : 122 case KeyEvent.VK_F22 : 123 case KeyEvent.VK_F23 : 124 case KeyEvent.VK_F24 : 125 case KeyEvent.VK_PRINTSCREEN : 126 case KeyEvent.VK_SCROLL_LOCK : 127 case KeyEvent.VK_CAPS_LOCK : 128 case KeyEvent.VK_NUM_LOCK : 129 case KeyEvent.VK_PAUSE : 130 131 case KeyEvent.VK_FINAL : 132 case KeyEvent.VK_CONVERT : 133 case KeyEvent.VK_NONCONVERT : 134 case KeyEvent.VK_ACCEPT : 135 case KeyEvent.VK_MODECHANGE : 136 case KeyEvent.VK_KANA : 137 case KeyEvent.VK_KANJI : 138 case KeyEvent.VK_ALPHANUMERIC : 139 case KeyEvent.VK_KATAKANA : 140 case KeyEvent.VK_HIRAGANA : 141 case KeyEvent.VK_FULL_WIDTH : 142 case KeyEvent.VK_HALF_WIDTH : 143 case KeyEvent.VK_ROMAN_CHARACTERS : 144 case KeyEvent.VK_ALL_CANDIDATES : 145 case KeyEvent.VK_PREVIOUS_CANDIDATE : 146 case KeyEvent.VK_CODE_INPUT : 147 case KeyEvent.VK_JAPANESE_KATAKANA : 148 case KeyEvent.VK_JAPANESE_HIRAGANA : 149 case KeyEvent.VK_JAPANESE_ROMAN : 150 case KeyEvent.VK_KANA_LOCK : 151 case KeyEvent.VK_INPUT_METHOD_ON_OFF : 152 153 case KeyEvent.VK_AGAIN : 154 case KeyEvent.VK_UNDO : 155 case KeyEvent.VK_COPY : 156 case KeyEvent.VK_PASTE : 157 case KeyEvent.VK_CUT : 158 case KeyEvent.VK_FIND : 159 case KeyEvent.VK_PROPS : 160 case KeyEvent.VK_STOP : 161 162 case KeyEvent.VK_HELP : 163 return true; 164 } 165 return false; 166 } 167 168 protected boolean processKeyBinding(KeyStroke ks, KeyEvent e, int condition, boolean pressed) 171 { 172 boolean wasEditing = isEditing(); 173 174 if (shouldIgnoreKey(e.getKeyCode())) return false; 175 176 boolean result = super.processKeyBinding(ks, e, condition, pressed); 177 if (!wasEditing && isEditing() && getEditorComponent() instanceof JComboBox ) 180 { 181 JComboBox cbb = (JComboBox ) getEditorComponent(); 182 if (cbb.isEditable() && (e.getKeyCode() == KeyEvent.VK_BACK_SPACE || e.getKeyCode() == KeyEvent.VK_DELETE)) 183 { 184 cbb.getEditor().setItem(""); 185 } 186 else if (cbb.isEditable() && !e.isActionKey() && e.getKeyChar() != '\n') 187 { 188 cbb.getEditor().setItem("" + e.getKeyChar()); 189 result = true; 190 } 191 else 192 { 193 if (!_onJdk13) cbb.requestFocus(); 195 ComboBoxModel model = cbb.getModel(); 196 for (int i = 0; i < model.getSize(); i++) 197 { 198 String matchChar = String.valueOf(e.getKeyChar()).toUpperCase(); 199 if (model.getElementAt(i).toString().toUpperCase().startsWith(matchChar)) 200 { 201 cbb.setSelectedIndex(i); 202 } 203 } 204 } 205 } 206 else if (!wasEditing && isEditing() && getEditorComponent() instanceof DjChooserField && e.getKeyChar() != '\n') 207 { 208 DjChooserField fld = (DjChooserField) getEditorComponent(); 209 fld.showChooseDialog(new ActionEvent (this, 0, "")); 210 } 211 return result; 212 } 213 214 public void setModel(TableModel model) 215 { 216 super.setModel(model); 217 218 if (!(model instanceof DjTableModel)) return; 219 220 try 221 { 222 DjTableModel htm = (DjTableModel) model; 223 224 while (getColumnCount() > 0) 226 removeColumn(getColumnModel().getColumn(0)); 227 228 for (int k = 0; k < htm.getColumnCount(); k++) 229 { 230 TableCellRenderer renderer = htm.getColumnRenderer(k); 231 232 if (renderer == null) 233 { 234 renderer = new DefaultTableCellRenderer (); 235 } 236 237 TableCellEditor editor = htm.getColumnEditor(k); 238 239 if (editor == null) 240 { 241 editor = new DjCellEditor(new JTextField ()); 242 } 243 244 TableColumn column = new TableColumn (k, htm.getColumnWidth(k), renderer, editor); 245 addColumn(column); 246 } 247 248 } 249 catch (Exception x) 250 { 251 DjLogger.log(x); 252 } 253 } 254 255 public void scrollToSelection() 256 { 257 int row = getSelectedRow(); 258 int col = getSelectedColumn(); 259 260 if (col == -1 || row == -1) return; 261 262 addColumnSelectionInterval(col, col); 263 addRowSelectionInterval(row, row); 264 scrollRectToVisible(getCellRect(row, col, false)); 265 } 266 267 public int insertRow() throws DjenericException 268 { 269 DjTableModel model = (DjTableModel) getModel(); 270 271 if (!model.isInsertable()) 272 { 273 String msg = Messages.getString("DjTable.CreationNotAllowed"); 274 model.setStatusMessage(msg, false); 275 throw new DjenericException(msg); 276 } 277 278 int row = getSelectedRow(); 279 int newRow = model.insertRow(row + 1); 280 if (newRow != -1) 281 { 282 tableChanged(new TableModelEvent (model, newRow, newRow, TableModelEvent.ALL_COLUMNS, TableModelEvent.INSERT)); 283 setRowSelectionInterval(newRow, newRow); 284 setColumnSelectionInterval(0, 0); 285 scrollToSelection(); 286 } 287 return newRow; 288 } 289 290 public boolean deleteRow() throws DjenericException 291 { 292 int row = getSelectedRow(); 293 if (row < 0 || getModel().getRowCount() == 0) return false; 294 295 DjTableModel model = (DjTableModel) getModel(); 296 if (!model.isDeleteable()) 297 { 298 String msg = Messages.getString("DjTable.DeletionNotAllowed"); 299 model.setStatusMessage(msg, false); 300 throw new DjenericException(msg); 301 } 302 303 boolean wasDeleted = model.deleteRow(row); 304 if (wasDeleted) 305 { 306 tableChanged(new TableModelEvent (model, row, row, TableModelEvent.ALL_COLUMNS, TableModelEvent.DELETE)); 307 if (row > model.getRowCount() - 1) row--; 308 if (row >= 0 && row < model.getRowCount()) setRowSelectionInterval(row, row); 309 scrollToSelection(); 310 repaint(); 311 } 312 return wasDeleted; 313 } 314 315 private Object _orgValue = null; 316 public int _atRow, _atCol; 317 318 public Component prepareEditor(TableCellEditor editor, int row, int column) 319 { 320 Component c = super.prepareEditor(editor, row, column); 321 322 _orgValue = getModel().getValueAt(row, column); 323 324 _atRow = row; 325 _atCol = column; 326 327 if (c != null) 328 { 329 if (c instanceof JCheckBox ) 330 { 331 JCheckBox jc = (JCheckBox ) c; 332 jc.unregisterKeyboardAction(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0)); 333 jc.registerKeyboardAction(tab, KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), JComponent.WHEN_FOCUSED); 334 } 335 else if (c instanceof JTextField ) 336 { 337 JTextField jc = (JTextField ) c; 338 jc.selectAll(); 340 341 jc.removeFocusListener(this); 342 jc.addFocusListener(this); 343 344 jc.unregisterKeyboardAction(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0)); 345 jc.registerKeyboardAction(cea, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_FOCUSED); 346 347 jc.unregisterKeyboardAction(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0)); 348 jc.registerKeyboardAction(tab, KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), JComponent.WHEN_FOCUSED); 349 new DjFocusMeLater(jc); 350 } 351 else if (c instanceof DjChooserField) 352 { 353 DjChooserField jc = (DjChooserField) c; 354 356 jc.getDisplayField().unregisterKeyboardAction(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0)); 357 jc.getDisplayField().registerKeyboardAction(cea, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), 358 JComponent.WHEN_FOCUSED); 359 360 jc.getDisplayField().unregisterKeyboardAction(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0)); 361 jc.getDisplayField().registerKeyboardAction(tab, KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), 362 JComponent.WHEN_FOCUSED); 363 364 jc.getEditor().unregisterKeyboardAction(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0)); 365 jc.getEditor().registerKeyboardAction(cea, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), 366 JComponent.WHEN_FOCUSED); 367 368 jc.getEditor().unregisterKeyboardAction(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0)); 369 jc.getEditor().registerKeyboardAction(tab, KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), 370 JComponent.WHEN_FOCUSED); 371 new DjFocusMeLater(jc.getDisplayField()); 372 } 373 else if (c instanceof JComboBox ) 374 { 375 JComboBox cbb = (JComboBox ) c; 376 377 cbb.setFont(new java.awt.Font ("Dialog", 0, 12)); 378 JComponent jc = (JComponent ) c; 379 381 Component real = DjFocusMeLater.getNeededComponent(jc); 382 if (real instanceof JComponent ) 383 { 384 jc = (JComponent ) real; 385 386 jc.removeFocusListener(this); 387 jc.addFocusListener(this); 388 389 if (jc != cbb && !cbb.isEditable() && !_onJdk13) 391 { 392 cbb.removeFocusListener(this); 393 cbb.addFocusListener(this); 394 } 395 396 jc.unregisterKeyboardAction(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0)); 397 jc.registerKeyboardAction(cea, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_FOCUSED); 398 399 jc.unregisterKeyboardAction(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0)); 400 jc.registerKeyboardAction(tab, KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), JComponent.WHEN_FOCUSED); 401 402 jc.unregisterKeyboardAction(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0)); 403 jc.registerKeyboardAction(tab, KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0), JComponent.WHEN_FOCUSED); 404 405 jc.unregisterKeyboardAction(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, java.awt.event.InputEvent.SHIFT_MASK)); 406 jc.registerKeyboardAction(prevTab, KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 407 java.awt.event.InputEvent.SHIFT_MASK), 408 JComponent.WHEN_FOCUSED); 409 } 410 if (!cbb.isEditable()) 411 { 412 cbb.removeKeyListener(comboEnter); 413 cbb.addKeyListener(comboEnter); 414 } 415 new DjFocusMeLater(jc); 416 } 417 } 418 return c; 419 } 420 421 public void cancelCellEditing() 422 { 423 editingCanceled(null); 424 getModel().setValueAt(_orgValue, _atRow, _atCol); 425 } 426 427 public void nextCell() 428 { 429 int col = getSelectedColumn(); 430 int row = getSelectedRow(); 431 if (col < getColumnCount() - 1) col++; 432 else 433 { 434 col = 0; 435 if (row < getRowCount() - 1) row++; 436 } 437 438 addColumnSelectionInterval(col, col); 439 addRowSelectionInterval(row, row); 440 scrollRectToVisible(getCellRect(row, col, false)); 441 } 442 443 public void prevCell() 444 { 445 int col = getSelectedColumn(); 446 int row = getSelectedRow(); 447 if (col > 0) col--; 448 else 449 { 450 col = getColumnCount() - 1; 451 if (row > 0) row--; 452 } 453 454 addColumnSelectionInterval(col, col); 455 addRowSelectionInterval(row, row); 456 scrollRectToVisible(getCellRect(row, col, false)); 457 } 458 459 private boolean _busyLosingFocus = false; 461 462 public void focusLost(FocusEvent fe) 463 { 464 if (_busyLosingFocus) return; 465 _busyLosingFocus = true; 466 try 467 { 468 if (isEditing()) 469 { 470 editingStopped(null); 472 } 473 } 474 finally 475 { 476 _busyLosingFocus = false; 477 } 478 } 479 480 public void editingStopped(ChangeEvent e) 481 { 482 super.editingStopped(e); 483 new DjFocusMeLater(this); 484 } 486 487 public void focusGained(FocusEvent fe) 489 { 490 } 491 492 private class CancelEditAction extends AbstractAction 493 { 494 private static final long serialVersionUID = 1L; 495 DjTable _table; 496 497 private CancelEditAction(DjTable t) 498 { 499 super("cancel-edit"); 500 _table = t; 501 } 502 503 public void actionPerformed(ActionEvent e) 504 { 505 _table.cancelCellEditing(); 506 _table.requestFocus(); 507 } 508 } 509 510 private class TabAction extends AbstractAction 511 { 512 private static final long serialVersionUID = 1L; 513 DjTable _table; 514 boolean _doNext; 515 516 private TabAction(DjTable t, boolean doNext) 517 { 518 super("tab-edit"); 519 _table = t; 520 _doNext = doNext; 521 } 522 523 public void actionPerformed(ActionEvent e) 524 { 525 if (_table.getCellEditor() instanceof DjCellEditor) 526 { 527 DjCellEditor b = (DjCellEditor) _table.getCellEditor(); 528 if (b.getComponent() instanceof JComboBox ) 529 { 530 JComboBox cbb = (JComboBox ) b.getComponent(); 531 if (!cbb.isEditable() && cbb.isPopupVisible()) return; 532 } 533 } 534 535 CellEditor editor = _table.getCellEditor(); 536 if (editor != null) editor.stopCellEditing(); 537 538 if (_doNext) _table.nextCell(); 539 else _table.prevCell(); 540 541 _table.requestFocus(); 542 } 543 } 544 545 private class ComboboxAction implements KeyListener 546 { 547 DjTable _table; 548 549 public ComboboxAction(DjTable t) 550 { 551 _table = t; 552 } 553 554 public void keyPressed(KeyEvent e) 555 { 556 if (e.getKeyCode() == KeyEvent.VK_ENTER) 557 { 558 e.consume(); 559 CellEditor editor = _table.getCellEditor(); 560 if (editor != null) editor.stopCellEditing(); 561 562 _table.nextCell(); 563 _table.requestFocus(); 564 } 565 } 566 567 public void keyReleased(KeyEvent e) 568 { 569 570 } 571 572 public void keyTyped(KeyEvent e) 573 { 574 } 575 576 } 577 } 578 579 class DeleteRowAction extends AbstractAction 580 { 581 private static final long serialVersionUID = 1L; 582 583 DjTable _tab; 584 585 public DeleteRowAction(DjTable tab) 586 { 587 super("DeleteRowAction"); 588 _tab = tab; 589 } 590 591 public void actionPerformed(ActionEvent e) 592 { 593 try 594 { 595 _tab.deleteRow(); 596 } 597 catch (Exception x) 598 { 599 DjTableModel model = (DjTableModel) _tab.getModel(); 600 model.setStatusMessage(x); 601 } 602 } 603 } 604 605 class InsertRowAction extends AbstractAction 606 { 607 private static final long serialVersionUID = 1L; 608 609 DjTable _tab; 610 611 public InsertRowAction(DjTable tab) 612 { 613 super("InsertRowAction"); 614 _tab = tab; 615 } 616 617 public void actionPerformed(ActionEvent e) 618 { 619 try 620 { 621 _tab.insertRow(); 622 } 623 catch (Exception x) 624 { 625 DjTableModel model = (DjTableModel) _tab.getModel(); 626 model.setStatusMessage(x.getMessage(), false); 627 } 628 } 629 } | Popular Tags |