【问题标题】:SWT Browser seems to stick around even after I dispose it即使在我处理掉 SWT 浏览器之后,它似乎仍然存在
【发布时间】:2014-04-01 14:32:14
【问题描述】:

我有一个 SWT 应用程序,我使用画布来显示图像、视频和 PDF 文件。用户可以将任何媒体类型拖到画布上。我使用浏览器对象仅显示 PDF。当我显示完 PDF 后,我只需处理浏览器。有时这可行,但有时浏览器不会消失,我的画布上会出现一个僵尸浏览器窗口。

为什么会出现僵尸浏览器??

我的画布类有一个draw方法,类似这样的

        public void draw(GC gc) {      
            if (mediaType == PDF) { 
                if (browser == null)
                    browser = new Browser(this, SWT.NONE);
            }
            else if (browser != null) {
                browser.dispose();
                browser = null;
            }
            // etc, etc
        }

所以我只在需要时创建浏览器。

【问题讨论】:

    标签: java browser swt ole


    【解决方案1】:

    问题在于new Browser(this, SWT.NONE) 有时会调用canvas的draw方法。所以如果你在draw中创建一个新的浏览器,draw方法可能会被调用多次,在这种情况下会给你多个浏览器。

    我在开始绘制时添加了一个 Thread.dumpStack() 并得到了这个。

        java.lang.Throwable
            at java.lang.Thread.dumpStack(Thread.java:417)
            at com.acme.client.widget.canvas.AcmeImageCanvas.draw(AcmeImageCanvas.java:1923)
            at com.acme.client.widget.canvas.AcmeImageCanvas.paintControl(AcmeImageCanvas.java:1888)
            at org.eclipse.swt.widgets.TypedListener.handleEvent(Unknown Source)
            at org.eclipse.swt.widgets.EventTable.sendEvent(Unknown Source)
            at org.eclipse.swt.widgets.Widget.sendEvent(Unknown Source)
            at org.eclipse.swt.widgets.Widget.sendEvent(Unknown Source)
            at org.eclipse.swt.widgets.Widget.sendEvent(Unknown Source)
            at org.eclipse.swt.widgets.Composite.WM_PAINT(Unknown Source)
            at org.eclipse.swt.widgets.Control.windowProc(Unknown Source)
            at org.eclipse.swt.widgets.Canvas.windowProc(Unknown Source)
            at org.eclipse.swt.widgets.Display.windowProc(Unknown Source)
            at org.eclipse.swt.internal.ole.win32.COM.VtblCall(Native Method)
            at org.eclipse.swt.internal.ole.win32.IDispatch.Invoke(Unknown Source)
            at org.eclipse.swt.ole.win32.OleAutomation.invoke(Unknown Source)
            at org.eclipse.swt.ole.win32.OleAutomation.setProperty(Unknown Source)
            at org.eclipse.swt.browser.IE.create(Unknown Source)
            at org.eclipse.swt.browser.Browser.<init>(Unknown Source)
            at com.acme.client.widget.canvas.AcmeImageCanvas.draw(AcmeImageCanvas.java:1923)
            at com.acme.client.widget.canvas.AcmeImageCanvas.retrieveImage(AcmeImageCanvas.java:4679)
            at com.acme.client.widget.canvas.AcmeThumbnailCanvas.mouseUp(AcmeThumbnailCanvas.java:1761)
            at org.eclipse.swt.widgets.TypedListener.handleEvent(Unknown Source)
            at org.eclipse.swt.widgets.EventTable.sendEvent(Unknown Source)
            at org.eclipse.swt.widgets.Widget.sendEvent(Unknown Source)
            at org.eclipse.swt.widgets.Display.runDeferredEvents(Unknown Source)
            at org.eclipse.swt.widgets.Display.readAndDispatch(Unknown Source)
            at com.acme.client.uiframework.AcmeApp.main(AcmeApp.java:1674)
    

    可以看到Browser.调用了canvas的draw方法。

    解决方案是将 Browser 构造移到别处,并使用 setVisible(false) 而不是 dispose 将其隐藏。

    【讨论】:

    • 事后看来,为什么我的paintControl调用draw?这是问题的真正原因。我把我的paintControl改成NOT调用draw,然后改回原来的策略new/dispose Browser in draw。
    猜你喜欢
    • 2021-04-10
    • 2012-05-26
    • 1970-01-01
    • 1970-01-01
    • 2023-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多