0

我正在制作我的第一个小程序。我有一个 JPanel,它创建一个 Swing GUI 并执行 CPU 密集型任务(重新绘制 60Hz 组件)。我的 Applet 在事件调度线程上显示此 JPanel。这是问题的抽象。通常我会从 html 文档而不是 main 方法启动小程序。这个程序给我的 CPU 带来了大约 40% 的负载。

import javax.swing.*;
import java.awt.*;
import java.awt.geom.*;
import java.awt.event.*;

public class TestApplet extends JApplet {
    TestPanel tp;
    public void init() {
        try {
            SwingUtilities.invokeAndWait(new Runnable() {
                public void run() {
                    createGUI();
                }
            });
        } catch (Exception e) { 
            System.err.println("createGUI didn't complete successfully");
        }
    }
    private void createGUI() {
        //Create and set up the content pane.
        tp = new TestPanel();
        tp.setOpaque(true); 
        setContentPane(tp);        
    }

    public static void main(String[] args) {
        JFrame f = new JFrame("Fish Tank");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JApplet ap = new TestApplet();
        ap.init();
        f.add("Center", ap);
        f.pack();
        f.setVisible(true);
    }
}

class TestPanel extends JPanel{
    public TestTank tt = new TestTank();
    public TestPanel() {add(tt);}
    public void stop() {tt.stop();}
    public void start() {tt.start();}
}

class TestTank extends Component implements ActionListener{
    private javax.swing.Timer timer;
    TestTank(){
        timer = new javax.swing.Timer(17, this);
        timer.setCoalesce(true);
        timer.start();
    }
    public Dimension getPreferredSize(){
        return new Dimension(900, 700);
    }
    public void paint(Graphics g) {
        Graphics2D g2 = (Graphics2D) g;
        Dimension size = getSize();
        g2.setPaint(new GradientPaint(0,0,Color.RED,900, 0,Color.WHITE));
        g2.fill(new Rectangle2D.Float(0,0,size.width,size.height));
    }
    public void actionPerformed(ActionEvent e) {
        repaint();
    }
    public void stop(){timer.stop();}
    public void start(){timer.start();}
}

我的问题:当用户切换选项卡或最小化浏览器时,如何暂停和恢复 JPanel (FishTankPanel) 的执行?当用户看不到它在做什么时,我希望 Applet 停止使用 CPU。我需要捕获浏览器事件以便在小程序中执行 tp.stop()。我尝试使用 JPanel 中的窗口事件侦听器执行它们,并通过覆盖 Applet 中的 start() 和 stop() 方法。我一直不成功。任何建议或解决方案将不胜感激。

4

3 回答 3

2

我会按照 Dave 所说的那样做,并使用 JApplet 覆盖启动和停止方法来调用您的 GUI 方法。例如,查看代码中的更改:

public class TestApplet extends JApplet {
   TestPanel tp;

   public void init() {
      // ... no change
   }

   private void createGUI() {
      // ... no change
   }

   @Override
   public void stop() {
      if (tp != null) {
         tp.stop();
      }
   }

   @Override
   public void start() {
      if (tp != null) {
         tp.start();
      }
   }

}    

class TestTank extends Component implements ActionListener {
   private javax.swing.Timer timer;

   // ... no change

   public void stop() {
      timer.stop();
      System.out.println("stop");
   }

   public void start() {
      timer.start();
      System.out.println("start");
   }
}
于 2012-12-23T22:52:40.777 回答
2

看来您可能需要为此利用一些 JS。EG 使用此答案中显示的 JS 分别显式调用小程序start()stop()方法进行焦点和模糊检测。

于 2012-12-24T01:07:22.977 回答
0

我的问题的解决方案是使用 javascript 来实现Page Visibility API。然后我从 javascript 脚本中调用了适当的 Java 方法。

于 2012-12-24T21:02:43.980 回答