/*
This file belongs to the Servoy development and deployment environment, Copyright (C) 1997-2010 Servoy BV
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Affero General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your option) any
later version.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License along
with this program; if not, see http://www.gnu.org/licenses or write to the Free
Software Foundation,Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
*/
package com.servoy.j2db.smart;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.Window;
import java.lang.reflect.Method;
import javax.swing.Action;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JMenuBar;
import javax.swing.JRootPane;
import javax.swing.RootPaneContainer;
import com.servoy.j2db.FormController;
import com.servoy.j2db.FormManager;
import com.servoy.j2db.FormWindow;
import com.servoy.j2db.IMainContainer;
import com.servoy.j2db.ISmartClientApplication;
import com.servoy.j2db.LAFManager;
import com.servoy.j2db.gui.FormDialog;
import com.servoy.j2db.plugins.ISmartRuntimeWindow;
import com.servoy.j2db.scripting.JSWindow;
import com.servoy.j2db.scripting.RuntimeWindow;
import com.servoy.j2db.util.Debug;
import com.servoy.j2db.util.JavaVersion;
import com.servoy.j2db.util.Pair;
import com.servoy.j2db.util.Settings;
import com.servoy.j2db.util.UIUtils;
import com.servoy.j2db.util.Utils;
import com.servoy.j2db.util.toolbar.ToolbarPanel;
/**
* Swing implementation of the JSWindow. It is based on a wrapped awt Window instance.
* @author acostescu
* @since 6.0
*/
public class SwingRuntimeWindow extends RuntimeWindow implements ISmartRuntimeWindow
{
protected volatile Window wrappedWindow = null; // will be null before the JSWindow is first shown or after the JSWindow is destroyed; can be JFrame (in case of main app. frame), FormFrame or FormDialog
protected JMenuBar wrappedWindowMenuBar = null;
private boolean createdNewWindow;
protected TextToolbar textToolbar;
protected ToolbarPanel toolbarPanel;
private boolean boundsSet = false;
public SwingRuntimeWindow(ISmartClientApplication application, String windowName, int windowType, RuntimeWindow parentWindow)
{
super(application, windowName, windowType, parentWindow);
}
@Override
public ISmartClientApplication getApplication()
{
return (ISmartClientApplication)super.getApplication();
}
@Override
public int getHeight()
{
if (wrappedWindow == null)
{
return initialBounds.height;
}
else
{
return wrappedWindow.getHeight();
}
}
@Override
public int getWidth()
{
if (wrappedWindow == null)
{
return initialBounds.width;
}
else
{
return wrappedWindow.getWidth();
}
}
@Override
public int getX()
{
if (wrappedWindow == null)
{
return initialBounds.x;
}
else
{
if (wrappedWindow.isShowing()) return wrappedWindow.getLocationOnScreen().x; // in case of multiple monitors that are used as virtual screen we want to get the virtual coordinates (so that when set back the window will show on the same monitor); getX, getY, ... will return the coordinates on current physical screen
else return wrappedWindow.getLocation().x;
}
}
@Override
public int getY()
{
if (wrappedWindow == null)
{
return initialBounds.y;
}
else
{
if (wrappedWindow.isShowing()) return wrappedWindow.getLocationOnScreen().y; // in case of multiple monitors that are used as virtual screen we want to get the virtual coordinates (so that when set back the window will show on the same monitor); getX, getY, ... will return the coordinates on current physical screen
else return wrappedWindow.getLocation().y;
}
}
// For future implementation of case 286968 change
// @Override
// public int getState()
// {
// if (wrappedWindow instanceof JFrame)
// {
// int extendedState = ((JFrame)wrappedWindow).getExtendedState();
// int servoyState = NORMAL; // 0
// if ((extendedState & Frame.ICONIFIED) == Frame.ICONIFIED) servoyState = servoyState | ICONIFIED;
// if ((extendedState & Frame.MAXIMIZED_BOTH) == Frame.MAXIMIZED_BOTH) servoyState = servoyState | MAXIMIZED;
// return servoyState;
// }
// else
// {
// return super.getState();
// }
// }
@Override
public JSWindow getParent()
{
if (wrappedWindow != null)
{
Window parent = wrappedWindow.getOwner();
RuntimeWindow pw;
if (parent == getApplication().getMainApplicationFrame())
{
pw = getApplication().getRuntimeWindowManager().getWindow(null);
}
else if (parent != null)
{
pw = getApplication().getRuntimeWindowManager().getWindow(parent.getName());
}
else pw = null;
return (pw != null) ? pw.getJSWindow() : null;
}
return super.getParent();
}
@Override
public void setLocation(int x, int y)
{
if (wrappedWindow == null)
{
boundsSet = true;
setInitialBounds(x, y, getWidth(), getHeight());
}
else if (canChangeBoundsThroughScripting())
{
if (x < 0 && y < 0)
{
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
x = (screenSize.width / 2) - (getWidth() / 2);
y = (screenSize.height / 2) - (getHeight() / 2);
}
wrappedWindow.setLocation(x, y);
}
}
@Override
public void setSize(int width, int height)
{
if (wrappedWindow == null)
{
boundsSet = true;
setInitialBounds(getX(), getY(), width, height);
}
else if (canChangeBoundsThroughScripting())
{
wrappedWindow.setSize(width, height);
wrappedWindow.validate();
}
}
@Override
public void setResizable(boolean resizable)
{
super.setResizable(resizable);
if (wrappedWindow instanceof JFrame) ((JFrame)wrappedWindow).setResizable(resizable);
else if (wrappedWindow instanceof FormDialog) ((FormDialog)wrappedWindow).setResizable(resizable);
}
// For future implementation of case 286968 change
// @Override
// public void setState(int state)
// {
// if (wrappedWindow instanceof JFrame)
// {
// int extendedState = Frame.NORMAL; // 0
// if ((state & ICONIFIED) == ICONIFIED) extendedState = extendedState | Frame.ICONIFIED;
// if ((state & MAXIMIZED) == MAXIMIZED) extendedState = extendedState | Frame.MAXIMIZED_BOTH;
// ((JFrame)wrappedWindow).setState(extendedState);
// }
// else
// {
// super.setState(state);
// }
// }
@Override
public void setTitle(final String title)
{
setTitle(title, false);
}
@Override
public void setTitle(final String title, boolean delayed)
{
super.setTitle(title);
if (isVisible())
{
if (wrappedWindow instanceof FormWindow)
{
if (delayed)
{
getApplication().invokeLater(new Runnable()
{
public void run()
{
// see FormManager showFormInMainPanel, title is set delayed, have to delay here also
((FormWindow)wrappedWindow).setTitle(title);
}
});
}
else
{
((FormWindow)wrappedWindow).setTitle(title);
}
}
else if (wrappedWindow instanceof JFrame) // for main app. frame
{
final String t = getApplication().getI18NMessageIfPrefixed(title);
getApplication().invokeLater(new Runnable()
{
public void run()
{
// see FormManager showFormInMainPanel, title is set delayed, have to delay here also
if (wrappedWindow != null) ((JFrame)wrappedWindow).setTitle(t);
}
});
}
} // else no use setting title as the tags can't be processed (if there is no form open)
}
@Override
public void showTextToolbar(boolean showTextToolbar)
{
super.showTextToolbar(showTextToolbar);
if (wrappedWindow instanceof RootPaneContainer)
{
applyToolbar((RootPaneContainer)wrappedWindow);
}
}
@Override
public void toBack()
{
if (wrappedWindow != null)
{
wrappedWindow.toBack();
}
}
@Override
public void toFront()
{
if (wrappedWindow != null)
{
wrappedWindow.toFront();
}
}
@Override
public boolean isVisible()
{
if (wrappedWindow != null)
{
return wrappedWindow.isShowing();
}
return false;
}
@Override
public void destroy()
{
super.destroy();
if (wrappedWindow != null)
{
// a MainPanel still keeps a reference to this Window via parent (& currently MainPanels are cached until a solution switch happens)
// so to free up Window held memory for main panels that are no longer used, detach it
if (wrappedWindow instanceof FormDialog) ((FormDialog)wrappedWindow).getContentPane().removeAll();
else if (wrappedWindow instanceof JFrame) ((JFrame)wrappedWindow).getContentPane().removeAll();
wrappedWindow.dispose();
wrappedWindow = null;
textToolbar = null;
toolbarPanel = null;
}
}
@Override
public Window getWrappedObject()
{
return wrappedWindow;
}
@Override
public void hideUI()
{
if (wrappedWindow instanceof FormWindow) // it should always be either null or instanceof FormWindow
{
((FormWindow)wrappedWindow).closeWindow();
}
}
// For future implementation of case 286968
// @Override
// protected void doShow(String formName)
// {
// FormManager fm = ((FormManager)getApplication().getFormManager());
// boolean isDialog = (windowType == MODAL_DIALOG || windowType == DIALOG);
// boolean isModal = (getType() == MODAL_DIALOG);
// IMainContainer previousModalContainer = null;
// boolean toFront = false;
// boolean firstShow = (wrappedWindow == null);
// IMainContainer currentMainContainer = null;
// if (isDialog)
// {
// // parent matters for dialogs
// JSWindow parentJSWindow;
// if (initialParentWindow != null && initialParentWindow.getWrappedObject() != null && ((Window)initialParentWindow.getWrappedObject()).isShowing())
// {
// parentJSWindow = initialParentWindow;
// }
// else
// {
// IMainContainer currentModalContainer = fm.getModalDialogContainer();
// parentJSWindow = getApplication().getJSWindowManager().getWindow(currentModalContainer.getContainerName());
// }
//
// currentMainContainer = ((FormWindow)parentJSWindow.getWrappedObject()).getMainContainer();
// Pair<Boolean, IMainContainer> p = createAndReparentDialogIfNeeded(fm, parentJSWindow, isModal);
// toFront = p.getLeft().booleanValue();
// previousModalContainer = p.getRight();
//
// // TO DO
// }
// else if (windowType == WINDOW)
// {
// // TO DO
// } // else illegal situation that should never happen
// else throw new RuntimeException("Unknown window type: " + windowType);
//
// IMainContainer container = ((FormWindow)wrappedWindow).getMainContainer();
// final FormController fp = fm.showFormInMainPanel(formName, container, title, true, windowName);
//
// if (isDialog && fp != null && fp.getName().equals(formName))
// {
// FormDialog sfd = ((FormDialog)wrappedWindow);
// sfd.setModal(isModal);
// if (isModal)
// {
// // When a modal window is closed, the old modal window state will have to be restored...
// // For example, when inside JS for an event you close a modal window and open another one,
// // the new modal window must have as owner not the closed window, but the last opened modal window
// // before the window just closed.
// // This has to happen when setVisible(false) is called on the modal dialog. We cannot simply rely
// // on executing this after sfd.setVisible(true) is unblocked, because then it will be executed
// // after the new dialog is opened by java script. (because that execution continues as the next event on the EventThread)
// sfd.setPreviousMainContainer(previousModalContainer, currentMainContainer);
// }
// }
//
// finalizeShowWindow(fp, formName, container, false, false, toFront);
// }
@Override
protected void doOldShow(String formName, boolean closeAll, boolean legacyV3Behavior)
{
if (windowType == JSWindow.WINDOW)
{
doOldShowInWindow(formName);
}
else
{
doOldShowInDialog(formName, closeAll, legacyV3Behavior);
}
}
private void doOldShowInDialog(String formName, boolean closeAll, boolean legacyV3Behavior)
{
FormManager fm = ((FormManager)getApplication().getFormManager());
IMainContainer currentModalDialogContainer = fm.getModalDialogContainer();
JSWindow parentJSWindow = getParent();
RuntimeWindow parentRuntimeWindow = null;
if (parentJSWindow != null && parentJSWindow.getImpl().isVisible()) parentRuntimeWindow = parentJSWindow.getImpl();
else
{
Window dialogWindowOwner = getWindowFromMainContainer(currentModalDialogContainer);
if (dialogWindowOwner != null)
{
IMainContainer currentContainer = fm.getCurrentContainer();
Window currentContainerWindow = getWindowFromMainContainer(currentContainer);
while (currentContainerWindow != null)
{
if (dialogWindowOwner == currentContainerWindow)
{
break;
}
currentContainerWindow = currentContainerWindow.getOwner();
}
if (currentContainerWindow == null)
{
// if it never really was the owner (in the own chain of the dialog) then do just use the currentContainer.
currentModalDialogContainer = currentContainer;
}
}
parentRuntimeWindow = getApplication().getRuntimeWindowManager().getWindow(currentModalDialogContainer.getContainerName());
}
boolean windowModal = ((legacyV3Behavior && wrappedWindow == null) || getType() == JSWindow.MODAL_DIALOG);
Pair<Boolean, IMainContainer> p = createAndReparentDialogIfNeeded(fm, parentRuntimeWindow, windowModal);
boolean bringToFrontNeeded = p.getLeft().booleanValue();
IMainContainer previousModalContainer = p.getRight();
FormDialog sfd = (FormDialog)wrappedWindow;
IMainContainer container = sfd.getMainContainer();
// For none legacy the dialog must always be really closed
sfd.setCloseAll(closeAll || !legacyV3Behavior);
if (sfd.isVisible())
{
sfd.storeBounds();
}
final FormController fp = fm.showFormInMainPanel(formName, container, title, closeAll && legacyV3Behavior, windowName);
if (fp != null && fp.getName().equals(formName))
{
sfd.setModal(windowModal);
if (!sfd.isDisplayable() && isUndecorated())
{
sfd.setUndecorated(true);
sfd.getRootPane().setWindowDecorationStyle(JRootPane.NONE);
if (Utils.isAppleMacOS()) sfd.getRootPane().putClientProperty("Window.shadow", Boolean.FALSE); //$NON-NLS-1$
}
applyOpacityAndTransparency(sfd, container, sfd.getContentPane(), sfd.isUndecorated());
if (windowModal)
{
testAndSetJava6Modality(sfd);
// When a modal window is closed, the old modal window state will have to be restored...
// For example, when inside JS for an event you close a modal window and open another one,
// the new modal window must have as owner not the closed window, but the last opened modal window
// before the window just closed.
// This has to happen when setVisible(false) is called on the modal dialog. We cannot simply rely
// on executing this after sfd.setVisible(true) is unblocked, because then it will be executed
// after the new dialog is opened by java script. (because that execution continues as the next event on the EventThread)
sfd.setPreviousMainContainer(previousModalContainer, currentModalDialogContainer);
}
else
{
// If it is a none modal dialog, make sure the current container is reset to the currentMainContainer (== previous his parent)
// else it is switched a bit to early (if a developer shows 2 dialogs at once from a main container)
// the focus event of the FormDialog will set it correctly.
fm.setCurrentContainer(currentModalDialogContainer, currentModalDialogContainer.getName());
}
}
finalizeShowWindow(fp, formName, container, true, legacyV3Behavior, bringToFrontNeeded);
}
private void applyOpacityAndTransparency(Window w, IMainContainer container, Container contentPane, boolean undecoratedW)
{
// opacity
float opacityValue = getOpacity();
if (opacityValue != getOpacity(w))
{
setOpacity(w, opacityValue);
}
// transparency
try
{
boolean transparentValue = getTransparent();
if (transparentValue == contentPane.isOpaque())
{
if (UIUtils.setWindowTransparency(w, contentPane, undecoratedW, transparentValue, true))
{
container.setOpaque(!transparentValue);
}
}
}
catch (Exception e)
{
Debug.error("Unable to set transparency on JSWindow " + getName() + ".", e);
}
}
private void setOpacity(Window w, float opacityValue)
{
// set on window if possible
if (JavaVersion.CURRENT_JAVA_VERSION.major >= 7)
{
try
{
Method mSetWindowOpacity = Window.class.getMethod("setOpacity", float.class);
mSetWindowOpacity.invoke(w, Float.valueOf(opacityValue));
}
catch (Exception ex)
{
Debug.trace("Error while trying to set opacity on window using v7 API; the capability might be missing.", ex);
}
}
else if (JavaVersion.CURRENT_JAVA_VERSION.major == 6 && JavaVersion.CURRENT_JAVA_VERSION.update >= 10) // see http://docs.oracle.com/javase/tutorial/uiswing/misc/trans_shaped_windows.html
{
try
{
Class< ? > awtUtilitiesClass = Class.forName("com.sun.awt.AWTUtilities");
Method mSetWindowOpacity = awtUtilitiesClass.getMethod("setWindowOpacity", Window.class, float.class);
mSetWindowOpacity.invoke(null, w, Float.valueOf(opacityValue));
}
catch (Exception ex)
{
Debug.trace("Error while trying to set opacity on window using v6 API; the capability might be missing.", ex);
}
}
else
{
Debug.warn("Cannot set opacity on window; it is supported only with Java 6 update 10 or higher.");
}
}
private float getOpacity(Window w)
{
float opacity = 1;
if (JavaVersion.CURRENT_JAVA_VERSION.major >= 7)
{
try
{
Method mGetWindowOpacity = Window.class.getMethod("getOpacity");
opacity = ((Float)mGetWindowOpacity.invoke(w)).floatValue();
}
catch (Exception ex)
{
// something went wrong; maybe capability is missing from graphics device; return default "opaque"
}
}
else if (JavaVersion.CURRENT_JAVA_VERSION.major == 6 && JavaVersion.CURRENT_JAVA_VERSION.update >= 10) // see http://docs.oracle.com/javase/tutorial/uiswing/misc/trans_shaped_windows.html
{
try
{
Class< ? > awtUtilitiesClass = Class.forName("com.sun.awt.AWTUtilities");
Method mgetWindowOpacity = awtUtilitiesClass.getMethod("getWindowOpacity", Window.class);
opacity = ((Float)mgetWindowOpacity.invoke(null, w)).floatValue();
}
catch (Exception ex)
{
// something went wrong; maybe capability is missing from graphics device; return default "opaque"
}
} // else it's not supported by JVM; always opaque
return opacity;
}
private static Object setModalityTypeMethod = null;
private static Object modalityDocumentModalValue = null;
/**
* This is a special method for that test for the ModalityType class/enum of java 6 of the value DOCUMENT_MODAL
* and if found it will set that on the dialog given as the argument,this way we default in 6 to document modal instead of application modal.
* @param sfd
*/
@SuppressWarnings("nls")
public static void testAndSetJava6Modality(FormDialog sfd)
{
if (setModalityTypeMethod == null)
{
try
{
Class< ? > clz = Class.forName("java.awt.Dialog$ModalityType");
modalityDocumentModalValue = clz.getField("DOCUMENT_MODAL").get(clz);
setModalityTypeMethod = FormDialog.class.getMethod("setModalityType", clz);
}
catch (Exception e)
{
setModalityTypeMethod = Boolean.FALSE;
}
}
if (setModalityTypeMethod instanceof Method)
{
try
{
((Method)setModalityTypeMethod).invoke(sfd, new Object[] { modalityDocumentModalValue });
}
catch (Exception e)
{
setModalityTypeMethod = Boolean.FALSE;
}
}
}
/**
* @param currentModalDialogContainer
* @return
*/
public Window getWindowFromMainContainer(IMainContainer currentModalDialogContainer)
{
Window dialogWindowOwner = null;
Container component = (Container)currentModalDialogContainer;
while (component != null)
{
if (component instanceof Window)
{
dialogWindowOwner = (Window)component;
break;
}
component = component.getParent();
}
return dialogWindowOwner;
}
private void doOldShowInWindow(String formName)
{
FormManager fm = ((FormManager)getApplication().getFormManager());
boolean toFront = createFrameIfNeeded(fm);
FormFrame frame = (FormFrame)wrappedWindow;
if (frame.isVisible())
{
frame.storeBounds();
}
IMainContainer container = frame.getMainContainer();
final FormController fp = fm.showFormInMainPanel(formName, container, title, true, windowName);
finalizeShowWindow(fp, formName, container, true, false, toFront);
}
private boolean createFrameIfNeeded(FormManager fm)
{
IMainContainer container = fm.getOrCreateMainContainer(windowName);
boolean bringToFrontNeeded = false;
FormFrame frame = (FormFrame)wrappedWindow;
if (frame == null)
{
wrappedWindow = frame = createFormFrame(windowName);
frame.setResizable(resizable);
frame.setMainContainer(container);
// need to call 'pack' as the 'container' may have been used before & removed from a frame, causing
// it to be unbinded from its peer, but we need it binded for calculations before showing it; see
// MainPanel.show, all 'tableFormPanel' components would be inivisible, because 'tableFormPanel' is unbinded from its peer,
// causing the frame focus to not work;
frame.pack();
createdNewWindow = true;
}
else if (frame.isVisible())
{
bringToFrontNeeded = true;
}
return bringToFrontNeeded;
}
private Pair<Boolean, IMainContainer> createAndReparentDialogIfNeeded(FormManager fm, RuntimeWindow parentJSWindow, boolean windowModal)
{
IMainContainer container = fm.getOrCreateMainContainer(windowName);
IMainContainer previousModalContainer = null;
FormDialog sfd = (FormDialog)wrappedWindow;
boolean reparented = false;
Object[] savedStatusForRecreate = null;
// make sure the dialog has the correct owner
if (sfd != null)
{
Window formDialogOwner = sfd.getOwner();
Window owner = null;
if (parentJSWindow == null || parentJSWindow.getWrappedObject() == null)
{
owner = getApplication().getMainApplicationFrame();
}
else
{
owner = (Window)parentJSWindow.getWrappedObject();
}
if ((owner != sfd) && !owner.equals(formDialogOwner))
{
// wrong owner... will create a new window and close/dispose old one
savedStatusForRecreate = saveWrappedWindowStatusForRecreate();
hide(true);
sfd.dispose();
sfd = null;
wrappedWindow = null;
reparented = true;
}
}
if (windowModal)
{
previousModalContainer = fm.setModalDialogContainer(container);
}
boolean bringToFrontNeeded = false;
if (sfd == null)
{
wrappedWindow = sfd = createFormDialog(parentJSWindow != null ? (Window)parentJSWindow.getWrappedObject() : null, windowModal, windowName);
createdNewWindow = true;
sfd.setResizable(resizable);
sfd.setMainContainer(container);
if (reparented)
{
restoreWrappedWindowStatusAfterRecreate(savedStatusForRecreate);
}
}
else if (sfd.isVisible())
{
bringToFrontNeeded = true;
}
return new Pair<Boolean, IMainContainer>(Boolean.valueOf(bringToFrontNeeded), previousModalContainer);
}
private Object[] saveWrappedWindowStatusForRecreate()
{
return new Object[] { wrappedWindow.isShowing() ? wrappedWindow.getLocationOnScreen() : wrappedWindow.getLocation(), wrappedWindow.getSize()
// , Integer.valueOf(getState()) // For future implementation of case 286968 change
};
}
private void restoreWrappedWindowStatusAfterRecreate(Object[] savedStatusForRecreate)
{
wrappedWindow.setLocation((Point)savedStatusForRecreate[0]);
wrappedWindow.setSize((Dimension)savedStatusForRecreate[1]);
// For future implementation of case 286968 change
// setState(((Integer)savedStatusForRecreate[2]).intValue());
showTextToolbar(showTextToolbar);
}
private void finalizeShowWindow(final FormController fp, String formName, IMainContainer container, boolean oldShow, boolean legacyV3Behavior,
boolean bringToFrontNeeded)
{
if (fp != null && fp.getName().equals(formName))
{
applyToolbar((RootPaneContainer)wrappedWindow);
if (wrappedWindowMenuBar != null && wrappedWindow instanceof JFrame)
{
((JFrame)wrappedWindow).setJMenuBar(wrappedWindowMenuBar);
}
else if (wrappedWindowMenuBar != null && wrappedWindow instanceof JDialog)
{
((JDialog)wrappedWindow).setJMenuBar(wrappedWindowMenuBar);
}
if (oldShow)
{
if (!storeBounds || !restoreWindowBounds())
{
setDefaultSize(fp);
if (!FormManager.FULL_SCREEN.equals(initialBounds))
{
setWindowBounds(initialBounds, legacyV3Behavior);
}
}
else if (!resizable)
{
setDefaultSize(fp);
//if location was restored, then initial width and height need to be set
if (!FormManager.FULL_SCREEN.equals(initialBounds))
{
setWindowBounds(new Rectangle(getX(), getY(), initialBounds.width, initialBounds.height), legacyV3Behavior);
}
}
}
boolean findModeSet = false;
Action action = getApplication().getCmdManager().getRegisteredAction("cmdperformfind"); //$NON-NLS-1$
if (action != null && fp.getFormModel() != null)
{
findModeSet = fp.getFormModel().isInFindMode() && !action.isEnabled();
if (findModeSet) action.setEnabled(true);
}
getApplication().invokeLater(new Runnable()
{
public void run()
{
if (wrappedWindow == null) return; // already destroyed (test client probably)
((RootPaneContainer)wrappedWindow).getRootPane().requestFocus();
if (LAFManager.isUsingAppleLAF())
{
getApplication().invokeLater(new Runnable()
{
public void run()
{
((Component)fp.getFormUI()).repaint();
}
});
}
}
});
if (createdNewWindow &&
(Utils.getPlatform() == Utils.PLATFORM_LINUX || (Utils.getPlatform() == Utils.PLATFORM_MAC && JavaVersion.CURRENT_JAVA_VERSION.major >= 7)))
{
createdNewWindow = false;
getApplication().invokeLater(new Runnable()
{
public void run()
{
if (wrappedWindow != null &&
(Utils.getPlatform() == Utils.PLATFORM_LINUX || (Utils.getPlatform() == Utils.PLATFORM_MAC && !wrappedWindow.isFocused())))
{
// needed to work around a focus issue on Linux, text fields in a tabpanel on a dialog do not get focus.
// also needed as a workaround for a focus issue on Mac, where windows did not get focus
// possibly (Mac OS) related: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=8001161
wrappedWindow.setVisible(false);
wrappedWindow.setVisible(true);
}
}
});
}
// blocks in case of modal dialogs
if (oldShow && FormManager.FULL_SCREEN.equals(initialBounds))
{
((FormWindow)wrappedWindow).setFullScreen();
}
else
{
wrappedWindow.setVisible(true);
if (bringToFrontNeeded)
{
wrappedWindow.toFront();
}
}
if (findModeSet && action != null) action.setEnabled(false);
}
}
private void setDefaultSize(FormController fp)
{
// quickly set the form to visible if not visible.
boolean visible = fp.getFormUI().isVisible();
if (!visible)
{
((Component)fp.getFormUI()).setVisible(true);
}
// now calculate the preferred size
wrappedWindow.pack();
// if not visible before restore that state (will be set right later on)
if (!visible) ((Component)fp.getFormUI()).setVisible(false);
}
public void setWindowBounds(Rectangle r, boolean legacyV3Behavior)
{
if (wrappedWindow != null)
{
Rectangle r2 = wrappedWindow.getBounds();
if (r != null)
{
if (r.height <= 0)
{
r.height = r2.height;
}
if (r.width <= 0)
{
r.width = r2.width;
}
if (!UIUtils.isOnScreen(r)) // with multiple monitors, all locations on a monitor can be negative
{
wrappedWindow.setSize(r.width, r.height);
// if the current dialog is not visible, the the location
// else let it be what it was.
if (!wrappedWindow.isVisible() || legacyV3Behavior)
{
Window ow = wrappedWindow.getOwner();
if (ow == null) ow = getApplication().getMainApplicationFrame();
wrappedWindow.setLocationRelativeTo(ow);
}
}
else
{
wrappedWindow.setBounds(r);
wrappedWindow.validate();
}
}
}
}
protected FormDialog createFormDialog(Window owner, boolean modal, String dialogName)
{
if (owner == null || (!(owner instanceof JDialog || owner instanceof JFrame))) owner = getApplication().getMainApplicationFrame();
if (owner instanceof JDialog)
{
return new FormDialog(getApplication(), (JDialog)owner, modal, dialogName);
}
else
{
return new FormDialog(getApplication(), (JFrame)owner, modal, dialogName);
}
}
protected FormFrame createFormFrame(String windowName)
{
FormFrame frame = new FormFrame(getApplication(), windowName);
frame.setIconImage(getApplication().getMainApplicationFrame().getIconImage());
return frame;
}
public TextToolbar getTextToolbar()
{
return textToolbar;
}
private void applyToolbar(RootPaneContainer window)
{
if (showTextToolbar)
{
if (textToolbar == null)
{
textToolbar = new TextToolbar(getApplication());
}
if (toolbarPanel == null) toolbarPanel = new ToolbarPanel(Settings.INITIAL_CLIENT_WIDTH - 200);
toolbarPanel.addToolbar(textToolbar, 0);
}
else
{
if (textToolbar != null)
{
toolbarPanel.remove(textToolbar);
textToolbar = null;
}
}
//if there is a toolbar show the pannel
if (toolbarPanel != null)
{
if (toolbarPanel.getToolBarNames().length > 0)
{
window.getContentPane().add(toolbarPanel, BorderLayout.NORTH);
}
else
{
window.getContentPane().remove(toolbarPanel);
toolbarPanel = null;
}
}
if (isVisible())
{
if (toolbarPanel != null)
{
toolbarPanel.revalidate();
}
else
{
window.getContentPane().invalidate();
window.getContentPane().validate();
}
}
}
public void storeBounds()
{
if (wrappedWindow instanceof FormWindow)
{
((FormWindow)wrappedWindow).storeBounds();
}
}
public boolean restoreWindowBounds()
{
if (wrappedWindow instanceof FormWindow && !boundsSet)
{
return ((FormWindow)wrappedWindow).restoreBounds();
}
boundsSet = false;
return false;
}
/*
* (non-Javadoc)
*
* @see com.servoy.j2db.plugins.ISwingRuntimeWindow#getJMenuBar()
*/
public JMenuBar getJMenuBar()
{
return wrappedWindowMenuBar;
}
/*
* (non-Javadoc)
*
* @see com.servoy.j2db.plugins.ISwingRuntimeWindow#getWindow()
*/
public Window getWindow()
{
return wrappedWindow;
}
/*
* (non-Javadoc)
*
* @see com.servoy.j2db.plugins.ISwingRuntimeWindow#setJMenuBar(javax.swing.JMenuBar)
*/
public void setJMenuBar(JMenuBar menuBar)
{
wrappedWindowMenuBar = menuBar;
if (wrappedWindow instanceof JFrame)
{
((JFrame)wrappedWindow).setJMenuBar(wrappedWindowMenuBar);
}
else if (wrappedWindow instanceof JDialog)
{
((JDialog)wrappedWindow).setJMenuBar(wrappedWindowMenuBar);
}
}
/*
* (non-Javadoc)
*
* @see com.servoy.j2db.scripting.RuntimeWindow#resetBounds()
*/
@Override
public void resetBounds()
{
Settings.getInstance().deleteBounds(windowName, getApplication().getSolutionName());
}
@Override
public void setToolbarPanel(ToolbarPanel toolbar)
{
toolbarPanel = toolbar;
}
@Override
public ToolbarPanel getToolbarPanel()
{
return toolbarPanel;
}
}