未检测到通过 window.open() 运行的小程序的高度和宽度变化

Posted

技术标签:

【中文标题】未检测到通过 window.open() 运行的小程序的高度和宽度变化【英文标题】:Not detecting height and width change for applet run via window.open() 【发布时间】:2016-05-06 02:40:15 【问题描述】:

我创建了一个时钟小程序,它可以在用户拉伸窗口时调整文本大小。在 Netbeans 中它工作正常,但在 Web 服务器上运行 jar 时它不会检测到任何大小变化。我最初在绘制函数中使用 getWidth() 和 getHeight() 来获取当前窗口大小。当我意识到它没有检测到 Netbeans 之外的更改时,我切换/添加了一个 componentResized() 侦听器,但也没有检测到 Netbeans 之外的任何调整大小。

在网络服务器 index.html 页面上,我使用 win=window.open(url, name, the_size) 打开一个带有时钟小程序的窗口。为什么在我拉伸窗口时听者没有看到任何调整大小?是否因为 window.open() 窗口与 Netbean 弹出窗口有所不同?

   @Override
    public void init() 

        if (getParameter("verbose") != null)
        
            try 
                m_verboseLevel = Integer.parseInt(getParameter("verbose"));
             catch (NumberFormatException e) 
                System.out.println(Thread.currentThread().getName() + " verbose: " + getParameter("verbose") + " is not 0->3");
                m_verboseLevel = 0;
             
        

        m_size = getParameter("size");
        m_clock_color = getParameter("color");

        // Add listener to update width and height as user changes it
        addComponentListener(new ComponentAdapter() 
            @Override
            public void componentResized(ComponentEvent e) 
                  m_w = getWidth();
                  m_h = getHeight();
System.out.println(m_w + " "  + m_h);
            
         );
        try 

在绘画中,m_w 和 m_h 最初为 0,因为没有任何东西移动。我调用 getWidth() 和 getHeight(),输出与 html 小程序宽度和高度值 600 和 800 匹配。但在 Netbeans 之外,m_h/m_w 永远不会改变,因此比例逻辑不会改变任何东西。

    @Override
    public void paint(Graphics g) 

        // first time?
        if ((m_w == 0) && (m_h == 0)) 
            m_w = getWidth();     // return the width of the applet
            m_h = getHeight();    // return the height of the applet
        

        // Use buffering for smooth update
        BufferedImage bi = new BufferedImage(m_w, m_h, BufferedImage.TYPE_INT_RGB);
        Graphics2D g2d = bi.createGraphics();
        super.paint(g2d);

        String[] lines = new String[2];
        lines[0] = "Acquisition of Signal";
        lines[1] = "Loss of Signal";

        // first time?
        if (m_clockLine == 0) 
            FontRenderContext frc = g2d.getFontRenderContext();
            LineMetrics metrics = m_clock_font.getLineMetrics(lines[1], frc);

            // Omitt the descent from the height variable.
            String time = "00:00:00";
            g2d.setFont(m_clock_font);
            float height1 = metrics.getAscent() + metrics.getDescent();
            m_width = m_clock_font.getStringBounds(time, frc).getWidth();
            m_clockLine = (int) (metrics.getAscent() - 1);

            metrics = m_label_font.getLineMetrics(lines[0], frc);
            float height2 = metrics.getAscent() + metrics.getDescent();
            m_labelLine = (int) (metrics.getAscent() - 1);

            metrics = m_tk_font.getLineMetrics(lines[1], frc);
            float height3 = metrics.getAscent() + metrics.getDescent();
            m_titleLine = (int) (metrics.getAscent() - 1);

            m_width += 22*2;
            m_height = height1 + height2 + height3 + height1 + height2 + (m_padding*4);
        
System.out.println(m_w + " " + m_width +  " " + m_h +  " " + m_height);

        g2d.scale(m_w/m_width, m_h/m_height);

        /* Make background black */
        g2d.setColor(Color.black);
        g2d.fillRect(0, 0, (int)m_width, (int)m_height);

         /* Draw individual clock labels */
        g2d.setFont(m_label_font);
        g2d.setColor(m_main_color);

        g2d.drawString(lines[0], 145, m_clockLine+m_labelLine+m_padding);
        g2d.drawString(lines[1], 220, m_clockLine+m_labelLine+m_titleLine+m_clockLine+m_labelLine+(m_padding*4));

        // Write check clock timer lines
        if (m_c != null) 
            m_c.print(g2d, m_labelLine, m_clockLine, m_titleLine, m_padding, m_width, m_height);
        

        g2d.dispose();
        g.drawImage(bi, 0, 0, this);
     // end paint

【问题讨论】:

【参考方案1】:

好的,经过大量谷歌搜索后,我发现了问题所在。当 applet 使用 addComponentListener componentResized 或 getWidth/getHeight 调用检查其尺寸时,它正在读取 applet/对象的 html 宽度和高度值。使用 Netbeans Applet 查看器时,这些值会随着查看器的拉伸而改变。但是在 html 页面中,宽度和高度不会随着浏览器的大小而改变。这就是为什么拉伸浏览器时小程序大小不会改变的原因。所以实际环境中的解决方案是通过javascript重新设置宽高值,让小程序onLoad可以看到新的尺寸。注意:onResize 似乎永远不会消失,但我还是把它留了下来。

所以我删除了componentResized 逻辑,并在paint 函数中调用getWidth/getHeight 来获取applet 尺寸。这是最终的绘制函数。

@Override
    public void paint(Graphics g) 

        // This makes the applet resizable
        int w = getWidth();     // return the width of the applet
        int h = getHeight();    // return the height of the applet

        // Use buffering for smooth update
        BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
        Graphics2D g2d = bi.createGraphics();
        super.paint(g2d);

        String[] lines = new String[2];
        lines[0] = "Acquisition of Signal";
        lines[1] = "Loss of Signal";

        // first time?
        if (m_clockLine == 0) 
            FontRenderContext frc = g2d.getFontRenderContext();
            LineMetrics metrics = m_clock_font.getLineMetrics(lines[1], frc);

            // Omitt the descent from the height variable.
            String time = "00:00:00";
            g2d.setFont(m_clock_font);
            float height1 = metrics.getAscent() + metrics.getDescent();
            m_width = m_clock_font.getStringBounds(time, frc).getWidth();
            m_clockLine = (int) (metrics.getAscent() - 1);

            metrics = m_label_font.getLineMetrics(lines[0], frc);
            float height2 = metrics.getAscent() + metrics.getDescent();
            m_labelLine = (int) (metrics.getAscent() - 1);

            metrics = m_tk_font.getLineMetrics(lines[1], frc);
            float height3 = metrics.getAscent() + metrics.getDescent();
            m_titleLine = (int) (metrics.getAscent() - 1);

            m_width += 22*2;
            m_height = height1 + height2 + height3 + height1 + height2 + (m_padding*4);
        

        g2d.scale(w/m_width, h/m_height);

        /* Make background black */
        g2d.setColor(Color.black);
        g2d.fillRect(0, 0, (int)m_width, (int)m_height);

         /* Draw individual clock labels */
        g2d.setFont(m_label_font);
        g2d.setColor(m_main_color);

        g2d.drawString(lines[0], 145, m_clockLine+m_labelLine+m_padding);
        g2d.drawString(lines[1], 220, m_clockLine+m_labelLine+m_titleLine+m_clockLine+m_labelLine+(m_padding*4));

        // Write check clock timer line
        if (m_c != null) 
            m_c.print(g2d, m_labelLine, m_clockLine, m_titleLine, m_padding, m_width, m_height);
        

        g2d.dispose();
        g.drawImage(bi, 0, 0, this);
     // end paint

在 html 脚本中我添加了以下逻辑:

<html>
  <head>
    <TITLE>Terra Small Clock</TITLE>
    <meta content="text/html; charset=utf-8" http-equiv="content-type">
    <meta content="IE=5.0000" http-equiv="X-UA-Compatible">
    <meta name="GENERATOR" content="MSHTML 11.00.9600.17842">
  </head>
  <SCRIPT LANGUAGE="JavaScript">
    /*
    Description:
    The re-size function job is to reset the applet width and height to the new dimensions as the 
    user stretches the browser window.  The clock applet will then use the "current" width and 
    height to scale the clock.
    */
    function resize()
    
       if (navigator.appName.indexOf("Microsoft") != -1)
       
          // 100% works fine on object tag with IE
          return;
       
       var w_newWidth,w_newHeight;

       var netscapeScrollWidth=0;
       w_newWidth  = window.innerWidth-netscapeScrollWidth;
       w_newHeight = window.innerHeight-netscapeScrollWidth;

       var appletDiv = document.getElementById('clockApp');
       if (appletDiv != null) 
         appletDiv.style.width  = w_newWidth  + "px";
         appletDiv.style.height = w_newHeight + "px";
       
    

    window.onResize = resize;
    window.onLoad   = resize;
  </SCRIPT>
  <body bgcolor="000000" leftmargin="0" rightmargin="0" topmargin="0" margin margin onResize="resize()" onLoad="resize()">
    <p style="text-align:center">
      <object type="application/x-java-applet" id="clockApp"  >
        <param name="codebase" value="https://<host stuff>.nasa.gov/java_clocks/classes/" />
        <param name="code" value="aosClock.class" />
        <param name="archive" value="clock.jar" />

        <param name="verbose" value="0" />
        <param name="color" value="green" />
        <param name="input_file" value="https://<host stuff>.nasa.gov/java_clocks/terra/terra_aos_times" />
      </object>
    </p>
  </body>
</html>

因此,当我停止拉伸浏览器窗口时,onLoad 会关闭,并且小程序/对象的宽度和高度会被重置。然后,小程序会针对新维度调整时钟。

【讨论】:

以上是关于未检测到通过 window.open() 运行的小程序的高度和宽度变化的主要内容,如果未能解决你的问题,请参考以下文章

检测使用 window.open 打开的窗口的 onload 事件

开不了的窗_____window.open

通过 workflow_run 运行时,拉取请求未检测到操作

window.open链接未在Windows Phone 8的cordova应用中打开

window.opener = null 的问题...

“将图像另存为..”在使用 window.open() 和 document.write() 时无法在 Google Chrome 中运行