1 package com.mxgraph.examples.swing.editor; 2 3 import java.awt.BorderLayout; 4 import java.awt.Point; 5 import java.awt.event.ActionEvent; 6 import java.awt.event.ActionListener; 7 import java.awt.event.ComponentAdapter; 8 import java.awt.event.ComponentEvent; 9 import java.awt.event.MouseAdapter; 10 import java.awt.event.MouseEvent; 11 import java.awt.event.MouseMotionListener; 12 import java.awt.event.MouseWheelEvent; 13 import java.awt.event.MouseWheelListener; 14 import java.io.File; 15 import java.net.ProxySelector; 16 import java.net.URL; 17 import java.util.List; 18 import java.util.StringTokenizer; 19 20 import javax.swing.AbstractAction; 21 import javax.swing.Action; 22 import javax.swing.BorderFactory; 23 import javax.swing.ImageIcon; 24 import javax.swing.JApplet; 25 import javax.swing.JCheckBoxMenuItem; 26 import javax.swing.JFrame; 27 import javax.swing.JLabel; 28 import javax.swing.JMenuBar; 29 import javax.swing.JOptionPane; 30 import javax.swing.JPanel; 31 import javax.swing.JPopupMenu; 32 import javax.swing.JScrollPane; 33 import javax.swing.JSplitPane; 34 import javax.swing.JTabbedPane; 35 import javax.swing.JToolBar; 36 import javax.swing.SwingUtilities; 37 import javax.swing.UIManager; 38 39 import org.apache.commons.codec.DecoderException; 40 import org.apache.commons.codec.binary.Hex; 41 import org.apache.commons.codec.net.URLCodec; 42 43 import com.mxgraph.layout.mxCircleLayout; 44 import com.mxgraph.layout.mxCompactTreeLayout; 45 import com.mxgraph.layout.mxEdgeLabelLayout; 46 import com.mxgraph.layout.mxIGraphLayout; 47 import com.mxgraph.layout.mxOrganicLayout; 48 import com.mxgraph.layout.mxParallelEdgeLayout; 49 import com.mxgraph.layout.mxPartitionLayout; 50 import com.mxgraph.layout.mxStackLayout; 51 import com.mxgraph.layout.hierarchical.mxHierarchicalLayout; 52 import com.mxgraph.swing.mxGraphComponent; 53 import com.mxgraph.swing.mxGraphOutline; 54 import com.mxgraph.swing.handler.mxKeyboardHandler; 55 import com.mxgraph.swing.handler.mxRubberband; 56 import com.mxgraph.swing.util.mxMorphing; 57 import com.mxgraph.util.mxEvent; 58 import com.mxgraph.util.mxEventObject; 59 import com.mxgraph.util.mxEventSource.mxIEventListener; 60 import com.mxgraph.util.mxRectangle; 61 import com.mxgraph.util.mxResources; 62 import com.mxgraph.util.mxUndoManager; 63 import com.mxgraph.util.mxUndoableEdit; 64 import com.mxgraph.util.mxUndoableEdit.mxUndoableChange; 65 import com.mxgraph.view.mxGraph; 66 67 public class BasicGraphEditor extends JPanel 68 { 69 70 /** 71 * 72 */ 73 private static final long serialVersionUID = -6561623072112577140L; 74 75 /** 76 * Adds required resources for i18n 77 */ 78 static 79 { 80 mxResources.add("com/mxgraph/examples/swing/resources/editor"); 81 } 82 83 /** 84 * 85 */ 86 protected mxGraphComponent graphComponent; 87 88 /** 89 * 90 */ 91 protected mxGraphOutline graphOutline; 92 93 /** 94 * 95 */ 96 protected JTabbedPane libraryPane; 97 98 /** 99 * 100 */ 101 protected mxUndoManager undoManager; 102 103 /** 104 * 105 */ 106 protected String appTitle; 107 108 /** 109 * 110 */ 111 protected JLabel statusBar; 112 113 /** 114 * 115 */ 116 protected File currentFile; 117 118 /** 119 * 120 */ 121 protected boolean modified = false; 122 123 /** 124 * 125 */ 126 protected mxRubberband rubberband; 127 128 /** 129 * 130 */ 131 protected mxKeyboardHandler keyboardHandler; 132 133 /** 134 * 135 */ 136 protected mxIEventListener undoHandler = new mxIEventListener() 137 { 138 public void invoke(Object source, mxEventObject evt) 139 { 140 undoManager.undoableEditHappened((mxUndoableEdit) evt 141 .getProperty("edit")); 142 } 143 }; 144 145 /** 146 * 147 */ 148 protected mxIEventListener changeTracker = new mxIEventListener() 149 { 150 public void invoke(Object source, mxEventObject evt) 151 { 152 setModified(true); 153 } 154 }; 155 156 /** 157 * 158 */ BasicGraphEditor(String appTitle, mxGraphComponent component, Config config)159 public BasicGraphEditor(String appTitle, mxGraphComponent component, Config config) 160 { 161 this.config = config; 162 163 // Stores and updates the frame title 164 this.appTitle = appTitle; 165 166 // Stores a reference to the graph and creates the command history 167 graphComponent = component; 168 final mxGraph graph = graphComponent.getGraph(); 169 undoManager = createUndoManager(); 170 171 // Do not change the scale and translation after files have been loaded 172 graph.setResetViewOnRootChange(false); 173 174 // Updates the modified flag if the graph model changes 175 graph.getModel().addListener(mxEvent.CHANGE, changeTracker); 176 177 // Adds the command history to the model and view 178 graph.getModel().addListener(mxEvent.UNDO, undoHandler); 179 graph.getView().addListener(mxEvent.UNDO, undoHandler); 180 181 // Keeps the selection in sync with the command history 182 mxIEventListener undoHandler = new mxIEventListener() 183 { 184 public void invoke(Object source, mxEventObject evt) 185 { 186 List<mxUndoableChange> changes = ((mxUndoableEdit) evt 187 .getProperty("edit")).getChanges(); 188 graph.setSelectionCells(graph 189 .getSelectionCellsForChanges(changes)); 190 } 191 }; 192 193 undoManager.addListener(mxEvent.UNDO, undoHandler); 194 undoManager.addListener(mxEvent.REDO, undoHandler); 195 196 // Creates the graph outline component 197 graphOutline = new mxGraphOutline(graphComponent); 198 199 // Creates the library pane that contains the tabs with the palettes 200 libraryPane = new JTabbedPane(); 201 202 // Creates the inner split pane that contains the library with the 203 // palettes and the graph outline on the left side of the window 204 JSplitPane inner = new JSplitPane(JSplitPane.VERTICAL_SPLIT, 205 libraryPane, graphOutline); 206 inner.setDividerLocation(320); 207 inner.setResizeWeight(1); 208 inner.setDividerSize(6); 209 inner.setBorder(null); 210 211 // Creates the outer split pane that contains the inner split pane and 212 // the graph component on the right side of the window 213 JSplitPane outer = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, inner, graphComponent); 214 outer.setOneTouchExpandable(true); 215 outer.setDividerLocation(200); 216 outer.setDividerSize(6); 217 outer.setBorder(null); 218 219 // Creates the status bar 220 statusBar = createStatusBar(); 221 222 // Display some useful information about repaint events 223 installRepaintListener(); 224 225 // Puts everything together 226 setLayout(new BorderLayout()); 227 add(outer, BorderLayout.CENTER); 228 add(statusBar, BorderLayout.SOUTH); 229 installToolBar(); 230 231 // Installs rubberband selection and handling for some special 232 // keystrokes such as F2, Control-C, -V, X, A etc. 233 installHandlers(); 234 installListeners(); 235 // updateTitle(); 236 } 237 238 /** 239 * 240 */ createUndoManager()241 protected mxUndoManager createUndoManager() 242 { 243 return new mxUndoManager(); 244 } 245 246 /** 247 * 248 */ installHandlers()249 protected void installHandlers() 250 { 251 rubberband = new mxRubberband(graphComponent); 252 keyboardHandler = new EditorKeyboardHandler(graphComponent); 253 } 254 255 /** 256 * 257 */ installToolBar()258 protected void installToolBar() 259 { 260 add(new EditorToolBar(this, JToolBar.HORIZONTAL), BorderLayout.NORTH); 261 } 262 263 /** 264 * 265 */ createStatusBar()266 protected JLabel createStatusBar() 267 { 268 JLabel statusBar = new JLabel(mxResources.get("ready")); 269 statusBar.setBorder(BorderFactory.createEmptyBorder(2, 4, 2, 4)); 270 271 return statusBar; 272 } 273 274 /** 275 * 276 */ installRepaintListener()277 protected void installRepaintListener() 278 { 279 graphComponent.getGraph().addListener(mxEvent.REPAINT, 280 new mxIEventListener() 281 { 282 public void invoke(Object source, mxEventObject evt) 283 { 284 String buffer = (graphComponent.getTripleBuffer() != null) ? "" 285 : " (unbuffered)"; 286 mxRectangle dirty = (mxRectangle) evt 287 .getProperty("region"); 288 289 if (dirty == null) 290 { 291 status("Repaint all" + buffer); 292 } 293 else 294 { 295 status("Repaint: x=" + (int) (dirty.getX()) + " y=" 296 + (int) (dirty.getY()) + " w=" 297 + (int) (dirty.getWidth()) + " h=" 298 + (int) (dirty.getHeight()) + buffer); 299 } 300 } 301 }); 302 } 303 304 /** 305 * 306 */ insertPalette(String title)307 public EditorPalette insertPalette(String title) 308 { 309 final EditorPalette palette = new EditorPalette(); 310 final JScrollPane scrollPane = new JScrollPane(palette); 311 scrollPane 312 .setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); 313 scrollPane 314 .setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); 315 libraryPane.add(title, scrollPane); 316 317 // Updates the widths of the palettes if the container size changes 318 libraryPane.addComponentListener(new ComponentAdapter() 319 { 320 /** 321 * 322 */ 323 public void componentResized(ComponentEvent e) 324 { 325 int w = scrollPane.getWidth() 326 - scrollPane.getVerticalScrollBar().getWidth(); 327 palette.setPreferredWidth(w); 328 } 329 330 }); 331 332 return palette; 333 } 334 335 /** 336 * 337 */ mouseWheelMoved(MouseWheelEvent e)338 protected void mouseWheelMoved(MouseWheelEvent e) 339 { 340 if (e.getWheelRotation() < 0) 341 { 342 graphComponent.zoomIn(); 343 } 344 else 345 { 346 graphComponent.zoomOut(); 347 } 348 349 status(mxResources.get("scale") + ": " 350 + (int) (100 * graphComponent.getGraph().getView().getScale()) 351 + "%"); 352 } 353 354 /** 355 * 356 */ showOutlinePopupMenu(MouseEvent e)357 protected void showOutlinePopupMenu(MouseEvent e) 358 { 359 Point pt = SwingUtilities.convertPoint(e.getComponent(), e.getPoint(), 360 graphComponent); 361 JCheckBoxMenuItem item = new JCheckBoxMenuItem(mxResources 362 .get("magnifyPage")); 363 item.setSelected(graphOutline.isFitPage()); 364 365 item.addActionListener(new ActionListener() 366 { 367 /** 368 * 369 */ 370 public void actionPerformed(ActionEvent e) 371 { 372 graphOutline.setFitPage(!graphOutline.isFitPage()); 373 graphOutline.repaint(); 374 } 375 }); 376 377 JCheckBoxMenuItem item2 = new JCheckBoxMenuItem(mxResources 378 .get("showLabels")); 379 item2.setSelected(graphOutline.isDrawLabels()); 380 381 item2.addActionListener(new ActionListener() 382 { 383 /** 384 * 385 */ 386 public void actionPerformed(ActionEvent e) 387 { 388 graphOutline.setDrawLabels(!graphOutline.isDrawLabels()); 389 graphOutline.repaint(); 390 } 391 }); 392 393 JCheckBoxMenuItem item3 = new JCheckBoxMenuItem(mxResources 394 .get("buffering")); 395 item3.setSelected(graphOutline.isTripleBuffered()); 396 397 item3.addActionListener(new ActionListener() 398 { 399 /** 400 * 401 */ 402 public void actionPerformed(ActionEvent e) 403 { 404 graphOutline 405 .setTripleBuffered(!graphOutline.isTripleBuffered()); 406 graphOutline.repaint(); 407 } 408 }); 409 410 JPopupMenu menu = new JPopupMenu(); 411 menu.add(item); 412 menu.add(item2); 413 menu.add(item3); 414 menu.show(graphComponent, pt.x, pt.y); 415 416 e.consume(); 417 } 418 419 /** 420 * 421 */ showGraphPopupMenu(MouseEvent e)422 protected void showGraphPopupMenu(MouseEvent e) 423 { 424 Point pt = SwingUtilities.convertPoint(e.getComponent(), e.getPoint(), 425 graphComponent); 426 EditorPopupMenu menu = new EditorPopupMenu(BasicGraphEditor.this); 427 menu.show(graphComponent, pt.x, pt.y); 428 429 e.consume(); 430 } 431 432 /** 433 * 434 */ mouseLocationChanged(MouseEvent e)435 protected void mouseLocationChanged(MouseEvent e) 436 { 437 status(e.getX() + ", " + e.getY()); 438 } 439 440 /** 441 * 442 */ installListeners()443 protected void installListeners() 444 { 445 // Installs mouse wheel listener for zooming 446 MouseWheelListener wheelTracker = new MouseWheelListener() 447 { 448 /** 449 * 450 */ 451 public void mouseWheelMoved(MouseWheelEvent e) 452 { 453 if (e.getSource() instanceof mxGraphOutline 454 || e.isControlDown()) 455 { 456 BasicGraphEditor.this.mouseWheelMoved(e); 457 } 458 } 459 460 }; 461 462 // Handles mouse wheel events in the outline and graph component 463 graphOutline.addMouseWheelListener(wheelTracker); 464 graphComponent.addMouseWheelListener(wheelTracker); 465 466 // Installs the popup menu in the outline 467 graphOutline.addMouseListener(new MouseAdapter() 468 { 469 470 /** 471 * 472 */ 473 public void mousePressed(MouseEvent e) 474 { 475 // Handles context menu on the Mac where the trigger is on mousepressed 476 mouseReleased(e); 477 } 478 479 /** 480 * 481 */ 482 public void mouseReleased(MouseEvent e) 483 { 484 if (e.isPopupTrigger()) 485 { 486 showOutlinePopupMenu(e); 487 } 488 } 489 490 }); 491 492 // Installs the popup menu in the graph component 493 graphComponent.getGraphControl().addMouseListener(new MouseAdapter() 494 { 495 496 /** 497 * 498 */ 499 public void mousePressed(MouseEvent e) 500 { 501 // Handles context menu on the Mac where the trigger is on mousepressed 502 mouseReleased(e); 503 } 504 505 /** 506 * 507 */ 508 public void mouseReleased(MouseEvent e) 509 { 510 if (e.isPopupTrigger()) 511 { 512 showGraphPopupMenu(e); 513 } 514 } 515 516 }); 517 518 // Installs a mouse motion listener to display the mouse location 519 graphComponent.getGraphControl().addMouseMotionListener( 520 new MouseMotionListener() 521 { 522 523 /* 524 * (non-Javadoc) 525 * @see java.awt.event.MouseMotionListener#mouseDragged(java.awt.event.MouseEvent) 526 */ 527 public void mouseDragged(MouseEvent e) 528 { 529 mouseLocationChanged(e); 530 } 531 532 /* 533 * (non-Javadoc) 534 * @see java.awt.event.MouseMotionListener#mouseMoved(java.awt.event.MouseEvent) 535 */ 536 public void mouseMoved(MouseEvent e) 537 { 538 mouseDragged(e); 539 } 540 541 }); 542 } 543 544 // /** 545 // * 546 // */ 547 // public void setCurrentFile(File file) 548 // { 549 // File oldValue = currentFile; 550 // currentFile = file; 551 // 552 // firePropertyChange("currentFile", oldValue, file); 553 // 554 // if (oldValue != file) 555 // { 556 // updateTitle(); 557 // } 558 // } 559 560 /** 561 * 562 */ getCurrentFile()563 public File getCurrentFile() 564 { 565 return currentFile; 566 } 567 568 /** 569 * 570 * @param modified 571 */ setModified(boolean modified)572 public void setModified(boolean modified) 573 { 574 boolean oldValue = this.modified; 575 this.modified = modified; 576 577 firePropertyChange("modified", oldValue, modified); 578 579 // if (oldValue != modified) 580 // { 581 // updateTitle(); 582 // } 583 } 584 585 /** 586 * 587 * @return 588 */ isModified()589 public boolean isModified() 590 { 591 return modified; 592 } 593 594 /** 595 * 596 */ getGraphComponent()597 public mxGraphComponent getGraphComponent() 598 { 599 return graphComponent; 600 } 601 602 /** 603 * 604 */ getGraphOutline()605 public mxGraphOutline getGraphOutline() 606 { 607 return graphOutline; 608 } 609 610 /** 611 * 612 */ getLibraryPane()613 public JTabbedPane getLibraryPane() 614 { 615 return libraryPane; 616 } 617 618 /** 619 * 620 */ getUndoManager()621 public mxUndoManager getUndoManager() 622 { 623 return undoManager; 624 } 625 626 /** 627 * 628 * @param name 629 * @param action 630 * @return 631 */ bind(String name, final Action action)632 public Action bind(String name, final Action action) 633 { 634 return bind(name, action, null); 635 } 636 637 /** 638 * 639 * @param name 640 * @param action 641 * @return 642 */ 643 @SuppressWarnings("serial") bind(String name, final Action action, String iconUrl)644 public Action bind(String name, final Action action, String iconUrl) 645 { 646 return new AbstractAction(name, (iconUrl != null) ? new ImageIcon( 647 BasicGraphEditor.class.getResource(iconUrl)) : null) 648 { 649 public void actionPerformed(ActionEvent e) 650 { 651 action.actionPerformed(new ActionEvent(getGraphComponent(), e 652 .getID(), e.getActionCommand())); 653 } 654 }; 655 } 656 657 /** 658 * 659 * @param msg 660 */ 661 public void status(String msg) 662 { 663 statusBar.setText(msg); 664 } 665 666 // /** 667 // * 668 // */ 669 // public void updateTitle() 670 // { 671 // JFrame frame = (JFrame) SwingUtilities.windowForComponent(this); 672 // 673 // if (frame != null) 674 // { 675 // String title = (currentFile != null) ? currentFile 676 // .getAbsolutePath() : mxResources.get("newDiagram"); 677 // 678 // if (modified) 679 // { 680 // title += "*"; 681 // } 682 // 683 // frame.setTitle(title + " - " + appTitle); 684 // } 685 // } 686 687 /** 688 * 689 */ 690 public void about() 691 { 692 JFrame frame = (JFrame) SwingUtilities.windowForComponent(this); 693 694 if (frame != null) 695 { 696 EditorAboutFrame about = new EditorAboutFrame(frame); 697 about.setModal(true); 698 699 // Centers inside the application frame 700 int x = frame.getX() + (frame.getWidth() - about.getWidth()) / 2; 701 int y = frame.getY() + (frame.getHeight() - about.getHeight()) / 2; 702 about.setLocation(x, y); 703 704 // Shows the modal dialog and waits 705 about.setVisible(true); 706 } 707 } 708 709 /** 710 * 711 */ 712 public void exit() 713 { 714 JFrame frame = (JFrame) SwingUtilities.windowForComponent(this); 715 716 if (frame != null) 717 { 718 frame.dispose(); 719 } 720 } 721 722 /** 723 * 724 */ 725 public void setLookAndFeel(String clazz) 726 { 727 JFrame frame = (JFrame) SwingUtilities.windowForComponent(this); 728 729 if (frame != null) 730 { 731 try 732 { 733 UIManager.setLookAndFeel(clazz); 734 SwingUtilities.updateComponentTreeUI(frame); 735 736 // Needs to assign the key bindings again 737 keyboardHandler = new EditorKeyboardHandler(graphComponent); 738 } 739 catch (Exception e1) 740 { 741 e1.printStackTrace(); 742 } 743 } 744 } 745 746 /** 747 * 748 */ 749 public JFrame createFrame(JMenuBar menuBar) 750 { 751 JFrame frame = new JFrame(); 752 frame.getContentPane().add(this); 753 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 754 frame.setJMenuBar(menuBar); 755 frame.setSize(870, 640); 756 757 // Updates the frame title 758 // updateTitle(); 759 760 return frame; 761 } 762 763 /** 764 * Creates an action that executes the specified layout. 765 * 766 * @param key Key to be used for getting the label from mxResources and also 767 * to create the layout instance for the commercial graph editor example. 768 * @return an action that executes the specified layout 769 */ 770 @SuppressWarnings("serial") 771 public Action graphLayout(final String key, boolean animate) 772 { 773 final mxIGraphLayout layout = createLayout(key, animate); 774 775 if (layout != null) 776 { 777 return new AbstractAction(mxResources.get(key)) 778 { 779 public void actionPerformed(ActionEvent e) 780 { 781 final mxGraph graph = graphComponent.getGraph(); 782 Object cell = graph.getSelectionCell(); 783 784 if (cell == null 785 || graph.getModel().getChildCount(cell) == 0) 786 { 787 cell = graph.getDefaultParent(); 788 } 789 790 graph.getModel().beginUpdate(); 791 try 792 { 793 long t0 = System.currentTimeMillis(); 794 layout.execute(cell); 795 status("Layout: " + (System.currentTimeMillis() - t0) 796 + " ms"); 797 } 798 finally 799 { 800 mxMorphing morph = new mxMorphing(graphComponent, 20, 801 1.2, 20); 802 803 morph.addListener(mxEvent.DONE, new mxIEventListener() 804 { 805 806 public void invoke(Object sender, mxEventObject evt) 807 { 808 graph.getModel().endUpdate(); 809 } 810 811 }); 812 813 morph.startAnimation(); 814 } 815 816 } 817 818 }; 819 } 820 else 821 { 822 return new AbstractAction(mxResources.get(key)) 823 { 824 825 public void actionPerformed(ActionEvent e) 826 { 827 JOptionPane.showMessageDialog(graphComponent, 828 mxResources.get("noLayout")); 829 } 830 831 }; 832 } 833 } 834 835 /** 836 * Creates a layout instance for the given identifier. 837 */ 838 protected mxIGraphLayout createLayout(String ident, boolean animate) 839 { 840 mxIGraphLayout layout = null; 841 842 if (ident != null) 843 { 844 mxGraph graph = graphComponent.getGraph(); 845 846 if (ident.equals("verticalHierarchical")) 847 { 848 layout = new mxHierarchicalLayout(graph); 849 } 850 else if (ident.equals("horizontalHierarchical")) 851 { 852 layout = new mxHierarchicalLayout(graph, JLabel.WEST); 853 } 854 else if (ident.equals("verticalTree")) 855 { 856 layout = new mxCompactTreeLayout(graph, false); 857 } 858 else if (ident.equals("horizontalTree")) 859 { 860 layout = new mxCompactTreeLayout(graph, true); 861 } 862 else if (ident.equals("parallelEdges")) 863 { 864 layout = new mxParallelEdgeLayout(graph); 865 } 866 else if (ident.equals("placeEdgeLabels")) 867 { 868 layout = new mxEdgeLabelLayout(graph); 869 } 870 else if (ident.equals("organicLayout")) 871 { 872 layout = new mxOrganicLayout(graph); 873 } 874 if (ident.equals("verticalPartition")) 875 { 876 layout = new mxPartitionLayout(graph, false) 877 { 878 /** 879 * Overrides the empty implementation to return the size of the 880 * graph control. 881 */ 882 public mxRectangle getContainerSize() 883 { 884 return graphComponent.getLayoutAreaSize(); 885 } 886 }; 887 } 888 else if (ident.equals("horizontalPartition")) 889 { 890 layout = new mxPartitionLayout(graph, true) 891 { 892 /** 893 * Overrides the empty implementation to return the size of the 894 * graph control. 895 */ 896 public mxRectangle getContainerSize() 897 { 898 return graphComponent.getLayoutAreaSize(); 899 } 900 }; 901 } 902 else if (ident.equals("verticalStack")) 903 { 904 layout = new mxStackLayout(graph, false) 905 { 906 /** 907 * Overrides the empty implementation to return the size of the 908 * graph control. 909 */ 910 public mxRectangle getContainerSize() 911 { 912 return graphComponent.getLayoutAreaSize(); 913 } 914 }; 915 } 916 else if (ident.equals("horizontalStack")) 917 { 918 layout = new mxStackLayout(graph, true) 919 { 920 /** 921 * Overrides the empty implementation to return the size of the 922 * graph control. 923 */ 924 public mxRectangle getContainerSize() 925 { 926 return graphComponent.getLayoutAreaSize(); 927 } 928 }; 929 } 930 else if (ident.equals("circleLayout")) 931 { 932 layout = new mxCircleLayout(graph); 933 } 934 } 935 936 return layout; 937 } 938 939 public static class Config { 940 941 private JApplet applet; 942 private ProxySelector proxySelector; 943 944 public Config(JApplet applet /*, HttpClient httpClient*/) { 945 this.applet = applet; 946 // this.httpClient = httpClient; 947 try { 948 // Proxy configuration - requires java.net.NetPermission getProxySelector 949 proxySelector = ProxySelector.getDefault(); 950 } catch (Exception e) { 951 System.err.println("Can't obtain proxy information: "+e); 952 e.printStackTrace(); 953 } 954 } 955 956 public ProxySelector getProxySelector() { 957 return proxySelector; 958 } 959 960 // private HttpClient httpClient; 961 // 962 // public HttpClient getHttpClient() { 963 // return httpClient; 964 // } 965 966 // public URL getDocumentBase() { 967 // return applet.getDocumentBase(); 968 // } 969 970 public String getDokuHost() { 971 return applet.getParameter("host"); 972 } 973 974 public String getDokuBase() { 975 return applet.getParameter("dokuBase"); 976 } 977 978 public String getImageFormat() { 979 return applet.getParameter("imageFormat"); 980 } 981 982 public String getPalettes() { 983 return applet.getParameter("palettes"); 984 } 985 986 public String getAuthtok() { 987 return applet.getParameter("authtok"); 988 } 989 990 public String getSectok() { 991 return applet.getParameter("sectok"); 992 } 993 994 public String getName() throws DecoderException { 995 return new String(Hex.decodeHex(applet.getParameter("name").toCharArray())); 996 } 997 998 public String getSessionName() { 999 return applet.getParameter("sessionName"); 1000 } 1001 1002 public String getSessionId() { 1003 return applet.getParameter("sessionId"); 1004 } 1005 1006 private String hex2urlEncoded(String hexStr) throws DecoderException { 1007 return new String(URLCodec.encodeUrl(null, Hex.decodeHex(hexStr.toCharArray()))); 1008 } 1009 1010 public String getCookies() throws DecoderException { 1011 String cookiesStr = applet.getParameter("cookies"); 1012 if (cookiesStr==null) { 1013 return null; 1014 } 1015 1016 StringBuilder ret = new StringBuilder(); 1017 StringTokenizer st = new StringTokenizer(cookiesStr, ";"); 1018 while (st.hasMoreTokens()) { 1019 String tok = st.nextToken(); 1020 int idx = tok.indexOf("="); 1021 ret.append(hex2urlEncoded(tok.substring(0, idx))); 1022 ret.append("="); 1023 ret.append(hex2urlEncoded(tok.substring(idx+1))); 1024 if (st.hasMoreElements()) { 1025 ret.append(";"); 1026 } 1027 } 1028 1029 return ret.toString(); 1030 } 1031 1032 public boolean isNew() { 1033 return "yes".equals(applet.getParameter("isNew")); 1034 } 1035 1036 } 1037 1038 private Config config; 1039 1040 public Config getConfig() { 1041 return config; 1042 } 1043 1044 } 1045