我在Java小程序中遇到某种竞争情况,这是Google Chrome(win xp)特有的。
我正在将<applet>
标记写入弹出窗口。
该问题的特征是:
该小程序在MS IE和Firefox中始终显示正常。
在Chrome中,小程序仅显示50%的时间。
当它不显示时,小程序实际上似乎可以从Java控制台静默完美地运行!没有错误!
总是调用JApplet
的init()
和start()
方法。
即使没有显示小程序,isShowing()
和isDisplayable()
始终返回true
。
如果未显示,则不会调用paint()
方法。
如果未显示小程序,则在选择窗口中的文本时会注意到应该放置小程序的透明矩形区域(窗口背景色)。因此,我认为小程序区域已正确放置在窗口中。
我的代码:
MyApplet.java
package mypackage;
public class MyApplet extends JApplet {
public void init(){
super.init();
getContentPane().add(new JLabel("Hello"), BorderLayout.CENTER);
System.out.println("init ok");
}
public void start() {
super.start();
System.out.println("s parent:"+this.getParent());
System.out.println("s disp:"+this.isDisplayable());
System.out.println("s showing:"+this.isShowing());
}
public void paint(Graphics g){
System.out.println("painting");
super.paint(g);
}
}
test.html
<HTML>
<SCRIPT language='JavaScript'>
var jarpath='./myjar.jar';
var classname='mypackage.MyApplet';
function opentest(){
applet=window.open('', '', "height=420,width=620");
applet.document.write(
'<html><body>'+
'<OBJECT classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"'+
'width=600 height=400>'+
'<param name=code value="'+classname+'">'+
'<param name=archive value="'+jarpath+'">'+
'<param name=type value="application/x-java-applet;version1.3">'+
'<COMMENT>'+
'<EMBED code="'+classname+'" archive="'+jarpath+'" ' +
'type="application/x-java-applet;version=1.3" ' +
'width=600 height=400 ' +
'>'+
'<NOEMBED>' +
'unavailable'+
'</NOEMBED>'+
'</EMBED>' +
'</COMMENT>' +
'</OBJECT>'+
'</body></html>' );
}
</SCRIPT>
<BODY>
Click here to open <A onclick="opentest()">Test</A>
</BODY>
</HTML>
控制台输出
我有50%的时间单击“测试”,新窗口包含“你好”标签。在其他50%的时间中,该窗口为空白。
当加载和不加载小程序时,控制台输出似乎相同。看来无可厚非!
security: property package.access value sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.
security: property package.access new value sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.,com.sun.javaws
security: property package.access value sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.,com.sun.javaws
security: property package.access new value sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.,com.sun.javaws,com.sun.deploy
security: property package.access value sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.,com.sun.javaws,com.sun.deploy
security: property package.access new value sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.,com.sun.javaws,com.sun.deploy,com.sun.jnlp
security: property package.definition value null
security: property package.definition new value com.sun.javaws
security: property package.definition value com.sun.javaws
security: property package.definition new value com.sun.javaws,com.sun.deploy
security: property package.definition value com.sun.javaws,com.sun.deploy
security: property package.definition new value com.sun.javaws,com.sun.deploy,com.sun.jnlp
security: property package.access value sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.,com.sun.javaws,com.sun.deploy,com.sun.jnlp
security: property package.access new value sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.,com.sun.javaws,com.sun.deploy,com.sun.jnlp,org.mozilla.jss
security: property package.definition value com.sun.javaws,com.sun.deploy,com.sun.jnlp
security: property package.definition new value com.sun.javaws,com.sun.deploy,com.sun.jnlp,org.mozilla.jss
basic: Added progress listener: sun.plugin.util.GrayBoxPainter$GrayBoxProgressListener@137c60d
basic: Plugin2ClassLoader.addURL parent called for file:/E:/Java/eclipse/MyApplet/myjar.jar
network: Cache entry not found [url: file:/E:/Java/eclipse/MyApplet/myjar.jar, version: null]
network: Cache entry not found [url: file:/E:/Java/eclipse/MyApplet/myjar.jar, version: null]
basic: Applet loaded.
basic: Applet resized and added to parent container
basic: PERF: AppletExecutionRunnable - applet.init() BEGIN ; jvmLaunch dt 145396 us, pluginInit dt 331540 us, TotalTime: 476936 us
init ok
basic: Applet initialized
basic: Removed progress listener: sun.plugin.util.GrayBoxPainter$GrayBoxProgressListener@137c60d
basic: Applet made visible
basic: Starting applet
basic: completed perf rollup
s parent:sun.plugin2.main.client.PluginEmbeddedFrame[frame0,0,0,600x400,invalid,layout=java.awt.BorderLayout,title=,resizable,normal]
s disp:true
s showing:true
basic: Applet started
basic: Told clients applet is started
更新资料
感谢Ates,尝试以下超时可使Applet在100%的时间内正确显示。
function opentest(){
applet=window.open('', '', "height=420,width=620");
setTimeout(function () {
applet.document.write( ... ); } ,
1000 );
}
正如Ates所提到的,我们现在看到弹出窗口不喜欢直接的
document.write
!这是正确的行为吗?我应该在写入文件之前等待一些信号吗?
我应该以不同的方式去做吗?我可以添加某种侦听器来知道何时可以安全地调用
document.write()
吗? 最佳答案
applet = window.open('', '', "height=420,width=620");
applet.document.write(...
这可能是您的比赛条件开始的地方。您可能试图在不正确初始化窗口的情况下更改新打开的窗口的文档。一个快速尝试的方法是,通过将其余代码推迟到将异步运行的虚拟超时中,使“正在运行”的JavaScript线程“呼吸”:
applet = window.open('', '', "height=420,width=620");
setTimeout(function () {
applet.document.write(...
}, 0);
这不一定是解决此问题的最佳方法,但是尝试查看这是否实际上是竞争状况的根源是一件快速的事情。