1 19 20 package org.netbeans.modules.xml.multiview.ui; 21 22 import java.awt.event.ActionEvent ; 23 import java.awt.event.ActionListener ; 24 import org.netbeans.modules.xml.multiview.Error; 25 import org.netbeans.modules.xml.multiview.Refreshable; 26 import org.netbeans.modules.xml.multiview.Utils; 27 import org.netbeans.modules.xml.multiview.cookies.ErrorLocator; 28 import org.netbeans.modules.xml.multiview.cookies.LinkCookie; 29 import org.openide.util.RequestProcessor; 30 31 import javax.swing.*; 32 import javax.swing.text.JTextComponent ; 33 import java.awt.*; 34 import java.awt.event.FocusEvent ; 35 import java.awt.event.FocusListener ; 36 import java.util.Iterator ; 37 import java.util.LinkedList ; 38 39 48 public abstract class SectionInnerPanel extends javax.swing.JPanel implements LinkCookie, ErrorLocator { 49 private SectionView sectionView; 50 private java.util.List refreshableList = new LinkedList (); 51 52 private boolean localFocusListenerInitialized = false; 53 private FocusListener localFocusListener = new FocusListener () { 54 public void focusGained(FocusEvent evt) { 55 final FocusListener [] focusListeners = getFocusListeners(); 56 for (int i = 0; i < focusListeners.length; i++) { 57 focusListeners[i].focusGained(evt); 58 } 59 } 60 61 public void focusLost(FocusEvent evt) { 62 processFocusEvent(evt); 63 } 64 }; 65 66 private RequestProcessor.Task refreshTask = RequestProcessor.getDefault().create(new Runnable () { 67 public void run() { 68 refreshView(); 69 } 70 }); 71 72 private static final int REFRESH_DELAY = 50; 73 private FlushFocusListener activeListener = null; 74 private boolean closing = false; 75 76 79 public SectionInnerPanel(SectionView sectionView) { 80 this.sectionView = sectionView; 81 } 82 83 public synchronized void addFocusListener(FocusListener l) { 84 super.addFocusListener(l); 85 if (!localFocusListenerInitialized) { 86 localFocusListenerInitialized = true; 87 Container container = this; 88 FocusListener focusListener = localFocusListener; 89 addFocusListenerRecursively(container, focusListener); 90 } 91 } 92 93 private void addFocusListenerRecursively(Container container, FocusListener focusListener) { 94 final Component [] components = container.getComponents(); 95 for (int i = 0; i < components.length; i++) { 96 Component component = components[i]; 97 if (component.isFocusable() && !(component instanceof JLabel)) { 98 component.addFocusListener(focusListener); 99 } 100 if (component instanceof Container) { 101 if (!(component instanceof SectionNodePanel)) { 102 addFocusListenerRecursively((Container) component, focusListener); 103 } 104 } 105 } 106 } 107 108 111 public SectionView getSectionView() { 112 return sectionView; 113 } 114 115 123 public abstract void setValue(JComponent source, Object value); 124 125 130 public void documentChanged(javax.swing.text.JTextComponent source, String value) { 131 } 132 133 137 public void rollbackValue(javax.swing.text.JTextComponent source) { 138 } 139 140 144 public final void addModifier(final JTextComponent tc) { 145 tc.addFocusListener(new ModifyFocusListener(tc)); 146 } 147 148 154 public final void addModifier(final JTextComponent tc, boolean test) { 155 tc.addFocusListener(new ModifyFocusListener(tc, test)); 156 } 157 158 163 public final void addModifier(final JComboBox comboBox) { 164 comboBox.addFocusListener(new ComboBoxModifyFocusListener(comboBox)); 165 } 166 167 174 public final void addModifier(final JComboBox comboBox, boolean test) { 175 comboBox.addFocusListener(new ComboBoxModifyFocusListener(comboBox, test)); 176 } 177 178 179 184 public final void addModifier(final JRadioButton radioButton){ 185 radioButton.addFocusListener(new RadioButtonModifyFocusListener(radioButton)); 186 } 187 188 193 public final void addModifier(final JCheckBox checkBox){ 194 checkBox.addFocusListener(new CheckBoxModifyFocusListener(checkBox)); 195 } 196 197 206 public final void addImmediateModifier(final JCheckBox checkBox){ 207 checkBox.addActionListener(new CheckBoxActionListener(checkBox)); 208 } 209 210 219 public final void addImmediateModifier(final JRadioButton radioButton){ 220 radioButton.addActionListener(new RadioButtonActionListener(radioButton)); 221 } 222 223 232 public final void addImmediateModifier(final JComboBox comboBox) { 233 comboBox.addActionListener(new ComboBoxActionListener(comboBox)); 234 } 235 236 244 public final void addImmediateModifier(final JTextComponent tc) { 245 tc.getDocument().addDocumentListener(new TextListener(tc, true)); 246 } 247 248 253 public final void addValidatee(final JTextComponent tc) { 254 tc.getDocument().addDocumentListener(new TextListener(tc)); 255 tc.addFocusListener(new ValidateFocusListener(tc)); 256 } 257 258 protected void scheduleRefreshView() { 259 refreshTask.schedule(REFRESH_DELAY); 260 } 261 262 265 public void refreshView() { 266 for (Iterator it = refreshableList.iterator(); it.hasNext();) { 267 ((Refreshable) it.next()).refresh(); 268 } 269 } 270 271 protected void addRefreshable(Refreshable refreshable) { 272 refreshableList.add(refreshable); 273 } 274 275 public void dataModelPropertyChange(Object source, String propertyName, Object oldValue, Object newValue) { 276 scheduleRefreshView(); 277 } 278 279 private class TextListener implements javax.swing.event.DocumentListener { 280 281 private JTextComponent tc; 282 private boolean setValue = false; 283 284 TextListener(JTextComponent tc) { 285 this(tc, false); 286 } 287 288 TextListener(JTextComponent tc, boolean setValue) { 289 this.tc = tc; 290 this.setValue = setValue; 291 } 292 293 296 public void changedUpdate(javax.swing.event.DocumentEvent evt) { 297 update(evt); 298 } 299 300 303 public void insertUpdate(javax.swing.event.DocumentEvent evt) { 304 update(evt); 305 } 306 307 310 public void removeUpdate(javax.swing.event.DocumentEvent evt) { 311 update(evt); 312 } 313 314 private void update(javax.swing.event.DocumentEvent evt) { 315 if (setValue){ 316 startUIChange(); 317 setValue(tc, tc.getText()); 318 signalUIChange(); 319 endUIChange(); 320 } else { 321 documentChanged(tc, tc.getText()); 322 } 323 } 324 } 325 326 327 private abstract class FlushFocusListener extends java.awt.event.FocusAdapter { 328 public abstract boolean flushData(); 329 } 330 331 private class ValidateFocusListener extends FlushFocusListener { 332 private String orgValue; 333 private boolean viewIsBuggy; 334 private final JTextComponent tc; 335 338 private boolean disable; 339 340 public ValidateFocusListener(JTextComponent tc) { 341 this.tc = tc; 342 } 343 344 public void focusGained(FocusEvent evt) { 345 activeListener = this; 346 orgValue = tc.getText(); 347 if (sectionView.getErrorPanel().getError() != null) { 348 viewIsBuggy = true; 349 } else { 350 viewIsBuggy = false; 351 } 352 } 353 354 public void focusLost(FocusEvent evt) { 355 if (!closing) { 356 if (!flushData()) { 357 Utils.runInAwtDispatchThread(new Runnable () { 358 public void run() { 359 tc.requestFocus(); 361 } 362 }); 363 } else { 364 disable = false; 365 activeListener = null; 366 } 367 } 368 } 369 370 public boolean flushData() { 371 Error error = sectionView.getErrorPanel().getError(); 372 if (error != null && error.isEditError() && tc == error.getFocusableComponent()) { 373 if (Error.TYPE_WARNING == error.getSeverityLevel() && !disable) { 374 org.openide.DialogDescriptor desc = new RefreshSaveDialog(sectionView.getErrorPanel()); 375 Dialog dialog = org.openide.DialogDisplayer.getDefault().createDialog(desc); 376 dialog.show(); 377 Integer opt = (Integer ) desc.getValue(); 378 if (opt.equals(RefreshSaveDialog.OPTION_FIX)) { 379 disable = true; 380 return false; 381 } else if (opt.equals(RefreshSaveDialog.OPTION_REFRESH)) { 382 rollbackValue(tc); 383 sectionView.checkValidity(); 384 } else { 385 startUIChange(); 386 setValue(tc, tc.getText()); 387 signalUIChange(); 388 endUIChange(); 389 sectionView.checkValidity(); 390 } 391 } else if (!disable){ 392 org.openide.DialogDescriptor desc = new RefreshDialog(sectionView.getErrorPanel()); 393 Dialog dialog = org.openide.DialogDisplayer.getDefault().createDialog(desc); 394 dialog.show(); 395 Integer opt = (Integer ) desc.getValue(); 396 if (opt.equals(RefreshDialog.OPTION_FIX)) { 397 disable = true; 398 return false; 399 } else if (opt.equals(RefreshDialog.OPTION_REFRESH)) { 400 rollbackValue(tc); 401 sectionView.checkValidity(); 402 } 403 } 404 } else { 405 if (!tc.getText().equals(orgValue)) { 406 startUIChange(); 407 setValue(tc, tc.getText()); 408 signalUIChange(); 409 endUIChange(); 410 sectionView.checkValidity(); 411 } else { 412 if (viewIsBuggy) { 413 sectionView.checkValidity(); 414 } 415 } 416 } 417 disable = false; 418 return true; 419 } 420 } 421 422 private class ModifyFocusListener extends FlushFocusListener { 423 private String orgValue; 424 private final JTextComponent tc; 425 private boolean test; 427 428 public ModifyFocusListener(JTextComponent tc) { 429 this(tc, true); 430 } 431 432 public ModifyFocusListener(JTextComponent tc, boolean test) { 433 this.tc = tc; 434 this.test = test; 435 } 436 437 public void focusGained(FocusEvent evt) { 438 orgValue = tc.getText(); 439 activeListener = this; 440 } 441 442 public void focusLost(FocusEvent evt) { 443 if (!closing) { 444 flushData(); 445 activeListener = null; 446 } 447 } 448 449 public boolean flushData() { 450 if (!test || !tc.getText().equals(orgValue)) { 451 startUIChange(); 452 setValue(tc, tc.getText()); 453 signalUIChange(); 454 endUIChange(); 455 } 456 return true; 457 } 458 } 459 460 463 private class ComboBoxModifyFocusListener extends FlushFocusListener { 464 private Object orgValue; 465 private final JComboBox comboBox; 466 private boolean test; 468 469 public ComboBoxModifyFocusListener(JComboBox comboBox) { 470 this(comboBox, true); 471 } 472 473 public ComboBoxModifyFocusListener(JComboBox comboBox, boolean test) { 474 this.comboBox = comboBox; 475 this.test = test; 476 } 477 478 public void focusGained(FocusEvent evt) { 479 orgValue = comboBox.getSelectedItem(); 480 activeListener = this; 481 } 482 483 public void focusLost(FocusEvent evt) { 484 if (!closing) { 485 flushData(); 486 activeListener = null; 487 } 488 } 489 490 public boolean flushData() { 491 Object newValue = comboBox.getSelectedItem(); 492 boolean newEqualsOld = (newValue==null ? orgValue==null : newValue.equals(orgValue)); 493 if (!test || !newEqualsOld) { 494 startUIChange(); 495 setValue(comboBox, comboBox.getSelectedItem()); 496 signalUIChange(); 497 endUIChange(); 498 } 499 return true; 500 } 501 } 502 503 506 private class RadioButtonModifyFocusListener extends FlushFocusListener { 507 private boolean orgValue; 508 private final JRadioButton radioButton; 509 510 public RadioButtonModifyFocusListener(JRadioButton radioButton) { 511 this.radioButton = radioButton; 512 } 513 514 public void focusGained(FocusEvent evt) { 515 orgValue = radioButton.isSelected(); 516 activeListener = this; 517 } 518 519 public void focusLost(FocusEvent evt) { 520 if (!closing) { 521 flushData(); 522 activeListener = null; 523 } 524 } 525 526 public boolean flushData() { 527 if (!(radioButton.isSelected() == orgValue)) { 528 startUIChange(); 529 setValue(radioButton, Boolean.valueOf(radioButton.isSelected())); 530 signalUIChange(); 531 endUIChange(); 532 } 533 return true; 534 } 535 } 536 537 public boolean canClose() { 538 closing = true; 539 try { 540 if (activeListener != null) { 541 return activeListener.flushData(); 542 } 543 return true; 544 } finally { 545 closing = false; 546 } 547 } 548 549 553 private abstract class FlushActionListener implements ActionListener { 554 555 public final void actionPerformed(ActionEvent e) { 556 startUIChange(); 557 doSetValue(e); 558 signalUIChange(); 559 endUIChange(); 560 } 561 562 566 public abstract void doSetValue(ActionEvent e); 567 } 568 569 573 private class ComboBoxActionListener extends FlushActionListener{ 574 575 private final JComboBox comboBox; 576 577 public ComboBoxActionListener(JComboBox comboBox){ 578 this.comboBox = comboBox; 579 } 580 581 public void doSetValue(ActionEvent e) { 582 setValue(comboBox, comboBox.getSelectedItem()); 583 } 584 } 585 586 590 private class CheckBoxActionListener extends FlushActionListener{ 591 592 private final JCheckBox checkBox; 593 594 public CheckBoxActionListener(JCheckBox checkBox){ 595 this.checkBox = checkBox; 596 } 597 598 public void doSetValue(ActionEvent e) { 599 setValue(checkBox, Boolean.valueOf(checkBox.isSelected())); 600 } 601 } 602 603 607 private class RadioButtonActionListener extends FlushActionListener{ 608 609 private final JRadioButton radioButton; 610 611 public RadioButtonActionListener(JRadioButton radioButton){ 612 this.radioButton = radioButton; 613 } 614 615 public void doSetValue(ActionEvent e) { 616 setValue(radioButton, Boolean.valueOf(radioButton.isSelected())); 617 } 618 } 619 620 623 private class CheckBoxModifyFocusListener extends FlushFocusListener { 624 private boolean orgValue; 625 private final JCheckBox checkBox; 626 627 public CheckBoxModifyFocusListener(JCheckBox checkBox) { 628 this.checkBox = checkBox; 629 } 630 631 public void focusGained(FocusEvent evt) { 632 orgValue = checkBox.isSelected(); 633 activeListener = this; 634 } 635 636 public void focusLost(FocusEvent evt) { 637 if (!closing) { 638 flushData(); 639 activeListener = null; 640 } 641 } 642 643 public boolean flushData() { 644 if (!(checkBox.isSelected() == orgValue)) { 645 startUIChange(); 646 setValue(checkBox, Boolean.valueOf(checkBox.isSelected())); 647 signalUIChange(); 648 endUIChange(); 649 } 650 return true; 651 } 652 653 public boolean canClose() { 654 closing = true; 655 try { 656 if (activeListener != null) { 657 return activeListener.flushData(); 658 } 659 return true; 660 } finally { 661 closing = false; 662 } 663 } 664 665 } 666 667 670 protected void signalUIChange() { 671 } 672 673 675 protected void startUIChange() { 676 } 677 678 680 protected void endUIChange() { 681 } 682 683 } 684 | Popular Tags |