001/* 002 * Copyright 2010-2015 Institut Pasteur. 003 * 004 * This file is part of Icy. 005 * 006 * Icy is free software: you can redistribute it and/or modify 007 * it under the terms of the GNU General Public License as published by 008 * the Free Software Foundation, either version 3 of the License, or 009 * (at your option) any later version. 010 * 011 * Icy is distributed in the hope that it will be useful, 012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 014 * GNU General Public License for more details. 015 * 016 * You should have received a copy of the GNU General Public License 017 * along with Icy. If not, see <http://www.gnu.org/licenses/>. 018 */ 019package icy.gui.frame; 020 021import java.awt.AWTEvent; 022import java.awt.Color; 023import java.awt.Component; 024import java.awt.Container; 025import java.awt.Dimension; 026import java.awt.Image; 027import java.awt.LayoutManager; 028import java.awt.Point; 029import java.awt.Rectangle; 030import java.awt.Toolkit; 031import java.awt.event.ActionEvent; 032import java.awt.event.ComponentListener; 033import java.awt.event.KeyEvent; 034import java.awt.event.KeyListener; 035import java.awt.event.WindowEvent; 036import java.awt.event.WindowListener; 037import java.awt.image.ImageObserver; 038import java.beans.PropertyChangeEvent; 039import java.beans.PropertyChangeListener; 040import java.beans.PropertyVetoException; 041import java.util.ArrayList; 042 043import javax.swing.ActionMap; 044import javax.swing.InputMap; 045import javax.swing.JDesktopPane; 046import javax.swing.JFrame; 047import javax.swing.JInternalFrame; 048import javax.swing.JLayeredPane; 049import javax.swing.JMenu; 050import javax.swing.JMenuBar; 051import javax.swing.JPanel; 052import javax.swing.JRootPane; 053import javax.swing.WindowConstants; 054import javax.swing.border.Border; 055import javax.swing.event.EventListenerList; 056import javax.swing.event.InternalFrameEvent; 057import javax.swing.event.InternalFrameListener; 058 059import icy.action.IcyAbstractAction; 060import icy.common.MenuCallback; 061import icy.gui.main.MainFrame; 062import icy.gui.util.ComponentUtil; 063import icy.main.Icy; 064import icy.resource.ResourceUtil; 065import icy.resource.icon.IcyIcon; 066import icy.system.thread.ThreadUtil; 067import icy.util.StringUtil; 068 069/** 070 * This class behave either as a JFrame or a JInternalFrame.<br> 071 * IcyFrame should be 100% AWT safe 072 * 073 * @author Fabrice de Chaumont & Stephane Dallongeville 074 */ 075public class IcyFrame implements InternalFrameListener, WindowListener, ImageObserver, PropertyChangeListener 076{ 077 private class SwitchStateAction extends IcyAbstractAction 078 { 079 /** 080 * 081 */ 082 private static final long serialVersionUID = -4433831471426743128L; 083 084 final IcyIcon detachIcon; 085 final IcyIcon attachIcon; 086 087 public SwitchStateAction() 088 { 089 super(""); 090 091 detachIcon = new IcyIcon(ResourceUtil.ICON_WINDOW_EXPAND, 20); 092 attachIcon = new IcyIcon(ResourceUtil.ICON_WINDOW_COLLAPSE, 20); 093 setAccelerator(KeyEvent.VK_F3); 094 095 refreshState(); 096 } 097 098 @Override 099 public boolean doAction(ActionEvent e) 100 { 101 switchState(); 102 return true; 103 } 104 105 void refreshState() 106 { 107 if (isInternalized()) 108 { 109 setName("Detach"); 110 setIcon(detachIcon); 111 setDescription("Externalize the window"); 112 } 113 else 114 { 115 setName("Attach"); 116 setIcon(attachIcon); 117 setDescription("Internalize the window"); 118 } 119 } 120 } 121 122 /** 123 * list containing all active frames 124 */ 125 static ArrayList<IcyFrame> frames = new ArrayList<IcyFrame>(); 126 127 /** 128 * Return all active (not closed) IcyFrame 129 */ 130 public static ArrayList<IcyFrame> getAllFrames() 131 { 132 synchronized (frames) 133 { 134 return new ArrayList<IcyFrame>(frames); 135 } 136 } 137 138 /** 139 * Return all active IcyFrame which derive from the specified class 140 */ 141 public static ArrayList<IcyFrame> getAllFrames(Class<?> frameClass) 142 { 143 final ArrayList<IcyFrame> result = new ArrayList<IcyFrame>(); 144 145 if (frameClass != null) 146 { 147 synchronized (frames) 148 { 149 for (IcyFrame frame : frames) 150 if (frameClass.isInstance(frame)) 151 result.add(frame); 152 153 } 154 } 155 156 return result; 157 } 158 159 /** 160 * Find IcyFrame corresponding to the specified JInternalFrame 161 */ 162 public static IcyFrame findIcyFrame(JInternalFrame frame) 163 { 164 synchronized (frames) 165 { 166 for (IcyFrame f : frames) 167 if (f.getInternalFrame() == frame) 168 return f; 169 170 return null; 171 } 172 } 173 174 public enum IcyFrameState 175 { 176 INTERNALIZED, EXTERNALIZED 177 } 178 179 protected IcyExternalFrame externalFrame; 180 protected IcyInternalFrame internalFrame; 181 182 /** 183 * frame state (internal / external) 184 */ 185 protected IcyFrameState state; 186 187 /** 188 * sync flag for AWT thread process 189 */ 190 protected boolean syncProcess; 191 192 /** 193 * listeners 194 */ 195 protected EventListenerList frameEventListeners; 196 197 /** 198 * internals 199 */ 200 protected final MenuCallback defaultSystemMenuCallback; 201 protected SwitchStateAction switchStateAction; 202 protected boolean switchStateItemVisible; 203 protected IcyFrameState previousState; 204 205 public IcyFrame() 206 { 207 this("", false, true, false, false, true); 208 } 209 210 public IcyFrame(String title) 211 { 212 this(title, false, true, false, false, true); 213 } 214 215 public IcyFrame(String title, boolean resizable) 216 { 217 this(title, resizable, true, false, false, true); 218 } 219 220 public IcyFrame(String title, boolean resizable, boolean closable) 221 { 222 this(title, resizable, closable, false, false, true); 223 } 224 225 public IcyFrame(String title, boolean resizable, boolean closable, boolean maximizable) 226 { 227 this(title, resizable, closable, maximizable, false, true); 228 } 229 230 public IcyFrame(final String title, final boolean resizable, final boolean closable, final boolean maximizable, 231 final boolean iconifiable) 232 { 233 this(title, resizable, closable, maximizable, iconifiable, true); 234 } 235 236 public IcyFrame(final String title, final boolean resizable, final boolean closable, final boolean maximizable, 237 final boolean iconifiable, final boolean waitCreate) 238 { 239 super(); 240 241 frameEventListeners = new EventListenerList(); 242 defaultSystemMenuCallback = new MenuCallback() 243 { 244 @Override 245 public JMenu getMenu() 246 { 247 return getDefaultSystemMenu(); 248 } 249 }; 250 251 syncProcess = false; 252 253 // set default state 254 if (canBeInternalized()) 255 state = IcyFrameState.INTERNALIZED; 256 else 257 state = IcyFrameState.EXTERNALIZED; 258 259 switchStateItemVisible = true; 260 // wanted default state 261 previousState = IcyFrameState.INTERNALIZED; 262 263 // create action after state has been set 264 switchStateAction = new SwitchStateAction(); 265 switchStateAction.setEnabled(canBeInternalized()); 266 267 ThreadUtil.invoke(new Runnable() 268 { 269 @Override 270 public void run() 271 { 272 externalFrame = createExternalFrame(title); 273 // redirect frame / window events 274 externalFrame.addWindowListener(IcyFrame.this); 275 externalFrame.setLocationRelativeTo(null); 276 externalFrame.setResizable(resizable); 277 externalFrame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); 278 // default size 279 externalFrame.setSize(480, 400); 280 281 internalFrame = createInternalFrame(title, resizable, closable, maximizable, iconifiable); 282 // redirect frame / window events 283 internalFrame.addInternalFrameListener(IcyFrame.this); 284 // default size 285 internalFrame.setSize(480, 400); 286 287 // default system menu callback 288 externalFrame.setSystemMenuCallback(defaultSystemMenuCallback); 289 internalFrame.setSystemMenuCallback(defaultSystemMenuCallback); 290 291 // register to the list 292 synchronized (frames) 293 { 294 frames.add(IcyFrame.this); 295 } 296 } 297 }, waitCreate); 298 299 final MainFrame mainFrame = Icy.getMainInterface().getMainFrame(); 300 // listen main frame mode change 301 if (mainFrame != null) 302 mainFrame.addPropertyChangeListener(MainFrame.PROPERTY_DETACHEDMODE, this); 303 } 304 305 /** 306 * Permit IcyExternalFrame overriding 307 */ 308 protected IcyExternalFrame createExternalFrame(String title) 309 { 310 return new IcyExternalFrame(title); 311 } 312 313 /** 314 * Permit IcyInternalFrame overriding 315 */ 316 protected IcyInternalFrame createInternalFrame(String title, boolean resizable, boolean closable, 317 boolean maximizable, boolean iconifiable) 318 { 319 return new IcyInternalFrame(title, resizable, closable, maximizable, iconifiable); 320 } 321 322 /** 323 * Return true if the frame can be internalized 324 */ 325 protected boolean canBeInternalized() 326 { 327 final MainFrame frame = Icy.getMainInterface().getMainFrame(); 328 329 // internalization possible only in single window mode 330 if (frame != null) 331 return !frame.isDetachedMode(); 332 333 return false; 334 } 335 336 /** 337 * Refresh system menu 338 */ 339 public void updateSystemMenu() 340 { 341 // AWT safe 342 ThreadUtil.invoke(new Runnable() 343 { 344 @Override 345 public void run() 346 { 347 if (isInternalized()) 348 internalFrame.updateSystemMenu(); 349 else 350 externalFrame.updateSystemMenu(); 351 } 352 }, syncProcess); 353 } 354 355 /** 356 * Close frame (send closing event) 357 */ 358 public void close() 359 { 360 // AWT safe 361 ThreadUtil.invoke(new Runnable() 362 { 363 @Override 364 public void run() 365 { 366 internalFrame.close(true); 367 externalFrame.close(); 368 } 369 }, syncProcess); 370 } 371 372 /** 373 * Dispose frame (send closed event) 374 */ 375 public void dispose() 376 { 377 // AWT safe 378 ThreadUtil.invoke(new Runnable() 379 { 380 @Override 381 public void run() 382 { 383 if (isInternalized()) 384 internalFrame.dispose(); 385 else 386 externalFrame.dispose(); 387 } 388 }, syncProcess); 389 } 390 391 /** go from detached to attached and opposite */ 392 public void switchState() 393 { 394 if (isInternalized()) 395 detach(); 396 else 397 attach(); 398 } 399 400 /** set the frame to be an inner frame on the desktop pane */ 401 public void internalize() 402 { 403 if (isExternalized()) 404 attach(); 405 } 406 407 /** the frame becomes detached in an independent frame */ 408 public void externalize() 409 { 410 if (isInternalized()) 411 detach(); 412 } 413 414 /** Set the frame to be an inner frame on the desktop pane */ 415 public void attach() 416 { 417 if (isInternalized() || !canBeInternalized()) 418 return; 419 420 // AWT safe 421 ThreadUtil.invoke(new Runnable() 422 { 423 @Override 424 public void run() 425 { 426 // save current visible state 427 final boolean visible = externalFrame.isVisible(); 428 429 // hide external frame 430 if (visible) 431 externalFrame.setVisible(false); 432 433 final JMenuBar menuBar = externalFrame.getJMenuBar(); 434 final Container content = externalFrame.getContentPane(); 435 436 // remove components from external frame 437 externalFrame.setJMenuBar(null); 438 externalFrame.setContentPane(new JPanel()); 439 externalFrame.validate(); 440 441 internalFrame.setJMenuBar(menuBar); 442 internalFrame.setContentPane(content); 443 internalFrame.validate(); 444 445 // show internal frame 446 if (visible) 447 { 448 internalFrame.setVisible(true); 449 try 450 { 451 internalFrame.setSelected(true); 452 } 453 catch (PropertyVetoException e) 454 { 455 // ignore 456 } 457 } 458 459 state = IcyFrameState.INTERNALIZED; 460 461 // notify state change 462 stateChanged(); 463 } 464 }, syncProcess); 465 } 466 467 /** Set the frame to be detached in an independent frame */ 468 public void detach() 469 { 470 if (isExternalized()) 471 return; 472 473 // AWT safe 474 ThreadUtil.invoke(new Runnable() 475 { 476 @Override 477 public void run() 478 { 479 // save current visible state 480 final boolean visible = internalFrame.isVisible(); 481 482 // hide internal frame 483 if (visible) 484 internalFrame.setVisible(false); 485 486 final JMenuBar menuBar = internalFrame.getJMenuBar(); 487 final Container content = internalFrame.getContentPane(); 488 489 // remove components from internal frame 490 internalFrame.setJMenuBar(null); 491 internalFrame.setContentPane(new JPanel()); 492 internalFrame.validate(); 493 494 externalFrame.setJMenuBar(menuBar); 495 externalFrame.setContentPane(content); 496 externalFrame.validate(); 497 498 // show external frame 499 if (visible) 500 { 501 externalFrame.setVisible(true); 502 externalFrame.requestFocus(); 503 } 504 505 // TODO : we have to force a refresh with resizing or we get a refresh bug on 506 // scrollbar (OSX only ?) 507 // externalFrame.setSize(externalFrame.getWidth(), externalFrame.getHeight() - 1); 508 // externalFrame.setSize(externalFrame.getWidth(), externalFrame.getHeight() + 1); 509 510 state = IcyFrameState.EXTERNALIZED; 511 512 // notify state change 513 stateChanged(); 514 } 515 }, syncProcess); 516 } 517 518 /** 519 * Called on state (internalized / externalized) change 520 */ 521 public void stateChanged() 522 { 523 // refresh switch action state 524 switchStateAction.refreshState(); 525 526 // refresh system menu 527 updateSystemMenu(); 528 529 // fire event 530 if (isInternalized()) 531 fireFrameInternalized(new IcyFrameEvent(IcyFrame.this, null, null)); 532 else 533 fireFrameExternalized(new IcyFrameEvent(IcyFrame.this, null, null)); 534 } 535 536 /** Center frame on the desktop */ 537 public void center() 538 { 539 // AWT safe 540 ThreadUtil.invoke(new Runnable() 541 { 542 @Override 543 public void run() 544 { 545 if (isInternalized()) 546 ComponentUtil.center(internalFrame); 547 else 548 ComponentUtil.center(externalFrame); 549 550 } 551 }, syncProcess); 552 } 553 554 /** 555 * Add to the container c 556 */ 557 public void addTo(final Container c) 558 { 559 if (isInternalized()) 560 { 561 // AWT safe 562 ThreadUtil.invoke(new Runnable() 563 { 564 @Override 565 public void run() 566 { 567 c.add(internalFrame); 568 } 569 }, syncProcess); 570 } 571 } 572 573 /** 574 * Add to the container c 575 */ 576 public void addTo(final Container c, final int index) 577 { 578 if (isInternalized()) 579 { 580 // AWT safe 581 ThreadUtil.invoke(new Runnable() 582 { 583 @Override 584 public void run() 585 { 586 c.add(internalFrame, index); 587 } 588 }, syncProcess); 589 } 590 } 591 592 /** 593 * @deprecated Use {@link #addToDesktopPane()} instead. 594 */ 595 @Deprecated 596 public void addTo(final Container c, final Object constraints) 597 { 598 // AWT safe 599 ThreadUtil.invoke(new Runnable() 600 { 601 @Override 602 public void run() 603 { 604 c.add(internalFrame, constraints); 605 } 606 }, syncProcess); 607 } 608 609 /** 610 * Add the frame to the Icy desktop pane with specified constraint. 611 */ 612 public void addToDesktopPane(final Object constraints) 613 { 614 // AWT safe 615 ThreadUtil.invoke(new Runnable() 616 { 617 @Override 618 public void run() 619 { 620 final JDesktopPane desktop = Icy.getMainInterface().getDesktopPane(); 621 622 if (desktop != null) 623 desktop.add(internalFrame, constraints); 624 } 625 }, syncProcess); 626 } 627 628 /** 629 * Add the frame to the Icy desktop pane 630 */ 631 public void addToDesktopPane() 632 { 633 addToDesktopPane(JLayeredPane.DEFAULT_LAYER); 634 } 635 636 /** 637 * @deprecated Use {@link #addToDesktopPane()} instead. 638 */ 639 @Deprecated 640 public void addToMainDesktopPane() 641 { 642 addToDesktopPane(); 643 } 644 645 /** 646 * Implement add method 647 */ 648 public void add(final Component comp) 649 { 650 // AWT safe 651 ThreadUtil.invoke(new Runnable() 652 { 653 @Override 654 public void run() 655 { 656 if (isInternalized()) 657 internalFrame.add(comp); 658 else 659 externalFrame.add(comp); 660 } 661 }, syncProcess); 662 } 663 664 /** 665 * Implement add method 666 */ 667 public void add(final Component comp, final Object constraints) 668 { 669 // AWT safe 670 ThreadUtil.invoke(new Runnable() 671 { 672 @Override 673 public void run() 674 { 675 if (isInternalized()) 676 internalFrame.add(comp, constraints); 677 else 678 externalFrame.add(comp, constraints); 679 } 680 }, syncProcess); 681 } 682 683 /** 684 * Implement add method 685 */ 686 public void add(final String name, final Component comp) 687 { 688 // AWT safe 689 ThreadUtil.invoke(new Runnable() 690 { 691 @Override 692 public void run() 693 { 694 if (isInternalized()) 695 internalFrame.add(name, comp); 696 else 697 externalFrame.add(name, comp); 698 } 699 }, syncProcess); 700 } 701 702 /** 703 * Remove from the container 704 */ 705 public void removeFrom(final Container c) 706 { 707 // AWT safe 708 ThreadUtil.invoke(new Runnable() 709 { 710 @Override 711 public void run() 712 { 713 c.remove(internalFrame); 714 } 715 }, syncProcess); 716 } 717 718 /** 719 * Implement removeAll method 720 */ 721 public void removeAll() 722 { 723 // AWT safe 724 ThreadUtil.invoke(new Runnable() 725 { 726 @Override 727 public void run() 728 { 729 if (isInternalized()) 730 internalFrame.removeAll(); 731 else 732 externalFrame.removeAll(); 733 } 734 }, syncProcess); 735 } 736 737 /** 738 * Implement remove method 739 */ 740 public void remove(final Component comp) 741 { 742 // AWT safe 743 ThreadUtil.invoke(new Runnable() 744 { 745 @Override 746 public void run() 747 { 748 if (isInternalized()) 749 internalFrame.remove(comp); 750 else 751 externalFrame.remove(comp); 752 } 753 }, syncProcess); 754 } 755 756 /** 757 * Remove the frame from the main pane of ICY 758 */ 759 public void removeFromMainDesktopPane() 760 { 761 removeFrom(Icy.getMainInterface().getDesktopPane()); 762 } 763 764 /** 765 * Implement toFront method 766 */ 767 public void toFront() 768 { 769 // AWT safe 770 ThreadUtil.invoke(new Runnable() 771 { 772 @Override 773 public void run() 774 { 775 if (isInternalized()) 776 internalFrame.toFront(); 777 else 778 externalFrame.toFront(); 779 } 780 }, syncProcess); 781 } 782 783 /** 784 * Implement toBack method 785 */ 786 public void toBack() 787 { 788 // AWT safe 789 ThreadUtil.invoke(new Runnable() 790 { 791 @Override 792 public void run() 793 { 794 if (isInternalized()) 795 internalFrame.toBack(); 796 else 797 externalFrame.toBack(); 798 } 799 }, syncProcess); 800 } 801 802 /** 803 * Implement pack method 804 */ 805 public void pack() 806 { 807 // AWT safe 808 ThreadUtil.invoke(new Runnable() 809 { 810 @Override 811 public void run() 812 { 813 if (isInternalized()) 814 internalFrame.pack(); 815 else 816 externalFrame.pack(); 817 } 818 }, syncProcess); 819 } 820 821 public Container getFrame() 822 { 823 if (isInternalized()) 824 return internalFrame; 825 826 return externalFrame; 827 } 828 829 public IcyInternalFrame getIcyInternalFrame() 830 { 831 return internalFrame; 832 } 833 834 public IcyExternalFrame getIcyExternalFrame() 835 { 836 return externalFrame; 837 } 838 839 public JInternalFrame getInternalFrame() 840 { 841 return internalFrame; 842 } 843 844 public JFrame getExternalFrame() 845 { 846 return externalFrame; 847 } 848 849 /** 850 * Indicate if system menu show display item to switch frame state (internal / external) 851 */ 852 public void setSwitchStateItemVisible(boolean value) 853 { 854 if (switchStateItemVisible != value) 855 { 856 switchStateItemVisible = value; 857 switchStateAction.setEnabled(value); 858 updateSystemMenu(); 859 } 860 } 861 862 /** 863 * @return the systemMenuCallback 864 */ 865 public MenuCallback getSystemMenuCallback() 866 { 867 // always have same callback on each frame 868 final MenuCallback result = internalFrame.getSystemMenuCallback(); 869 870 // default callback ? this means we set it to null 871 if (result == defaultSystemMenuCallback) 872 return null; 873 874 return result; 875 } 876 877 /** 878 * Set the system menu callback (this allow modification of system menu) 879 * 880 * @param value 881 * the systemMenuCallback to set 882 */ 883 public void setSystemMenuCallback(MenuCallback value) 884 { 885 if (value != null) 886 { 887 internalFrame.setSystemMenuCallback(value); 888 externalFrame.setSystemMenuCallback(value); 889 } 890 else 891 { 892 internalFrame.setSystemMenuCallback(defaultSystemMenuCallback); 893 externalFrame.setSystemMenuCallback(defaultSystemMenuCallback); 894 } 895 } 896 897 /** 898 * Return the default system menu 899 */ 900 public JMenu getDefaultSystemMenu() 901 { 902 final JMenu result; 903 904 if (isInternalized()) 905 result = internalFrame.getDefaultSystemMenu(); 906 else 907 result = externalFrame.getDefaultSystemMenu(); 908 909 if (switchStateItemVisible) 910 { 911 result.insert(switchStateAction, 0); 912 if (result.getMenuComponentCount() > 1) 913 result.insertSeparator(1); 914 } 915 916 return result; 917 } 918 919 /** 920 * Implement getParent 921 */ 922 public Container getParent() 923 { 924 if (isInternalized()) 925 return internalFrame.getParent(); 926 927 return externalFrame.getParent(); 928 } 929 930 /** 931 * Implement getContentPane method 932 */ 933 public Container getContentPane() 934 { 935 if (isInternalized()) 936 return internalFrame.getContentPane(); 937 938 return externalFrame.getContentPane(); 939 } 940 941 /** 942 * Implement getRootPane method 943 */ 944 public JRootPane getRootPane() 945 { 946 if (isInternalized()) 947 return internalFrame.getRootPane(); 948 949 return externalFrame.getRootPane(); 950 } 951 952 public Border getBorder() 953 { 954 if (isInternalized()) 955 return internalFrame.getBorder(); 956 957 return null; 958 } 959 960 /** 961 * @return the switchStateAction 962 */ 963 public SwitchStateAction getSwitchStateAction() 964 { 965 return switchStateAction; 966 } 967 968 /** 969 * Implement getMinimumSize method 970 */ 971 public Dimension getMinimumSize() 972 { 973 if (isInternalized()) 974 return internalFrame.getMinimumSize(); 975 976 return externalFrame.getMinimumSize(); 977 } 978 979 /** 980 * Implement getMinimumSize method for internal frame only 981 */ 982 public Dimension getMinimumSizeInternal() 983 { 984 return internalFrame.getMinimumSize(); 985 } 986 987 /** 988 * Implement getMinimumSize method for external frame only 989 */ 990 public Dimension getMinimumSizeExternal() 991 { 992 return externalFrame.getMinimumSize(); 993 } 994 995 /** 996 * Implement getMaximumSize method 997 */ 998 public Dimension getMaximumSize() 999 { 1000 if (isInternalized()) 1001 return internalFrame.getMaximumSize(); 1002 1003 return externalFrame.getMaximumSize(); 1004 } 1005 1006 /** 1007 * Implement getMaximumSize method for internal frame only 1008 */ 1009 public Dimension getMaximumSizeInternal() 1010 { 1011 return internalFrame.getMaximumSize(); 1012 } 1013 1014 /** 1015 * Implement getMaximumSize method for external frame only 1016 */ 1017 public Dimension getMaximumSizeExternal() 1018 { 1019 return externalFrame.getMaximumSize(); 1020 } 1021 1022 /** 1023 * Implement getPreferredSize method 1024 */ 1025 public Dimension getPreferredSize() 1026 { 1027 if (isInternalized()) 1028 return internalFrame.getPreferredSize(); 1029 1030 return externalFrame.getPreferredSize(); 1031 } 1032 1033 /** 1034 * Implement getPreferredSize method for internal frame only 1035 */ 1036 public Dimension getPreferredSizeInternal() 1037 { 1038 return internalFrame.getPreferredSize(); 1039 } 1040 1041 /** 1042 * Implement getPreferredSize method for external frame only 1043 */ 1044 public Dimension getPreferredSizeExternal() 1045 { 1046 return externalFrame.getPreferredSize(); 1047 } 1048 1049 /** 1050 * Implement getSize method 1051 */ 1052 public Dimension getSize() 1053 { 1054 if (isInternalized()) 1055 return internalFrame.getSize(); 1056 1057 return externalFrame.getSize(); 1058 } 1059 1060 /** 1061 * Implement getSize method for internal frame only 1062 */ 1063 public Dimension getSizeInternal() 1064 { 1065 return internalFrame.getSize(); 1066 } 1067 1068 /** 1069 * Implement getSize method for external frame only 1070 */ 1071 public Dimension getSizeExternal() 1072 { 1073 return externalFrame.getSize(); 1074 } 1075 1076 /** 1077 * Implement getHeight method 1078 */ 1079 public int getHeight() 1080 { 1081 if (isInternalized()) 1082 return internalFrame.getHeight(); 1083 1084 return externalFrame.getHeight(); 1085 } 1086 1087 /** 1088 * Implement getHeight method for internal frame only 1089 */ 1090 public int getHeightInternal() 1091 { 1092 return internalFrame.getHeight(); 1093 } 1094 1095 /** 1096 * Implement getHeight method for external frame only 1097 */ 1098 public int getHeightExternal() 1099 { 1100 return externalFrame.getHeight(); 1101 } 1102 1103 /** 1104 * Implement getWidth method 1105 */ 1106 public int getWidth() 1107 { 1108 if (isInternalized()) 1109 return internalFrame.getWidth(); 1110 1111 return externalFrame.getWidth(); 1112 } 1113 1114 /** 1115 * Implement getWidth method for internal frame only 1116 */ 1117 public int getWidthInternal() 1118 { 1119 return internalFrame.getWidth(); 1120 } 1121 1122 /** 1123 * Implement getWidth method for external frame only 1124 */ 1125 public int getWidthExternal() 1126 { 1127 return externalFrame.getWidth(); 1128 } 1129 1130 /** 1131 * Implement getX method 1132 */ 1133 public int getX() 1134 { 1135 if (isInternalized()) 1136 return internalFrame.getX(); 1137 1138 return externalFrame.getX(); 1139 } 1140 1141 /** 1142 * Implement getX method for internal frame only 1143 */ 1144 public int getXInternal() 1145 { 1146 return internalFrame.getX(); 1147 } 1148 1149 /** 1150 * Implement getX method for external frame only 1151 */ 1152 public int getXExternal() 1153 { 1154 return externalFrame.getX(); 1155 } 1156 1157 /** 1158 * Implement getY method 1159 */ 1160 public int getY() 1161 { 1162 if (isInternalized()) 1163 return internalFrame.getY(); 1164 1165 return externalFrame.getY(); 1166 } 1167 1168 /** 1169 * Implement getY method for internal frame only 1170 */ 1171 public int getYInternal() 1172 { 1173 return internalFrame.getY(); 1174 } 1175 1176 /** 1177 * Implement getY method for external frame only 1178 */ 1179 public int getYExternal() 1180 { 1181 return externalFrame.getY(); 1182 } 1183 1184 /** 1185 * Implement getLocation method 1186 */ 1187 public Point getLocation() 1188 { 1189 if (isInternalized()) 1190 return internalFrame.getLocation(); 1191 1192 return externalFrame.getLocation(); 1193 } 1194 1195 /** 1196 * Implement getLocation method 1197 */ 1198 public Point getLocationInternal() 1199 { 1200 return internalFrame.getLocation(); 1201 } 1202 1203 /** 1204 * Implement getLocation method for external frame only 1205 */ 1206 public Point getLocationExternal() 1207 { 1208 return externalFrame.getLocation(); 1209 } 1210 1211 /** 1212 * Implement getBounds method 1213 */ 1214 public Rectangle getBounds() 1215 { 1216 if (isInternalized()) 1217 return internalFrame.getBounds(); 1218 1219 return externalFrame.getBounds(); 1220 } 1221 1222 /** 1223 * Implement getBounds method for internal frame only 1224 */ 1225 public Rectangle getBoundsInternal() 1226 { 1227 return internalFrame.getBounds(); 1228 } 1229 1230 /** 1231 * Implement getBounds method for external frame only 1232 */ 1233 public Rectangle getBoundsExternal() 1234 { 1235 return externalFrame.getBounds(); 1236 } 1237 1238 /** 1239 * Implement getBounds method for external frame only 1240 */ 1241 public Rectangle getVisibleRect() 1242 { 1243 if (isInternalized()) 1244 return internalFrame.getVisibleRect(); 1245 1246 // not supported on external frame 1247 if (externalFrame.isVisible()) 1248 return externalFrame.getBounds(); 1249 1250 return new Rectangle(); 1251 } 1252 1253 /** 1254 * Implement getJMenuBar method 1255 */ 1256 public JMenuBar getJMenuBar() 1257 { 1258 if (isInternalized()) 1259 return internalFrame.getJMenuBar(); 1260 1261 return externalFrame.getJMenuBar(); 1262 } 1263 1264 /** 1265 * Returns the content pane InputMap 1266 */ 1267 public InputMap getInputMap(int condition) 1268 { 1269 if (isInternalized()) 1270 return ((JPanel) internalFrame.getContentPane()).getInputMap(condition); 1271 1272 return ((JPanel) externalFrame.getContentPane()).getInputMap(condition); 1273 } 1274 1275 /** 1276 * Returns the content pane InputMap 1277 */ 1278 public ActionMap getActionMap() 1279 { 1280 if (isInternalized()) 1281 return ((JPanel) internalFrame.getContentPane()).getActionMap(); 1282 1283 return ((JPanel) externalFrame.getContentPane()).getActionMap(); 1284 } 1285 1286 /** 1287 * Implement getToolkit method 1288 */ 1289 public Toolkit getToolkit() 1290 { 1291 if (isInternalized()) 1292 return internalFrame.getToolkit(); 1293 1294 return externalFrame.getToolkit(); 1295 } 1296 1297 /** 1298 * Implement setTitle method 1299 */ 1300 public String getTitle() 1301 { 1302 if (isInternalized()) 1303 return internalFrame.getTitle(); 1304 1305 return externalFrame.getTitle(); 1306 } 1307 1308 /** 1309 * Return true if title bar is visible 1310 */ 1311 public boolean getTitleBarVisible() 1312 { 1313 if (isInternalized()) 1314 return internalFrame.isTitleBarVisible(); 1315 1316 return externalFrame.isTitleBarVisible(); 1317 } 1318 1319 /** 1320 * @return the displaySwitchStateItem 1321 */ 1322 public boolean isSwitchStateItemVisible() 1323 { 1324 return switchStateItemVisible; 1325 } 1326 1327 /** 1328 * Implement getMousePosition method 1329 */ 1330 public Point getMousePosition() 1331 { 1332 if (isInternalized()) 1333 return internalFrame.getMousePosition(); 1334 1335 return externalFrame.getMousePosition(); 1336 } 1337 1338 /** 1339 * Implement isMinimized method 1340 */ 1341 public boolean isMinimized() 1342 { 1343 if (isInternalized()) 1344 return internalFrame.isIcon(); 1345 1346 return ComponentUtil.isMinimized(externalFrame); 1347 } 1348 1349 /** 1350 * Implement isMinimized method for internal frame only 1351 */ 1352 public boolean isMinimizedInternal() 1353 { 1354 return internalFrame.isIcon(); 1355 } 1356 1357 /** 1358 * Implement isMinimized method for external frame only 1359 */ 1360 public boolean isMinimizedExternal() 1361 { 1362 return ComponentUtil.isMinimized(externalFrame); 1363 } 1364 1365 /** 1366 * Implement isMaximized method 1367 */ 1368 public boolean isMaximized() 1369 { 1370 if (isInternalized()) 1371 return internalFrame.isMaximum(); 1372 1373 return ComponentUtil.isMaximized(externalFrame); 1374 } 1375 1376 /** 1377 * Implement isMaximized method for internal frame only 1378 */ 1379 public boolean isMaximizedInternal() 1380 { 1381 return internalFrame.isMaximum(); 1382 } 1383 1384 /** 1385 * Implement isMaximized method for external frame only 1386 */ 1387 public boolean isMaximizedExternal() 1388 { 1389 return ComponentUtil.isMaximized(externalFrame); 1390 } 1391 1392 /** 1393 * Implement isVisible method 1394 */ 1395 public boolean isVisible() 1396 { 1397 if (isInternalized()) 1398 return internalFrame.isVisible(); 1399 1400 return externalFrame.isVisible(); 1401 } 1402 1403 /** 1404 * Implement isResizable method 1405 */ 1406 public boolean isResizable() 1407 { 1408 if (isInternalized()) 1409 return internalFrame.isResizable(); 1410 1411 return externalFrame.isResizable(); 1412 } 1413 1414 /** 1415 * Implement isClosable method 1416 */ 1417 public boolean isClosable() 1418 { 1419 if (isInternalized()) 1420 return internalFrame.isClosable(); 1421 1422 // external frame is always closable 1423 return true; 1424 } 1425 1426 /** 1427 * return true if frame is in internalized state 1428 */ 1429 public boolean isInternalized() 1430 { 1431 return (state == IcyFrameState.INTERNALIZED); 1432 } 1433 1434 /** 1435 * return true if frame is in externalized state 1436 */ 1437 public boolean isExternalized() 1438 { 1439 return (state == IcyFrameState.EXTERNALIZED); 1440 } 1441 1442 /** 1443 * return true if frame is active 1444 */ 1445 public boolean isActive() 1446 { 1447 if (isInternalized()) 1448 return internalFrame.isSelected(); 1449 1450 return externalFrame.isActive(); 1451 } 1452 1453 /** 1454 * Implement isAlwaysOnTop method (only for externalized frame) 1455 */ 1456 public boolean isAlwaysOnTop() 1457 { 1458 return externalFrame.isAlwaysOnTop(); 1459 } 1460 1461 /** 1462 * Implement hasFocus method 1463 */ 1464 public boolean hasFocus() 1465 { 1466 if (isInternalized()) 1467 return internalFrame.hasFocus(); 1468 1469 return externalFrame.hasFocus(); 1470 } 1471 1472 /** 1473 * Implement setTitle method 1474 */ 1475 public void setTitle(final String title) 1476 { 1477 // AWT safe 1478 ThreadUtil.invoke(new Runnable() 1479 { 1480 @Override 1481 public void run() 1482 { 1483 internalFrame.setTitle(title); 1484 externalFrame.setTitle(title); 1485 } 1486 }, syncProcess); 1487 } 1488 1489 /** 1490 * Implement setToolTipText method (only for internalized frame) 1491 */ 1492 public void setToolTipText(final String text) 1493 { 1494 // AWT safe 1495 ThreadUtil.invoke(new Runnable() 1496 { 1497 @Override 1498 public void run() 1499 { 1500 // only internal frame support it 1501 internalFrame.setToolTipText(text); 1502 // externalFrame.setToolTipText(text); 1503 } 1504 }, syncProcess); 1505 } 1506 1507 /** 1508 * Implement setBackground method 1509 */ 1510 public void setBackground(final Color value) 1511 { 1512 // AWT safe 1513 ThreadUtil.invoke(new Runnable() 1514 { 1515 @Override 1516 public void run() 1517 { 1518 internalFrame.setBackground(value); 1519 externalFrame.setBackground(value); 1520 } 1521 }, syncProcess); 1522 } 1523 1524 /** 1525 * Implement setForeground method 1526 */ 1527 public void setForeground(final Color value) 1528 { 1529 // AWT safe 1530 ThreadUtil.invoke(new Runnable() 1531 { 1532 @Override 1533 public void run() 1534 { 1535 internalFrame.setForeground(value); 1536 externalFrame.setForeground(value); 1537 } 1538 }, syncProcess); 1539 } 1540 1541 /** 1542 * Implement setResizable method 1543 */ 1544 public void setResizable(final boolean value) 1545 { 1546 // AWT safe 1547 ThreadUtil.invoke(new Runnable() 1548 { 1549 @Override 1550 public void run() 1551 { 1552 internalFrame.setResizable(value); 1553 externalFrame.setResizable(value); 1554 } 1555 }, syncProcess); 1556 1557 } 1558 1559 /** 1560 * Implement setLocation method 1561 */ 1562 public void setLocation(final Point p) 1563 { 1564 // AWT safe 1565 ThreadUtil.invoke(new Runnable() 1566 { 1567 @Override 1568 public void run() 1569 { 1570 if (isInternalized()) 1571 internalFrame.setLocation(p); 1572 else 1573 externalFrame.setLocation(p); 1574 } 1575 }, syncProcess); 1576 } 1577 1578 /** 1579 * Implement setLocation method 1580 */ 1581 public void setLocation(final int x, final int y) 1582 { 1583 // AWT safe 1584 ThreadUtil.invoke(new Runnable() 1585 { 1586 @Override 1587 public void run() 1588 { 1589 if (isInternalized()) 1590 internalFrame.setLocation(x, y); 1591 else 1592 externalFrame.setLocation(x, y); 1593 } 1594 }, syncProcess); 1595 } 1596 1597 /** 1598 * Implement setLocation method for internal frame only 1599 */ 1600 public void setLocationInternal(final Point p) 1601 { 1602 // AWT safe 1603 ThreadUtil.invoke(new Runnable() 1604 { 1605 @Override 1606 public void run() 1607 { 1608 internalFrame.setLocation(p); 1609 } 1610 }, syncProcess); 1611 } 1612 1613 /** 1614 * Implement setLocation method for internal frame only 1615 */ 1616 public void setLocationInternal(final int x, final int y) 1617 { 1618 // AWT safe 1619 ThreadUtil.invoke(new Runnable() 1620 { 1621 @Override 1622 public void run() 1623 { 1624 internalFrame.setLocation(x, y); 1625 } 1626 }, syncProcess); 1627 } 1628 1629 /** 1630 * Implement setLocation method for external frame only 1631 */ 1632 public void setLocationExternal(final Point p) 1633 { 1634 // AWT safe 1635 ThreadUtil.invoke(new Runnable() 1636 { 1637 @Override 1638 public void run() 1639 { 1640 externalFrame.setLocation(p); 1641 } 1642 }, syncProcess); 1643 } 1644 1645 /** 1646 * Implement setLocation method for external frame only 1647 */ 1648 public void setLocationExternal(final int x, final int y) 1649 { 1650 // AWT safe 1651 ThreadUtil.invoke(new Runnable() 1652 { 1653 @Override 1654 public void run() 1655 { 1656 externalFrame.setLocation(x, y); 1657 } 1658 }, syncProcess); 1659 } 1660 1661 /** 1662 * Implement setSize method 1663 */ 1664 public void setSize(final Dimension d) 1665 { 1666 // AWT safe 1667 ThreadUtil.invoke(new Runnable() 1668 { 1669 @Override 1670 public void run() 1671 { 1672 if (isInternalized()) 1673 internalFrame.setSize(d); 1674 else 1675 externalFrame.setSize(d); 1676 } 1677 }, syncProcess); 1678 } 1679 1680 /** 1681 * Implement setSize method 1682 */ 1683 public void setSize(final int width, final int height) 1684 { 1685 // AWT safe 1686 ThreadUtil.invoke(new Runnable() 1687 { 1688 @Override 1689 public void run() 1690 { 1691 if (isInternalized()) 1692 internalFrame.setSize(width, height); 1693 else 1694 externalFrame.setSize(width, height); 1695 } 1696 }, syncProcess); 1697 } 1698 1699 /** 1700 * Implement setSize method for internal frame only 1701 */ 1702 public void setSizeInternal(final Dimension d) 1703 { 1704 // AWT safe 1705 ThreadUtil.invoke(new Runnable() 1706 { 1707 @Override 1708 public void run() 1709 { 1710 internalFrame.setSize(d); 1711 } 1712 }, syncProcess); 1713 } 1714 1715 /** 1716 * Implement setSize method for internal frame only 1717 */ 1718 public void setSizeInternal(final int width, final int height) 1719 { 1720 // AWT safe 1721 ThreadUtil.invoke(new Runnable() 1722 { 1723 @Override 1724 public void run() 1725 { 1726 internalFrame.setSize(width, height); 1727 } 1728 }, syncProcess); 1729 } 1730 1731 /** 1732 * Implement setSize method for external frame only 1733 */ 1734 public void setSizeExternal(final Dimension d) 1735 { 1736 // AWT safe 1737 ThreadUtil.invoke(new Runnable() 1738 { 1739 @Override 1740 public void run() 1741 { 1742 externalFrame.setSize(d); 1743 } 1744 }, syncProcess); 1745 } 1746 1747 /** 1748 * Implement setSize method for external frame only 1749 */ 1750 public void setSizeExternal(final int width, final int height) 1751 { 1752 // AWT safe 1753 ThreadUtil.invoke(new Runnable() 1754 { 1755 @Override 1756 public void run() 1757 { 1758 externalFrame.setSize(width, height); 1759 } 1760 }, syncProcess); 1761 } 1762 1763 /** 1764 * Implement setPreferredSize method 1765 */ 1766 public void setPreferredSize(final Dimension d) 1767 { 1768 // AWT safe 1769 ThreadUtil.invoke(new Runnable() 1770 { 1771 @Override 1772 public void run() 1773 { 1774 if (isInternalized()) 1775 internalFrame.setPreferredSize(d); 1776 else 1777 externalFrame.setPreferredSize(d); 1778 } 1779 }, syncProcess); 1780 } 1781 1782 /** 1783 * Implement setPreferredSize method for internal frame only 1784 */ 1785 public void setPreferredSizeInternal(final Dimension d) 1786 { 1787 // AWT safe 1788 ThreadUtil.invoke(new Runnable() 1789 { 1790 @Override 1791 public void run() 1792 { 1793 internalFrame.setPreferredSize(d); 1794 } 1795 }, syncProcess); 1796 } 1797 1798 /** 1799 * Implement setPreferredSize method for external frame only 1800 */ 1801 public void setPreferredSizeExternal(final Dimension d) 1802 { 1803 // AWT safe 1804 ThreadUtil.invoke(new Runnable() 1805 { 1806 @Override 1807 public void run() 1808 { 1809 externalFrame.setPreferredSize(d); 1810 } 1811 }, syncProcess); 1812 } 1813 1814 /** 1815 * Implement setMinimumSize method 1816 */ 1817 public void setMinimumSize(final Dimension d) 1818 { 1819 // AWT safe 1820 ThreadUtil.invoke(new Runnable() 1821 { 1822 @Override 1823 public void run() 1824 { 1825 if (isInternalized()) 1826 internalFrame.setMinimumSize(d); 1827 else 1828 externalFrame.setMinimumSize(d); 1829 } 1830 }, syncProcess); 1831 } 1832 1833 /** 1834 * Implement setMaximumSize method 1835 */ 1836 public void setMaximumSize(final Dimension d) 1837 { 1838 // AWT safe 1839 ThreadUtil.invoke(new Runnable() 1840 { 1841 @Override 1842 public void run() 1843 { 1844 if (isInternalized()) 1845 internalFrame.setMaximumSize(d); 1846 else 1847 externalFrame.setMaximumSize(d); 1848 } 1849 }, syncProcess); 1850 } 1851 1852 /** 1853 * Implement setMinimumSize method for internal frame only 1854 */ 1855 public void setMinimumSizeInternal(final Dimension d) 1856 { 1857 // AWT safe 1858 ThreadUtil.invoke(new Runnable() 1859 { 1860 @Override 1861 public void run() 1862 { 1863 internalFrame.setMinimumSize(d); 1864 } 1865 }, syncProcess); 1866 } 1867 1868 /** 1869 * Implement setMaximumSize method for internal frame only 1870 */ 1871 public void setMaximumSizeInternal(final Dimension d) 1872 { 1873 // AWT safe 1874 ThreadUtil.invoke(new Runnable() 1875 { 1876 @Override 1877 public void run() 1878 { 1879 internalFrame.setMaximumSize(d); 1880 } 1881 }, syncProcess); 1882 } 1883 1884 /** 1885 * Implement setMinimumSize method for external frame only 1886 */ 1887 public void setMinimumSizeExternal(final Dimension d) 1888 { 1889 // AWT safe 1890 ThreadUtil.invoke(new Runnable() 1891 { 1892 @Override 1893 public void run() 1894 { 1895 externalFrame.setMinimumSize(d); 1896 } 1897 }, syncProcess); 1898 } 1899 1900 /** 1901 * Implement setMaximumSize method for external frame only 1902 */ 1903 public void setMaximumSizeExternal(final Dimension d) 1904 { 1905 // AWT safe 1906 ThreadUtil.invoke(new Runnable() 1907 { 1908 @Override 1909 public void run() 1910 { 1911 externalFrame.setMaximumSize(d); 1912 } 1913 }, syncProcess); 1914 } 1915 1916 /** 1917 * Implement setBounds method 1918 */ 1919 public void setBounds(final Rectangle r) 1920 { 1921 // AWT safe 1922 ThreadUtil.invoke(new Runnable() 1923 { 1924 @Override 1925 public void run() 1926 { 1927 if (isInternalized()) 1928 internalFrame.setBounds(r); 1929 else 1930 externalFrame.setBounds(r); 1931 } 1932 }, syncProcess); 1933 1934 } 1935 1936 /** 1937 * Implement setMaximisable method 1938 */ 1939 public void setMaximisable(final boolean value) 1940 { 1941 // AWT safe 1942 ThreadUtil.invoke(new Runnable() 1943 { 1944 @Override 1945 public void run() 1946 { 1947 // only for internal frame 1948 internalFrame.setMaximizable(value); 1949 } 1950 }, syncProcess); 1951 } 1952 1953 /** 1954 * Implement setMinimized method 1955 */ 1956 public void setMinimized(final boolean value) 1957 { 1958 // only relevant if state changed 1959 if (isMinimized() ^ value) 1960 { 1961 // AWT safe 1962 ThreadUtil.invoke(new Runnable() 1963 { 1964 @Override 1965 public void run() 1966 { 1967 if (isInternalized()) 1968 internalFrame.setMinimized(value); 1969 else 1970 externalFrame.setMinimized(value); 1971 } 1972 }, syncProcess); 1973 } 1974 } 1975 1976 /** 1977 * Implement setMinimized method for internal frame only 1978 */ 1979 public void setMinimizedInternal(final boolean value) 1980 { 1981 // only relevant if state changed 1982 if (internalFrame.isMinimized() ^ value) 1983 { 1984 // AWT safe 1985 ThreadUtil.invoke(new Runnable() 1986 { 1987 @Override 1988 public void run() 1989 { 1990 internalFrame.setMinimized(value); 1991 } 1992 }, syncProcess); 1993 } 1994 } 1995 1996 /** 1997 * Implement setMinimized method for external frame only 1998 */ 1999 public void setMinimizedExternal(final boolean value) 2000 { 2001 // only relevant if state changed 2002 if (externalFrame.isMinimized() ^ value) 2003 { 2004 // AWT safe 2005 ThreadUtil.invoke(new Runnable() 2006 { 2007 @Override 2008 public void run() 2009 { 2010 externalFrame.setMinimized(value); 2011 } 2012 }, syncProcess); 2013 } 2014 } 2015 2016 /** 2017 * Implement setMaximized method 2018 */ 2019 public void setMaximized(final boolean value) 2020 { 2021 // only relevant if state changed 2022 if (isMaximized() ^ value) 2023 { 2024 // AWT safe 2025 ThreadUtil.invoke(new Runnable() 2026 { 2027 @Override 2028 public void run() 2029 { 2030 if (isInternalized()) 2031 internalFrame.setMaximized(value); 2032 else 2033 externalFrame.setMaximized(value); 2034 } 2035 }, syncProcess); 2036 } 2037 } 2038 2039 /** 2040 * Implement setMaximized method for internal frame only 2041 */ 2042 public void setMaximizedInternal(final boolean value) 2043 { 2044 // only relevant if state changed 2045 if (internalFrame.isMaximized() ^ value) 2046 { 2047 // AWT safe 2048 ThreadUtil.invoke(new Runnable() 2049 { 2050 @Override 2051 public void run() 2052 { 2053 internalFrame.setMaximized(value); 2054 } 2055 }, syncProcess); 2056 } 2057 } 2058 2059 /** 2060 * Implement setMaximized method for external frame only 2061 */ 2062 public void setMaximizedExternal(final boolean value) 2063 { 2064 // only relevant if state changed 2065 if (externalFrame.isMaximized() ^ value) 2066 { 2067 // AWT safe 2068 ThreadUtil.invoke(new Runnable() 2069 { 2070 @Override 2071 public void run() 2072 { 2073 externalFrame.setMaximized(value); 2074 } 2075 }, syncProcess); 2076 } 2077 } 2078 2079 /** 2080 * Implement setClosable method 2081 */ 2082 public void setClosable(final boolean value) 2083 { 2084 // AWT safe 2085 ThreadUtil.invoke(new Runnable() 2086 { 2087 @Override 2088 public void run() 2089 { 2090 internalFrame.setClosable(value); 2091 } 2092 }, syncProcess); 2093 } 2094 2095 /** 2096 * Implement setDefaultCloseOperation method 2097 * 2098 * @see JFrame#setDefaultCloseOperation(int) 2099 */ 2100 public void setDefaultCloseOperation(final int operation) 2101 { 2102 // AWT safe 2103 ThreadUtil.invoke(new Runnable() 2104 { 2105 @Override 2106 public void run() 2107 { 2108 internalFrame.setDefaultCloseOperation(operation); 2109 externalFrame.setDefaultCloseOperation(operation); 2110 } 2111 }, syncProcess); 2112 } 2113 2114 /** 2115 * Implement setFocusable method 2116 */ 2117 public void setFocusable(final boolean value) 2118 { 2119 // AWT safe 2120 ThreadUtil.invoke(new Runnable() 2121 { 2122 @Override 2123 public void run() 2124 { 2125 internalFrame.setFocusable(value); 2126 externalFrame.setFocusable(value); 2127 } 2128 }, syncProcess); 2129 } 2130 2131 /** 2132 * Implement setVisible method 2133 */ 2134 public void setVisible(final boolean value) 2135 { 2136 // AWT safe 2137 ThreadUtil.invoke(new Runnable() 2138 { 2139 @Override 2140 public void run() 2141 { 2142 if (isInternalized()) 2143 internalFrame.setVisible(value); 2144 else 2145 externalFrame.setVisible(value); 2146 } 2147 }, syncProcess); 2148 } 2149 2150 /** 2151 * Implement setAlwaysOnTop method (only for externalized frame) 2152 */ 2153 public void setAlwaysOnTop(final boolean alwaysOnTop) 2154 { 2155 // AWT safe 2156 ThreadUtil.invoke(new Runnable() 2157 { 2158 @Override 2159 public void run() 2160 { 2161 externalFrame.setAlwaysOnTop(alwaysOnTop); 2162 } 2163 }, syncProcess); 2164 } 2165 2166 /** 2167 * Implement setJMenuBar method 2168 */ 2169 public void setJMenuBar(final JMenuBar m) 2170 { 2171 // AWT safe 2172 ThreadUtil.invoke(new Runnable() 2173 { 2174 @Override 2175 public void run() 2176 { 2177 if (isInternalized()) 2178 internalFrame.setJMenuBar(m); 2179 else 2180 externalFrame.setJMenuBar(m); 2181 } 2182 }, syncProcess); 2183 } 2184 2185 /** 2186 * Hide or show the title bar (frame should not be displayable when you set this property) 2187 */ 2188 public void setTitleBarVisible(final boolean value) 2189 { 2190 // AWT safe 2191 ThreadUtil.invoke(new Runnable() 2192 { 2193 @Override 2194 public void run() 2195 { 2196 internalFrame.setTitleBarVisible(value); 2197 externalFrame.setTitleBarVisible(value); 2198 } 2199 }, syncProcess); 2200 } 2201 2202 /** 2203 * Implement setLayout method 2204 */ 2205 public void setLayout(final LayoutManager layout) 2206 { 2207 // AWT safe 2208 ThreadUtil.invoke(new Runnable() 2209 { 2210 @Override 2211 public void run() 2212 { 2213 if (isInternalized()) 2214 internalFrame.setLayout(layout); 2215 else 2216 externalFrame.setLayout(layout); 2217 } 2218 }, syncProcess); 2219 } 2220 2221 /** 2222 * Implement setBorder method (only for internal frame) 2223 */ 2224 public void setBorder(final Border border) 2225 { 2226 // AWT safe 2227 ThreadUtil.invoke(new Runnable() 2228 { 2229 @Override 2230 public void run() 2231 { 2232 internalFrame.setBorder(border); 2233 } 2234 }, syncProcess); 2235 } 2236 2237 /** 2238 * Implement setContentPane method 2239 */ 2240 public void setContentPane(final Container value) 2241 { 2242 // AWT safe 2243 ThreadUtil.invoke(new Runnable() 2244 { 2245 @Override 2246 public void run() 2247 { 2248 if (isInternalized()) 2249 internalFrame.setContentPane(value); 2250 else 2251 externalFrame.setContentPane(value); 2252 } 2253 }, syncProcess); 2254 } 2255 2256 /** 2257 * @return the syncProcess 2258 */ 2259 public boolean isSyncProcess() 2260 { 2261 return syncProcess; 2262 } 2263 2264 /** 2265 * By default IcyFrame does asych processing, you can force sync processing<br> 2266 * with this property 2267 * 2268 * @param syncProcess 2269 * the syncProcess to set 2270 */ 2271 public void setSyncProcess(boolean syncProcess) 2272 { 2273 this.syncProcess = syncProcess; 2274 } 2275 2276 /** 2277 * Frame becomes the active/focused frame 2278 */ 2279 public void requestFocus() 2280 { 2281 // AWT safe 2282 ThreadUtil.invoke(new Runnable() 2283 { 2284 @Override 2285 public void run() 2286 { 2287 if (isInternalized()) 2288 { 2289 try 2290 { 2291 internalFrame.setSelected(true); 2292 } 2293 catch (PropertyVetoException e) 2294 { 2295 // ignore 2296 } 2297 } 2298 else 2299 externalFrame.requestFocus(); 2300 } 2301 }, syncProcess); 2302 } 2303 2304 /** 2305 * Implement validate 2306 */ 2307 public void validate() 2308 { 2309 // AWT safe 2310 ThreadUtil.invoke(new Runnable() 2311 { 2312 @Override 2313 public void run() 2314 { 2315 if (isInternalized()) 2316 internalFrame.validate(); 2317 else 2318 externalFrame.validate(); 2319 } 2320 }, syncProcess); 2321 } 2322 2323 /** 2324 * Implement revalidate 2325 */ 2326 public void revalidate() 2327 { 2328 // AWT safe 2329 ThreadUtil.invoke(new Runnable() 2330 { 2331 @Override 2332 public void run() 2333 { 2334 if (isInternalized()) 2335 internalFrame.revalidate(); 2336 else 2337 { 2338 externalFrame.invalidate(); 2339 externalFrame.repaint(); 2340 } 2341 } 2342 }, syncProcess); 2343 } 2344 2345 /** 2346 * Implement repaint 2347 */ 2348 public void repaint() 2349 { 2350 // AWT safe 2351 ThreadUtil.invoke(new Runnable() 2352 { 2353 @Override 2354 public void run() 2355 { 2356 if (isInternalized()) 2357 internalFrame.repaint(); 2358 else 2359 externalFrame.repaint(); 2360 } 2361 }, syncProcess); 2362 } 2363 2364 /** 2365 * Implement updateUI 2366 */ 2367 public void updateUI() 2368 { 2369 // AWT safe 2370 ThreadUtil.invoke(new Runnable() 2371 { 2372 @Override 2373 public void run() 2374 { 2375 internalFrame.updateUI(); 2376 } 2377 }, syncProcess); 2378 } 2379 2380 /** 2381 * Fire frame activated event 2382 */ 2383 private void fireFrameActivated(IcyFrameEvent e) 2384 { 2385 for (IcyFrameListener l : frameEventListeners.getListeners(IcyFrameListener.class)) 2386 l.icyFrameActivated(e); 2387 } 2388 2389 /** 2390 * Fire frame deactivated event 2391 */ 2392 private void fireFrameDeactivated(IcyFrameEvent e) 2393 { 2394 for (IcyFrameListener l : frameEventListeners.getListeners(IcyFrameListener.class)) 2395 l.icyFrameDeactivated(e); 2396 } 2397 2398 /** 2399 * Fire frame closing event 2400 */ 2401 private void fireFrameClosing(IcyFrameEvent e) 2402 { 2403 for (IcyFrameListener l : frameEventListeners.getListeners(IcyFrameListener.class)) 2404 l.icyFrameClosing(e); 2405 } 2406 2407 /** 2408 * Fire frame closed event 2409 */ 2410 private void fireFrameClosed(IcyFrameEvent e) 2411 { 2412 for (IcyFrameListener l : frameEventListeners.getListeners(IcyFrameListener.class)) 2413 l.icyFrameClosed(e); 2414 } 2415 2416 /** 2417 * Fire frame iconified event 2418 */ 2419 private void fireFrameIconified(IcyFrameEvent e) 2420 { 2421 for (IcyFrameListener l : frameEventListeners.getListeners(IcyFrameListener.class)) 2422 l.icyFrameIconified(e); 2423 } 2424 2425 /** 2426 * Fire frame deiconified event 2427 */ 2428 private void fireFrameDeiconified(IcyFrameEvent e) 2429 { 2430 for (IcyFrameListener l : frameEventListeners.getListeners(IcyFrameListener.class)) 2431 l.icyFrameDeiconified(e); 2432 } 2433 2434 /** 2435 * Fire frame opened event 2436 */ 2437 private void fireFrameOpened(IcyFrameEvent e) 2438 { 2439 for (IcyFrameListener l : frameEventListeners.getListeners(IcyFrameListener.class)) 2440 l.icyFrameOpened(e); 2441 } 2442 2443 /** 2444 * Fire frame internalized event 2445 */ 2446 void fireFrameInternalized(IcyFrameEvent e) 2447 { 2448 for (IcyFrameListener l : frameEventListeners.getListeners(IcyFrameListener.class)) 2449 l.icyFrameInternalized(e); 2450 } 2451 2452 /** 2453 * Fire frame externalized event 2454 */ 2455 void fireFrameExternalized(IcyFrameEvent e) 2456 { 2457 for (IcyFrameListener l : frameEventListeners.getListeners(IcyFrameListener.class)) 2458 l.icyFrameExternalized(e); 2459 } 2460 2461 /** 2462 * Implement addFrameListener method 2463 */ 2464 public void addFrameListener(IcyFrameListener l) 2465 { 2466 frameEventListeners.add(IcyFrameListener.class, l); 2467 } 2468 2469 /** 2470 * Implement removeFrameListener method 2471 */ 2472 public void removeFrameListener(IcyFrameListener l) 2473 { 2474 frameEventListeners.remove(IcyFrameListener.class, l); 2475 } 2476 2477 /** 2478 * Implement addComponentListener method 2479 */ 2480 public void addComponentListener(ComponentListener l) 2481 { 2482 internalFrame.addComponentListener(l); 2483 externalFrame.addComponentListener(l); 2484 } 2485 2486 /** 2487 * Implement removeComponentListener method 2488 */ 2489 public void removeComponentListener(ComponentListener l) 2490 { 2491 internalFrame.removeComponentListener(l); 2492 externalFrame.removeComponentListener(l); 2493 } 2494 2495 /** 2496 * Implement addKeyListener method 2497 */ 2498 public void addKeyListener(KeyListener l) 2499 { 2500 internalFrame.addKeyListener(l); 2501 externalFrame.addKeyListener(l); 2502 } 2503 2504 /** 2505 * Implement addKeyListener method 2506 */ 2507 public void removeKeyListener(KeyListener l) 2508 { 2509 internalFrame.removeKeyListener(l); 2510 externalFrame.removeKeyListener(l); 2511 } 2512 2513 /** 2514 * internal close stuff 2515 */ 2516 public void frameClosed(AWTEvent e) 2517 { 2518 final MainFrame mainFrame = Icy.getMainInterface().getMainFrame(); 2519 // remove listener on main frame mode change 2520 if (mainFrame != null) 2521 mainFrame.removePropertyChangeListener(MainFrame.PROPERTY_DETACHEDMODE, this); 2522 // remove others listeners 2523 externalFrame.removeWindowListener(IcyFrame.this); 2524 internalFrame.removeInternalFrameListener(IcyFrame.this); 2525 2526 if (e instanceof InternalFrameEvent) 2527 { 2528 fireFrameClosed(new IcyFrameEvent(this, (InternalFrameEvent) e, null)); 2529 // don't forget to close external frame 2530 externalFrame.dispose(); 2531 } 2532 else if (e instanceof WindowEvent) 2533 { 2534 fireFrameClosed(new IcyFrameEvent(this, null, (WindowEvent) e)); 2535 // don't forget to close internal frame 2536 internalFrame.dispose(); 2537 } 2538 2539 // easy onClosed handling 2540 onClosed(); 2541 } 2542 2543 /** 2544 * easy onClosed job 2545 */ 2546 public void onClosed() 2547 { 2548 // unregister from list 2549 synchronized (frames) 2550 { 2551 frames.remove(this); 2552 } 2553 2554 // release some stuff else we have cycling reference 2555 externalFrame.systemMenuCallback = null; 2556 internalFrame.systemMenuCallback = null; 2557 switchStateAction = null; 2558 } 2559 2560 @Override 2561 public void internalFrameActivated(InternalFrameEvent e) 2562 { 2563 fireFrameActivated(new IcyFrameEvent(this, e, null)); 2564 } 2565 2566 @Override 2567 public void internalFrameClosed(InternalFrameEvent e) 2568 { 2569 frameClosed(e); 2570 } 2571 2572 @Override 2573 public void internalFrameClosing(InternalFrameEvent e) 2574 { 2575 fireFrameClosing(new IcyFrameEvent(this, e, null)); 2576 } 2577 2578 @Override 2579 public void internalFrameDeactivated(InternalFrameEvent e) 2580 { 2581 fireFrameDeactivated(new IcyFrameEvent(this, e, null)); 2582 } 2583 2584 @Override 2585 public void internalFrameDeiconified(InternalFrameEvent e) 2586 { 2587 fireFrameDeiconified(new IcyFrameEvent(this, e, null)); 2588 } 2589 2590 @Override 2591 public void internalFrameIconified(InternalFrameEvent e) 2592 { 2593 fireFrameIconified(new IcyFrameEvent(this, e, null)); 2594 } 2595 2596 @Override 2597 public void internalFrameOpened(InternalFrameEvent e) 2598 { 2599 fireFrameOpened(new IcyFrameEvent(this, e, null)); 2600 } 2601 2602 @Override 2603 public void windowActivated(WindowEvent e) 2604 { 2605 fireFrameActivated(new IcyFrameEvent(this, null, e)); 2606 } 2607 2608 @Override 2609 public void windowClosed(WindowEvent e) 2610 { 2611 frameClosed(e); 2612 } 2613 2614 @Override 2615 public void windowClosing(WindowEvent e) 2616 { 2617 fireFrameClosing(new IcyFrameEvent(this, null, e)); 2618 } 2619 2620 @Override 2621 public void windowDeactivated(WindowEvent e) 2622 { 2623 fireFrameDeactivated(new IcyFrameEvent(this, null, e)); 2624 } 2625 2626 @Override 2627 public void windowDeiconified(WindowEvent e) 2628 { 2629 fireFrameDeiconified(new IcyFrameEvent(this, null, e)); 2630 } 2631 2632 @Override 2633 public void windowIconified(WindowEvent e) 2634 { 2635 fireFrameIconified(new IcyFrameEvent(this, null, e)); 2636 } 2637 2638 @Override 2639 public void windowOpened(WindowEvent e) 2640 { 2641 fireFrameOpened(new IcyFrameEvent(this, null, e)); 2642 } 2643 2644 @Override 2645 public boolean imageUpdate(Image img, int infoflags, int x, int y, int width, int height) 2646 { 2647 if (isInternalized()) 2648 return internalFrame.imageUpdate(img, infoflags, x, y, width, height); 2649 2650 return externalFrame.imageUpdate(img, infoflags, x, y, width, height); 2651 } 2652 2653 @Override 2654 public void propertyChange(PropertyChangeEvent evt) 2655 { 2656 if (StringUtil.equals(evt.getPropertyName(), MainFrame.PROPERTY_DETACHEDMODE)) 2657 { 2658 // window mode has been changed 2659 final boolean detachedMode = ((Boolean) evt.getNewValue()).booleanValue(); 2660 2661 // detached mode set --> externalize 2662 if (detachedMode) 2663 { 2664 // save previous state 2665 previousState = state; 2666 externalize(); 2667 // disable switch state item 2668 if (switchStateAction != null) 2669 switchStateAction.setEnabled(false); 2670 } 2671 else 2672 { 2673 // restore previous state 2674 if (previousState == IcyFrameState.INTERNALIZED) 2675 internalize(); 2676 // enable switch state item 2677 if (switchStateAction != null) 2678 switchStateAction.setEnabled(true); 2679 } 2680 } 2681 } 2682}