M webclient/classes_spec/org/mozilla/webclient/NewWindowEvent.java

- changes for new responsibilities of NewWindowEvent

 * <p>Indicates the browser is requesting a new window be created to
 * display a new <code>BrowserControlCanvas</code> instance.  This
 * mechanism is only necessary if your embedding application wishes to
 * allow the browser to pop up new windows (or tabs).  Such is often the
 * case when the user clicks on an href with a "target" attribute, or
 * the embedding application wants to enable some right-click "open in
 * new window" or "open in new tab" feature.</p>

M webclient/classes_spec/org/mozilla/webclient/impl/wrapper_native/NativeBrowserControlCanvas.java
M webclient/classes_spec/org/mozilla/webclient/impl/wrapper_native/CocoaBrowserControlCanvas.java
M webclient/classes_spec/org/mozilla/webclient/impl/wrapper_native/Win32BrowserControlCanvas.java

- introduce new performPlatformAppropriateNewWindowRealization

     * Allow platform specific handling of new window creation.

M webclient/classes_spec/org/mozilla/webclient/impl/wrapper_native/EventRegistrationImpl.java

- modify the contract for new window creation

M webclient/test/automated/src/classes/org/mozilla/webclient/WindowCreatorTest.java

- verify it all works.


git-svn-id: svn://10.0.0.236/trunk@228930 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
edburns%acm.org
2007-06-28 12:05:07 +00:00
parent 4489b12465
commit 5c3d713df2
6 changed files with 213 additions and 117 deletions

View File

@@ -22,7 +22,96 @@
package org.mozilla.webclient;
import java.awt.Container;
import java.util.List;
/**
*
* <p>Indicates the browser is requesting a new window be created to
* display a new <code>BrowserControlCanvas</code> instance. This
* mechanism is only necessary if your embedding application wishes to
* allow the browser to pop up new windows (or tabs). Such is often the
* case when the user clicks on an href with a "target" attribute, or
* the embedding application wants to enable some right-click "open in
* new window" or "open in new tab" feature.</p>
*
* <p>Usage contract:</p>
*
* <p>The unfortunately complex usage contract to accomodate differences
* in the UI threading models in a platform indepent manner.</p>
*
* <p>On the application main thread, do something like this:</p>
*
* <code><pre>
final List<Runnable> realizeNewWindowRunnableList =
new CopyOnWriteArrayList<Runnable>();
<a href="EventRegistrationImpl.html">eventRegistration</a>.setNewWindowListener(new NewWindowListener() {
public void eventDispatched(WebclientEvent wcEvent) {
NewWindowEvent event = (NewWindowEvent) wcEvent;
final BrowserControlCanvas secondCanvas;
try {
secondBrowserControl =
BrowserControlFactory.newBrowserControl();
secondCanvas = (BrowserControlCanvas)
secondBrowserControl.queryInterface(BrowserControl.BROWSER_CONTROL_CANVAS_NAME);
} catch (Throwable e) {
System.out.println(e.getMessage());
fail();
return;
}
event.setBrowserControl(secondBrowserControl);
event.setRealizeNewWindowRunnableList(realizeNewWindowRunnableList);
event.setRealizeNewWindowRunnable(new Runnable() {
public void run() {
secondFrame.add(secondCanvas, BorderLayout.CENTER);
secondFrame.setVisible(true);
secondCanvas.setVisible(true);
}
public String toString() {
return "WindowCreatorTest newWindowRunnable";
}
});
}
});
// ... continue with browser code.
while (realizeNewWindowRunnableList.isEmpty()) {
Thread.currentThread().sleep(1000);
}
for (Runnable cur : realizeNewWindowRunnableList) {
cur.run();
}
* </pre></code>
*
* <p>The above code accomplishes the folliwng goals:</p>
* <p>Create a thread safe list data structure. This will hold the
* <code>Runnable</code> that we define to create the parent window and
* make it visible. Add a <code><a
* href="NewWindowListener.html">NewWindowListener</a></code> instance
* to the "main" <code>BrowserControl</code>. When this listener
* instance receives an <code>eventDispatched</code> call (on a platform
* specific <code>Thread</code>), it must create a <b>new</b>
* <code>BrowserControl</code>, gets its
* <code>BrowserControlCanvas</code>, store the canvas into the event,
* store the thread safe list data structure into the event, and store a
* Runnable into the event that adds the canvas to its parent container,
* and sets the parent container and the canvas visible. This Runnable
* will be called at a platform specific time, on a platform specific
* <code>Thread</code>. The <code>toString()</code> implementation is
* just good practice for debugging.</p>
*
* <p>Meanwhile, back on the main thread the thread safe list data
* structure mest be polled, as often as desired, until Runnable appears
* in the list. It will have been placed there by the Webclient API and
* the embedding application is required to run() it on the main
* thread.</p>
*
*/
public class NewWindowEvent extends WebclientEvent
{
@@ -46,15 +135,37 @@ public void setBrowserControl(BrowserControl newBrowserControl) {
browserControl = newBrowserControl;
}
private Container parentContainer;
private Runnable realizeNewWindowRunnable;
public Container getParentContainer() {
return parentContainer;
protected List<Runnable> browserWillAdd;
public void setRealizeNewWindowRunnableList(List<Runnable> browserWillAdd){
this.browserWillAdd = browserWillAdd;
}
public List<Runnable> getRealizeNewWindowRunnableList() {
return browserWillAdd;
}
public static class RealizeNewWindowEvent {
private BrowserControl browserControl;
public BrowserControl getBrowserControl() {
return browserControl;
}
public void setBrowserControl(BrowserControl browserControl) {
this.browserControl = browserControl;
}
}
public Runnable getRealizeNewWindowRunnable() {
return realizeNewWindowRunnable;
}
public void setParentContainer(Container parentContainer) {
this.parentContainer = parentContainer;
public void setRealizeNewWindowRunnable(Runnable realizeNewWindowRunnable) {
this.realizeNewWindowRunnable = realizeNewWindowRunnable;
}
} // end of class NewWindowEvent

View File

@@ -26,12 +26,12 @@
package org.mozilla.webclient.impl.wrapper_native;
import org.mozilla.webclient.BrowserControlCanvas;
import java.awt.*;
import java.util.List;
import java.util.logging.Logger;
import org.mozilla.util.Log;
import org.mozilla.util.ReturnRunnable;
import org.mozilla.webclient.NewWindowEvent;
import org.mozilla.webclient.impl.WrapperFactory;
/**
@@ -80,6 +80,13 @@ public class CocoaBrowserControlCanvas extends NativeBrowserControlCanvas {
return nativeView;
}
void performPlatformAppropriateNewWindowRealization(NewWindowEvent event) {
List<Runnable> addToList =
event.getRealizeNewWindowRunnableList();
event.getRealizeNewWindowRunnable().run();
addToList.add(new Runnable() { public void run() {} });
}
public static NativeEventThread newNativeEventThread(WrapperFactory owner) {
NativeEventThread result = new CocoaAppKitThreadDelegatingNativeEventThread("WebclientEventThread",

View File

@@ -21,8 +21,6 @@
*/
package org.mozilla.webclient.impl.wrapper_native;
import java.awt.BorderLayout;
import java.awt.Container;
import org.mozilla.util.ParameterCheck;
import java.util.ArrayList;
@@ -47,13 +45,14 @@ import org.mozilla.util.Log;
import org.mozilla.util.ReturnRunnable;
import org.mozilla.webclient.BrowserControl;
import org.mozilla.webclient.BrowserControlCanvas;
import org.mozilla.webclient.EventRegistration2;
import org.mozilla.webclient.impl.BrowserControlImpl;
import org.mozilla.webclient.impl.WrapperFactory;
import org.mozilla.webclient.DocumentLoadEvent;
import org.mozilla.webclient.DocumentLoadListener;
import org.mozilla.webclient.PageInfoListener;
import org.mozilla.webclient.NewWindowEvent;
import org.mozilla.webclient.NewWindowEvent.RealizeNewWindowEvent;
import org.mozilla.webclient.NewWindowListener;
import org.mozilla.webclient.WCKeyEvent;
import org.mozilla.webclient.WebclientEvent;
@@ -551,28 +550,18 @@ private EventObject createKeyEvent(long eventType, Object eventData) {
return keyEvent;
}
private int getNativeBrowserControlFromNewWindowEvent(NewWindowEvent event) {
NativeBrowserControlCanvas
currentCanvas = null,
newCanvas = null;
BrowserControlImpl newBrowserControl = null;
private int getNativeBrowserControlFromNewWindowEvent(final NewWindowEvent event) {
final BrowserControl newBrowserControl;
NativeBrowserControlCanvas newCanvas = null;
EventRegistration2 newEventRegistration = null;
Container parentContainer = null;
int result = 0;
if (null == (newBrowserControl =
(BrowserControlImpl) event.getBrowserControl())) {
if (null == (newBrowserControl = event.getBrowserControl())) {
return 0;
}
if (null == (parentContainer =
event.getParentContainer())) {
return 0;
}
currentCanvas = browserControlCanvas;
try {
newCanvas =
(NativeBrowserControlCanvas)
newCanvas = (NativeBrowserControlCanvas)
newBrowserControl.queryInterface(BrowserControl.BROWSER_CONTROL_CANVAS_NAME);
} catch (ClassNotFoundException cnfe) {
if (LOGGER.isLoggable(Level.SEVERE)) {
@@ -582,10 +571,6 @@ private int getNativeBrowserControlFromNewWindowEvent(NewWindowEvent event) {
throw new IllegalStateException(cnfe);
}
parentContainer.add(newCanvas, BorderLayout.CENTER);
parentContainer.setVisible(true);
newCanvas.setVisible(true);
try {
newEventRegistration = (EventRegistration2)
newBrowserControl.queryInterface(BrowserControl.EVENT_REGISTRATION_NAME);
@@ -602,6 +587,8 @@ private int getNativeBrowserControlFromNewWindowEvent(NewWindowEvent event) {
return 0;
}
newCanvas.performPlatformAppropriateNewWindowRealization(event);
result = ((ImplObjectNative)newEventRegistration).getNativeBrowserControl();
return result;
@@ -834,4 +821,4 @@ class URIToStringMap extends Object implements Map {
}
} // end of class EventRegistrationImpl
} // end of class EventRegistrationImpl

View File

@@ -32,6 +32,7 @@ import org.mozilla.util.Assert;
import org.mozilla.util.Log;
import org.mozilla.webclient.BrowserControl;
import org.mozilla.webclient.BrowserControlCanvas;
import org.mozilla.webclient.NewWindowEvent;
import org.mozilla.webclient.WindowControl;
import org.mozilla.webclient.impl.BrowserControlImpl;
import org.mozilla.webclient.impl.WrapperFactory;
@@ -88,6 +89,13 @@ abstract class NativeBrowserControlCanvas extends BrowserControlCanvas {
abstract protected int getWindow();
/**
* Allow platform specific handling of new window creation.
*
*/
abstract void performPlatformAppropriateNewWindowRealization(NewWindowEvent event);
private void createNativeBrowser() throws IllegalStateException {
try {
Rectangle r = new Rectangle(getBoundsRelativeToWindow());

View File

@@ -22,7 +22,9 @@
package org.mozilla.webclient.impl.wrapper_native;
import java.util.List;
import org.mozilla.util.ReturnRunnable;
import org.mozilla.webclient.NewWindowEvent;
/**
@@ -33,7 +35,7 @@ import org.mozilla.util.ReturnRunnable;
* There is one instance of the BrowserControlCanvas per top level awt Frame.
* @version $Id: Win32BrowserControlCanvas.java,v 1.5 2007-06-19 20:18:11 edburns%acm.org Exp $
* @version $Id: Win32BrowserControlCanvas.java,v 1.6 2007-06-28 12:05:07 edburns%acm.org Exp $
*
* @see org.mozilla.webclient.BrowserControlCanvasFactory
*
@@ -76,6 +78,23 @@ public class Win32BrowserControlCanvas extends NativeBrowserControlCanvas {
});
return result.intValue();
}
void performPlatformAppropriateNewWindowRealization(final NewWindowEvent event) {
final List<Runnable> addToList =
event.getRealizeNewWindowRunnableList();
NativeEventThread.instance.pushRunnable(new Runnable() {
public void run() {
addToList.add(event.getRealizeNewWindowRunnable());
}
public String toString() {
return "EventRegistrationImpl.RealizeNewWindowEvent";
}
});
NativeEventThread.instance.runUntilEventOfType(WindowControlImpl.NativeRealizeWCRunnable.class);
}
public static NativeEventThread newNativeEventThread(WrapperFactory owner) {
NativeEventThread result = new NativeEventThread("WebclientEventThread",