Menu

Resizing application window breaks after loading a JWebBrowser into JPanel

Help
ewvyx
2014-05-08
2014-05-20
  • ewvyx

    ewvyx - 2014-05-08

    My program extends JFrame and within the frame I have a JTabbedPane which holds JPanels. Depending on certain events, I will create a new JWebBrowser and add it to one of those JPanels. This works and looks great. Resizing BEFORE the creation of a JWebBrowser works like a champ. If the program is resized AFTER the creation of a JWebBrowser, the resizing becomes choppy (stops resizing abruptly) and the JWebBrowser will float on top of everything if the JPanel that was holding it gets removed from the JTabbedPane.

    I am using the destroyOnFinalization() option in all my JWebBrowser constructors. I've also noticed resizing a new window created by a JWebBrowser (by using File >> New Window) has the same issue. Is there something I can do to fix resizing on JWebBrowser? Is it another issue with MacOSX && Swing?

     
  • Christopher Deckers

    Hi,

    It is important to not initialize AWT before DJ Native Swing. Hence, your main method must call "NativeInterface.open()" or "NativeInterface.initialize()" as the first thing, and the class that contains that main method must not be a subclass of an AWT component (or else it would trigger some AWT initialization before calling main).

    Apart from that, using "destroyOnFinalization()" has the effect of not placing the native web browser component within the JWebBrowser but actually in the layered pane of your JFrame. When the JWebBrowser is resized, the proxied component resizes the native web browser. This is not done for every event that may happen for performance reasons, but may have the effect of choppy resizing. The logic also tracks removal from the component hierarchy, to hide the native web browser so I don't know why you still see it.

    Could you first check that initialization is done as expected? Could you make sure you use a recent 1.0.3 preview version? Could you also check whether you do anything special with your layered pane, your events or anything that could be in relation with what I explained above?

    Cheers,
    -Christopher

     
  • ewvyx

    ewvyx - 2014-05-14

    NativeInterface.open(); is the very first line of my main method. The class that contains the main() is separate, is not a subclass, and does not implement/extend anything.

    I have updated to the 1.0.3 preview with no change in behavior.

    I've tried no longer loading a custom component that added a tooltip to the layered pane but that didn't change anything either. That was the only instance of the layeredPane being touched.

    I now call disposeNativePeer(false) when I remove the panel containing the JWebBrowser and resizing returns to normal. If I happen to resize while the JWebBrowser is showing, it will remain even after I remove it (also tried calling set visible false on it and explicitly setting it to null) until I resize the window.

    My main method class looks like this:

    public class MyMainClass {
        public static void main(String[] args) {
            NativeInterface.open();
    
            setSystemProperties();
    
            Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
                @Override
                public void uncaughtException(final Thread t, final Throwable e) {
                    EventQueue.invokeLater(new Runnable() {
                        public void run() {
                            EditorUtilsSwing.showErrorDialog(e, myClass.instance);
                        }
                    });
                }
            });
    
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    MyClass myClass = new MyClass();
                    myClass.setVisible(true);
                }
            });
            NativeInterface.runEventPump();
        }
    
        public static void setSystemProperties() {
            System.setProperty("com.prosc.msi.myClass", "true");
        }
    }
    

    I created a short video that may help illustrate what is happening. Thank you for your help with this.

    https://www.youtube.com/watch?v=Bos_LRvQ9As

    Edit: I also took a closer look at the layeredPane before and after I try removing the JPanels/JWebBrowser and confirmed that the NativeComponent is no longer there but it is still visible.

     

    Last edit: ewvyx 2014-05-14
  • Christopher Deckers

    Hi,

    First, I could not watch the video: youtube says it is private.

    Second, let me throw in all I could think of, because I am not exactly sure where the problem is...

    If I happen to resize while the JWebBrowser is showing, it will remain even after I remove it

    When the problem occurs, could you press ctrl+shift+F1 and analyze the component hierarchy? Does it still show in there?
    You could even do that after you resize before the floating-component problem shows up to make sure we are not dealing with a multi-JWebBrowser-instances bug.

    I now call disposeNativePeer(false) when I remove the panel containing the JWebBrowser and resizing returns to normal.

    Did you make sure that the hierarchy is valid? That is: did you call revalidate() on the parent of the panel that is removed (and eventually repaint() too, though that may not matter much in that case)?

    Note that "destroyOnFinalization()" has the effect of retaining the native component alive until the JWebBrowser instance gets garbage collected. So it is strongly advised to call "disposeNativePeer()" (or the variant you are using) when you know you don't need it anymore.

    Out of curioisty, is it a WebStart application? If it is, did you add the following system property:

    <property name="sun.awt.disableMixing" value="true"/>
    

    If you try the demo application, and go to "Additional Features" > "Deferred Destruction", are you able to reproduce the problem when you resize the window, add/remove, or switch to a different example?

    If we really cannot find where the problem is, you could always try to include the DJ NativeSwing code that is part of the distribution and take a look in the related classes. "NativeComponentProxyFinalizationPanel" is the class involved in the layered pane logic.

    Hope this helps,
    -Christopher

     
  • ewvyx

    ewvyx - 2014-05-20

    Sorry about the video, you should be able to view it now:
    https://www.youtube.com/watch?v=Bos_LRvQ9As

    I double checked the hierarchy before and after. The JWebBrowser is there before the resize and after the resize. When I close the tab, the JWebBrowser is no longer in the hierarchy but it is still showing on top of the other tabbed pane panel.

    I tried explicit revalidate() and repaint() calls on the JTabbedPane with no change.

    It is not a WebStart application but I tried running with that system property anyhow, no change.

    I will try to get the demo application running within the next couple of days and see if I can reproduce it there. Thank you for your continued help with this.

     

Log in to post a comment.