1 19 20 package org.openide.nodes; 21 22 import java.awt.Component ; 23 import java.awt.Container ; 24 import java.awt.Dimension ; 25 import java.awt.GridBagConstraints ; 26 import java.awt.GridBagLayout ; 27 import java.awt.Insets ; 28 import java.awt.Point ; 29 import java.awt.datatransfer.DataFlavor ; 30 import java.awt.datatransfer.Transferable ; 31 import java.awt.datatransfer.UnsupportedFlavorException ; 32 import java.awt.dnd.Autoscroll ; 33 import java.awt.dnd.DnDConstants ; 34 import java.awt.dnd.DragGestureEvent ; 35 import java.awt.dnd.DragGestureListener ; 36 import java.awt.dnd.DragSource ; 37 import java.awt.dnd.DragSourceDragEvent ; 38 import java.awt.dnd.DragSourceDropEvent ; 39 import java.awt.dnd.DragSourceEvent ; 40 import java.awt.dnd.DragSourceListener ; 41 import java.awt.dnd.DropTarget ; 42 import java.awt.dnd.DropTargetDragEvent ; 43 import java.awt.dnd.DropTargetDropEvent ; 44 import java.awt.dnd.DropTargetEvent ; 45 import java.awt.dnd.DropTargetListener ; 46 import java.awt.dnd.InvalidDnDOperationException ; 47 import java.awt.event.ActionEvent ; 48 import java.awt.event.ActionListener ; 49 import java.beans.Customizer ; 50 import java.beans.PropertyChangeListener ; 51 import java.io.IOException ; 52 import java.util.logging.Level ; 53 import java.util.logging.Logger ; 54 import javax.swing.JButton ; 55 import javax.swing.JComponent ; 56 import javax.swing.JDialog ; 57 import javax.swing.JLabel ; 58 import javax.swing.JList ; 59 import javax.swing.JPanel ; 60 import javax.swing.JScrollPane ; 61 import javax.swing.JViewport ; 62 import javax.swing.SwingUtilities ; 63 import javax.swing.UIManager ; 64 import javax.swing.border.Border ; 65 import javax.swing.border.LineBorder ; 66 import javax.swing.event.ChangeEvent ; 67 import javax.swing.event.ChangeListener ; 68 import javax.swing.event.ListSelectionEvent ; 69 import javax.swing.event.ListSelectionListener ; 70 import org.openide.util.NbBundle; 71 import org.openide.util.datatransfer.ExTransferable; 72 73 85 @Deprecated 86 public final class IndexedCustomizer extends JDialog implements Customizer { 87 static final long serialVersionUID = -8731362267771694641L; 89 90 92 93 private JList control; 94 95 96 private JButton buttonUp; 97 98 99 private JButton buttonDown; 100 101 102 private JButton buttonClose; 103 104 105 private Index index; 106 private Node[] nodes; 107 108 109 private boolean immediateReorder = true; 110 111 113 private int[] permutation; 114 115 116 private ChangeListener nodeChangesL; 117 118 119 public IndexedCustomizer() { 120 this(null, true); 121 } 122 123 130 IndexedCustomizer(Container p, boolean closeButton) { 131 super(TMUtil.mainWindow(), true); 132 133 GridBagConstraints constraints; 134 135 if (closeButton) { 136 setDefaultCloseOperation(javax.swing.JDialog.DISPOSE_ON_CLOSE); 137 138 getRootPane().registerKeyboardAction( 140 new java.awt.event.ActionListener () { 141 public void actionPerformed(java.awt.event.ActionEvent evt) { 142 setVisible(false); 143 dispose(); 144 } 145 }, javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_ESCAPE, 0, true), 146 javax.swing.JComponent.WHEN_IN_FOCUSED_WINDOW 147 ); 148 149 setTitle(Node.getString("LAB_order")); 150 } 151 153 if (p == null) { 154 p = getContentPane(); 155 } 156 157 p.setLayout(new GridBagLayout ()); 158 159 JLabel l = new JLabel (Node.getString("LAB_listOrder")); 160 l.setDisplayedMnemonic(Node.getString("LAB_listOrder_Mnemonic").charAt(0)); 161 constraints = new GridBagConstraints (); 162 constraints.gridx = 0; 163 constraints.gridy = 0; 164 constraints.anchor = GridBagConstraints.WEST; 165 constraints.insets = new Insets (12, 12, 2, 12); 166 p.add(l, constraints); 167 168 control = new AutoscrollJList(); 169 l.setLabelFor(control); 170 control.addListSelectionListener( 171 new ListSelectionListener () { 172 public void valueChanged(ListSelectionEvent e) { 173 if (control.isSelectionEmpty()) { 174 buttonUp.setEnabled(false); 175 buttonDown.setEnabled(false); 176 } else { 177 int i = control.getSelectedIndex(); 178 179 if (i > 0) { buttonUp.setEnabled(true); 181 } else { 182 buttonUp.setEnabled(false); 183 } 184 185 if (i < (nodes.length - 1)) { 186 buttonDown.setEnabled(true); 187 } else { 188 buttonDown.setEnabled(false); 189 } 190 } 191 } 192 } 193 ); 194 control.setCellRenderer(new IndexedListCellRenderer()); 195 control.setVisibleRowCount(15); 196 control.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION); 197 198 constraints = new GridBagConstraints (); 200 constraints.gridx = 0; 201 constraints.gridy = 1; 202 constraints.fill = GridBagConstraints.BOTH; 203 constraints.weightx = 1.0; 204 constraints.weighty = 1.0; 205 constraints.insets = new Insets (0, 12, 11, 11); 206 p.add(new JScrollPane (control), constraints); 207 208 JPanel bb = new JPanel (); 209 210 if (closeButton) { 211 buttonClose = new JButton (Node.getString("Button_close")); 212 buttonClose.setMnemonic(Node.getString("Button_close_Mnemonic").charAt(0)); 213 } 214 215 buttonUp = new JButton (Node.getString("Button_up")); 216 buttonUp.setMnemonic(Node.getString("Button_up_Mnemonic").charAt(0)); 217 buttonDown = new JButton (Node.getString("Button_down")); 218 buttonDown.setMnemonic(Node.getString("Button_down_Mnemonic").charAt(0)); 219 220 bb.setLayout(new GridBagLayout ()); 221 222 constraints = new GridBagConstraints (); 223 constraints.gridx = 0; 224 constraints.gridy = 0; 225 constraints.anchor = GridBagConstraints.NORTH; 226 constraints.fill = GridBagConstraints.HORIZONTAL; 227 constraints.insets = new Insets (0, 0, 5, 11); 228 bb.add(buttonUp, constraints); 229 230 constraints = new GridBagConstraints (); 231 constraints.gridx = 0; 232 constraints.gridy = 1; 233 constraints.anchor = GridBagConstraints.NORTH; 234 constraints.fill = GridBagConstraints.HORIZONTAL; 235 constraints.weighty = 1.0; 236 constraints.insets = new Insets (0, 0, 0, 11); 237 bb.add(buttonDown, constraints); 238 239 if (closeButton) { 240 constraints = new GridBagConstraints (); 241 constraints.gridx = 0; 242 constraints.gridy = 2; 243 constraints.anchor = GridBagConstraints.SOUTH; 244 constraints.fill = GridBagConstraints.HORIZONTAL; 245 constraints.insets = new Insets (0, 0, 11, 11); 246 bb.add(buttonClose, constraints); 247 } 248 249 buttonUp.addActionListener( 250 new ActionListener () { 251 public void actionPerformed(ActionEvent e) { 252 int i = control.getSelectedIndex(); 253 moveUp(i); 254 updateList(); 255 control.setSelectedIndex(i - 1); 256 control.ensureIndexIsVisible(i - 1); 257 control.repaint(); 258 } 259 } 260 ); 261 262 buttonDown.addActionListener( 263 new ActionListener () { 264 public void actionPerformed(ActionEvent e) { 265 int i = control.getSelectedIndex(); 266 moveDown(i); 267 updateList(); 268 control.setSelectedIndex(i + 1); 269 control.ensureIndexIsVisible(i + 1); 270 control.repaint(); 271 } 272 } 273 ); 274 275 if (closeButton) { 276 buttonClose.addActionListener( 277 new ActionListener () { 278 public void actionPerformed(ActionEvent e) { 279 doClose(); 280 dispose(); 281 } 282 } 283 ); 284 } 285 286 buttonUp.setEnabled(false); 287 buttonDown.setEnabled(false); 288 constraints = new GridBagConstraints (); 289 constraints.gridx = 1; 290 constraints.gridy = 1; 291 constraints.fill = GridBagConstraints.VERTICAL; 292 p.add(bb, constraints); 293 294 if (closeButton) { 300 pack(); 301 setBounds(org.openide.util.Utilities.findCenterBounds(getSize())); 302 303 buttonClose.requestFocus(); 305 buttonClose.getAccessibleContext().setAccessibleDescription(Node.getString("ACSD_Button_close")); 306 } 307 308 buttonUp.getAccessibleContext().setAccessibleDescription(Node.getString("ACSD_Button_up")); 309 buttonDown.getAccessibleContext().setAccessibleDescription(Node.getString("ACSD_Button_down")); 310 control.getAccessibleContext().setAccessibleDescription(Node.getString("ACSD_ListOrder")); 311 p.getAccessibleContext().setAccessibleDescription(Node.getString("ACSD_IndexedCustomizer")); 312 getAccessibleContext().setAccessibleDescription(Node.getString("ACSD_IndexedCustomizer")); 313 } 314 315 318 void doClose() { 319 if ((!immediateReorder) && (index != null) && (permutation != null)) { 320 int[] realPerm = new int[permutation.length]; 321 322 for (int i = 0; i < realPerm.length; i++) { 323 realPerm[permutation[i]] = i; 324 325 } 327 328 index.reorder(realPerm); 329 } 330 } 331 332 334 337 private void updateList() { 338 if (index == null) { 339 return; 340 } 341 342 Node[] localNodes = index.getNodes(); 343 344 if (!immediateReorder) { 348 getPermutation(); 349 350 int origLength = permutation.length; 351 int newLength = localNodes.length; 352 353 if (origLength < newLength) { 354 nodes = new Node[newLength]; 356 357 int[] newPerm = new int[newLength]; 358 System.arraycopy(newPerm, 0, permutation, 0, origLength); 359 360 for (int i = 0; i < newLength; i++) { 361 if (i < origLength) { 362 nodes[i] = localNodes[permutation[i]]; 363 } else { 364 nodes[i] = localNodes[i]; 366 newPerm[i] = i; 367 } 368 } 369 370 permutation = newPerm; 371 } else if (origLength > newLength) { 372 nodes = new Node[newLength]; 374 permutation = new int[newLength]; 375 376 for (int i = 0; i < newLength; i++) { 377 nodes[i] = localNodes[i]; 378 permutation[i] = i; 379 } 380 } else { 381 nodes = new Node[newLength]; 383 384 for (int i = 0; i < newLength; i++) 385 nodes[i] = localNodes[permutation[i]]; 386 } 387 } else { 388 nodes = localNodes.clone(); 389 } 390 391 control.setListData(nodes); 392 393 if ((nodes.length > 0) && (control.getSelectedIndex() == -1)) { 394 control.setSelectedIndex(0); 395 } 396 } 397 398 public Dimension getPreferredSize() { 399 return new Dimension (300, super.getPreferredSize().height); 400 } 401 402 405 public boolean isImmediateReorder() { 406 return immediateReorder; 407 } 408 409 412 public void setImmediateReorder(boolean immediateReorder) { 413 if (this.immediateReorder == immediateReorder) { 414 return; 415 } 416 417 this.immediateReorder = immediateReorder; 418 419 if (immediateReorder) { 420 if (permutation != null) { 421 index.reorder(permutation); 422 permutation = null; 423 updateList(); 424 } 425 } 426 } 427 428 430 434 public void setObject(Object bean) { 435 if (bean instanceof Index) { 436 index = (Index) bean; 437 438 nodeChangesL = new ChangeListener () { 440 public void stateChanged(ChangeEvent ev) { 441 SwingUtilities.invokeLater( 442 new Runnable () { 443 public void run() { 444 updateList(); 445 } 446 } 447 ); 448 } 449 }; 450 updateList(); 451 control.invalidate(); 452 validate(); 453 index.addChangeListener(org.openide.util.WeakListeners.change(nodeChangesL, index)); 454 } else { 455 throw new IllegalArgumentException (); 456 } 457 } 458 459 public void addPropertyChangeListener(PropertyChangeListener listener) { 461 } 462 463 public void removePropertyChangeListener(PropertyChangeListener listener) { 464 } 465 466 469 private void moveUp(final int position) { 470 if (index == null) { 471 return; 472 } 473 474 if (immediateReorder) { 475 index.moveUp(position); 476 } else { 477 getPermutation(); 478 479 int temp = permutation[position]; 480 permutation[position] = permutation[position - 1]; 481 permutation[position - 1] = temp; 482 } 483 } 484 485 488 private void moveDown(final int position) { 489 if (index == null) { 490 return; 491 } 492 493 if (immediateReorder) { 494 index.moveDown(position); 495 } else { 496 getPermutation(); 497 498 int temp = permutation[position]; 499 permutation[position] = permutation[position + 1]; 500 permutation[position + 1] = temp; 501 } 502 } 503 504 507 private int[] getPermutation() { 508 if (permutation == null) { 509 if (nodes == null) { 510 nodes = index.getNodes().clone(); 511 } 512 513 permutation = new int[nodes.length]; 514 515 for (int i = 0; i < nodes.length; permutation[i] = i++) 516 ; 517 } 518 519 return permutation; 520 } 521 522 526 void performReorder(int[] perm, int selected) { 527 if (immediateReorder) { 528 index.reorder(perm); 529 } else { 530 int[] reversed = new int[perm.length]; 533 534 for (int i = 0; i < reversed.length; i++) 535 reversed[perm[i]] = i; 536 537 int[] orig = getPermutation(); 538 permutation = new int[orig.length]; 539 540 for (int i = 0; i < orig.length; i++) { 541 permutation[i] = orig[reversed[i]]; 542 543 } 545 } 546 547 updateList(); 548 control.setSelectedIndex(selected); 549 control.repaint(); 550 } 551 552 554 private static final class IndexedDragSource implements DragGestureListener , DragSourceListener { 555 557 JList comp; 558 559 560 DragGestureEvent dge; 561 562 563 DataFlavor myFlavor; 564 565 569 IndexedDragSource(JList comp) { 570 this.comp = comp; 571 572 DragSource ds = DragSource.getDefaultDragSource(); 574 ds.createDefaultDragGestureRecognizer(comp, DnDConstants.ACTION_MOVE, this); 575 } 576 577 578 public void dragGestureRecognized(DragGestureEvent dge) { 579 if ((dge.getDragAction() & DnDConstants.ACTION_MOVE) == 0) { 581 return; 582 } 583 584 int index = comp.locationToIndex(dge.getDragOrigin()); 586 587 if (index < 0) { 589 return; 590 } 591 592 myFlavor = new DataFlavor ( 595 String .class, NbBundle.getBundle(IndexedCustomizer.class).getString("IndexedFlavor") 596 ); 597 598 try { 599 dge.startDrag(DragSource.DefaultMoveDrop, new IndexTransferable(myFlavor, index), this); 600 601 this.dge = dge; 603 } catch (InvalidDnDOperationException exc) { 604 Logger.getLogger(IndexedCustomizer.class.getName()).log(Level.WARNING, null, exc); 605 606 } 608 } 609 610 public void dragEnter(DragSourceDragEvent dsde) { 611 } 612 613 public void dragOver(DragSourceDragEvent dsde) { 614 } 615 616 public void dropActionChanged(DragSourceDragEvent dsde) { 617 } 618 619 public void dragExit(DragSourceEvent dse) { 620 } 621 622 public void dragDropEnd(DragSourceDropEvent dsde) { 623 } 624 625 626 DragGestureEvent getDragGestureEvent() { 627 return dge; 628 } 629 } 630 632 634 private static final class IndexedDropTarget implements DropTargetListener { 635 636 JList comp; 637 638 639 IndexedListCellRenderer cellRenderer; 640 641 642 IndexedCustomizer dialog; 643 644 645 IndexedDragSource ids; 646 647 648 int lastIndex = -1; 649 650 652 IndexedDropTarget(IndexedCustomizer dialog, IndexedDragSource ids) { 653 this.dialog = dialog; 654 this.comp = dialog.control; 655 this.cellRenderer = (IndexedListCellRenderer) this.comp.getCellRenderer(); 656 this.ids = ids; 657 new DropTarget (comp, DnDConstants.ACTION_MOVE, this, true); 658 } 659 660 661 public void dragEnter(DropTargetDragEvent dtde) { 662 if (!checkConditions(dtde)) { 663 dtde.rejectDrag(); 664 } else { 665 lastIndex = comp.locationToIndex(dtde.getLocation()); 666 cellRenderer.draggingEnter(lastIndex, ids.getDragGestureEvent().getDragOrigin(), dtde.getLocation()); 667 comp.repaint(comp.getCellBounds(lastIndex, lastIndex)); 668 } 669 } 670 671 672 public void dragOver(DropTargetDragEvent dtde) { 673 if (!checkConditions(dtde)) { 674 dtde.rejectDrag(); 675 676 if (lastIndex >= 0) { 677 cellRenderer.draggingExit(); 678 comp.repaint(comp.getCellBounds(lastIndex, lastIndex)); 679 lastIndex = -1; 680 } 681 } else { 682 dtde.acceptDrag(DnDConstants.ACTION_MOVE); 683 684 int index = comp.locationToIndex(dtde.getLocation()); 685 686 if (lastIndex == index) { 687 cellRenderer.draggingOver(index, ids.getDragGestureEvent().getDragOrigin(), dtde.getLocation()); 688 } else { 689 if (lastIndex < 0) { 690 lastIndex = index; 691 } 692 693 cellRenderer.draggingExit(); 694 cellRenderer.draggingEnter(index, ids.getDragGestureEvent().getDragOrigin(), dtde.getLocation()); 695 comp.repaint(comp.getCellBounds(lastIndex, index)); 696 lastIndex = index; 697 } 698 } 699 } 700 701 public void dropActionChanged(DropTargetDragEvent dtde) { 702 } 703 704 705 public void dragExit(DropTargetEvent dte) { 706 if (lastIndex >= 0) { 707 cellRenderer.draggingExit(); 708 comp.repaint(comp.getCellBounds(lastIndex, lastIndex)); 709 } 710 } 711 712 714 public void drop(DropTargetDropEvent dtde) { 715 if ((DnDConstants.ACTION_MOVE != dtde.getDropAction()) || !dtde.isLocalTransfer()) { 717 dtde.rejectDrop(); 718 } 719 720 int target = comp.locationToIndex(dtde.getLocation()); 721 722 if (target < 0) { 723 dtde.rejectDrop(); 724 725 return; 726 } 727 728 Transferable t = dtde.getTransferable(); 729 730 dtde.acceptDrop(DnDConstants.ACTION_MOVE); 732 733 try { 734 int source = Integer.parseInt((String ) t.getTransferData(ids.myFlavor)); 735 736 if (source != target) { 737 performReorder(source, target); 738 dtde.dropComplete(true); 739 } else { 740 dtde.dropComplete(false); 741 } 742 } catch (IOException exc) { 743 dtde.dropComplete(false); 744 } catch (UnsupportedFlavorException exc) { 745 dtde.dropComplete(false); 746 } catch (NumberFormatException exc) { 747 dtde.dropComplete(false); 748 } 749 } 750 751 755 void performReorder(int source, int target) { 756 int[] myPerm = new int[comp.getModel().getSize()]; 757 758 for (int i = 0; i < Math.min(source, target); i++) 761 myPerm[i] = i; 762 763 for (int i = Math.max(source, target) + 1; i < myPerm.length; i++) 764 myPerm[i] = i; 765 766 myPerm[source] = target; 768 769 if (source > target) { 770 for (int i = target; i < source; i++) 772 myPerm[i] = i + 1; 773 } else { 774 for (int i = source + 1; i < (target + 1); i++) 776 myPerm[i] = i - 1; 777 } 778 779 dialog.performReorder(myPerm, target); 781 } 782 783 785 boolean checkConditions(DropTargetDragEvent dtde) { 786 int index = comp.locationToIndex(dtde.getLocation()); 787 788 return (DnDConstants.ACTION_MOVE == dtde.getDropAction()) && (index >= 0); 789 } 790 } 791 793 796 private static final class IndexTransferable extends ExTransferable.Single { 797 798 int index; 799 800 801 IndexTransferable(DataFlavor flavor, int index) { 802 super(flavor); 803 this.index = index; 804 } 805 806 807 protected Object getData() throws IOException , UnsupportedFlavorException { 808 return String.valueOf(index); 809 } 810 } 811 813 816 private static final class IndexedListCellRenderer implements javax.swing.ListCellRenderer { 817 static final long serialVersionUID = -5526451942677242944L; 818 protected static Border hasFocusBorder; 819 820 static { 821 hasFocusBorder = new LineBorder (UIManager.getColor("List.focusCellHighlight")); } 823 824 827 private javax.swing.ListCellRenderer delegate = TMUtil.findListCellRenderer(); 828 829 830 int dragIndex; 831 832 833 IndexedListCellRenderer() { 834 dragIndex = -1; 835 } 836 837 839 public void draggingEnter(int index, Point startingLoc, Point currentLoc) { 840 this.dragIndex = index; 842 } 843 844 845 public void draggingOver(int index, Point startingLoc, Point currentLoc) { 846 } 847 848 850 public void draggingExit() { 851 dragIndex = -1; 852 } 853 854 public Component getListCellRendererComponent( 855 JList list, Object value, int index, boolean isSelected, boolean cellHasFocus 856 ) { 857 JComponent result = (JComponent ) delegate.getListCellRendererComponent( 858 list, value, index, isSelected, cellHasFocus 859 ); 860 861 if (index == dragIndex) { 862 result.setBorder(hasFocusBorder); 864 } 865 866 return result; 867 } 868 } 869 871 874 private static class AutoscrollJList extends JList implements Autoscroll { 875 static final long serialVersionUID = 5495776972406885734L; 876 877 878 Insets scrollInsets; 879 880 882 Insets realInsets; 883 884 885 JViewport viewport; 886 887 AutoscrollJList() { 888 } 889 890 891 public void autoscroll(Point cursorLoc) { 892 JViewport viewport = getViewport(); 893 Point viewPos = viewport.getViewPosition(); 894 int viewHeight = viewport.getExtentSize().height; 895 896 if ((cursorLoc.y - viewPos.y) <= realInsets.top) { 897 viewport.setViewPosition(new Point (viewPos.x, Math.max(viewPos.y - realInsets.top, 0))); 899 } else if (((viewPos.y + viewHeight) - cursorLoc.y) <= realInsets.bottom) { 900 viewport.setViewPosition( 902 new Point (viewPos.x, Math.min(viewPos.y + realInsets.bottom, this.getHeight() - viewHeight)) 903 ); 904 } 905 } 906 907 911 public Insets getAutoscrollInsets() { 912 if (scrollInsets == null) { 913 int height = this.getHeight(); 914 scrollInsets = new Insets (height, 0, height, 0); 915 916 realInsets = new Insets (15, 0, 15, 0); 919 } 920 921 return scrollInsets; 922 } 923 924 926 JViewport getViewport() { 927 if (viewport == null) { 928 Component comp = this; 929 930 while (!(comp instanceof JViewport ) && (comp != null)) { 931 comp = comp.getParent(); 932 } 933 934 viewport = (JViewport ) comp; 935 } 936 937 return viewport; 938 } 939 } 940 } 942 | Popular Tags |