Java慢速2D性能 - 调整大小

时间:2011-08-13 11:18:46

标签: java swing 2d jframe

我正在使用带有Aero的Windows 7,并且拥有一个非常快的显卡(Radeon 6870),我用它来进行游戏。

在调整我使用java制作的非常简单的程序时,我遇到了一些问题。例如,这个程序绝对没有。它没有动作侦听器,没有循环。它只是一个带按钮的GUI界面。

关闭OpenGL加速时调整大小:

[View fullscreen] Sluggish resizing

大约需要一秒钟来调整组件的大小。对我来说非常明显。

使用OpenGL加速调整大小:

enter image description here

我试图启用OpenGl加速来解决这个问题。我编译了JAR和 用java -Dsun.java2d.opengl=true -jar C:\Test.jar运行它。结果是窗口周围的略微黑色区域,但更多的闪烁。实际上,闪烁在上面的屏幕截图中显示为灰色。

问题是否出现在任何其他软件中?

没有。 Eclipse,Netbeans,Chrome和其他应用程序已经过测试。没有这个问题。因此,我必须得出结论,代码必定存在一些问题。各种各样的人都运行了这段代码并说他们有“没有问题”。如果您要测试它,请确保您在从最小尺寸到最大尺寸的屏幕上调整窗口大小,同时以圆周方式移动鼠标。

代码:

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

public class JFrameWithButtonsTest {
    private int iScreen = 25;  
    private int iLocation = 10;
    JFrame frame = new JFrame();
    Container contentPane = frame.getContentPane();

    public JFrameWithButtonsTest() {
        JPanel northButtonPanel = new JPanel();
        northButtonPanel.setLayout(new GridLayout(2,2));
        northButtonPanel.add(new JButton(" I do nothing"));
        northButtonPanel.add(new JButton(" I do nothing"));
        northButtonPanel.add(new JButton(" I do nothing"));
        northButtonPanel.add(new JButton(" I do nothing"));
        contentPane.add(northButtonPanel, BorderLayout.NORTH);

        JPanel southButtonPanel = new JPanel();
        southButtonPanel.setLayout(new GridLayout(2,2));
        southButtonPanel.add(new JButton(" I do nothing"));
        southButtonPanel.add(new JButton(" I do nothing"));
        southButtonPanel.add(new JButton(" I do nothing"));
        southButtonPanel.add(new JButton(" I do nothing"));
        contentPane.add(southButtonPanel, BorderLayout.SOUTH);

        JPanel eastButtonPanel = new JPanel();
        eastButtonPanel.setLayout(new GridLayout(2,2));
        eastButtonPanel.add(new JButton(" I do nothing"));
        eastButtonPanel.add(new JButton(" I do nothing"));
        eastButtonPanel.add(new JButton(" I do nothing"));
        eastButtonPanel.add(new JButton(" I do nothing"));
        contentPane.add(eastButtonPanel, BorderLayout.EAST);

        boolean packFrame = false;
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        Dimension frameSize = frame.getSize();
        frameSize.height = (int) (iScreen * screenSize.height / 100);
        frameSize.width = (int) (iScreen * screenSize.width / 100);
        frame.setSize(frameSize);
        frame.setLocation((screenSize.width - frameSize.width) / iLocation,
                (screenSize.height - frameSize.height) / iLocation);
        if (packFrame) {
            frame.pack();
            packFrame = true;
        } else {
            frame.validate();
        }
        frame.setVisible(true);
    }
    public static void main(String[] args) {
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (Exception e) {
            e.printStackTrace();
        }
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new JFrameWithButtonsTest();
            }
        });
    }
}

请注意,如果没有此行,问题仍然存在:UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());

4 个答案:

答案 0 :(得分:5)

我开始注意到我最近的两个Java程序。

我查看了NetBeans的配置文件,发现以下内容会改善这种情况:

  public static void main(final String... args) {
    System.setProperty("sun.java2d.noddraw", Boolean.TRUE.toString());
    ...

与JVM命令行上的-Dsun.java2d.noddraw=true相同。

答案 1 :(得分:2)

这个技巧提高了Win7 + Aero中的重绘率:设置可调整为null,并提供自己的调整大小钩子。它不是完美的,但仍然更好..检查我的例子:

http://i.stack.imgur.com/IrPAb.png

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

class ResizeHookDemo extends JDialog {
  private final static int width = 580, height = 350;
  private final JFileChooser fc;
  private java.awt.geom.GeneralPath gp;

  public ResizeHookDemo() {
    super((JDialog)null, "Choose File", true);

    fc = new JFileChooser() {

     @Override
     public void paint(Graphics g) {
       super.paint(g);
       int w = getWidth();
       int h = getHeight();
       g.setColor(new Color(150, 150, 150, 200));
       g.drawLine(w-7, h, w, h-7);
       g.drawLine(w-11, h, w, h-11);
       g.drawLine(w-15, h, w, h-15);

       gp = new java.awt.geom.GeneralPath();      
       gp.moveTo(w-17, h);
       gp.lineTo(w, h-17);
       gp.lineTo(w, h);
       gp.closePath();
     }

    };
    fc.addActionListener(new ActionListener() {

      public void actionPerformed(ActionEvent e) {
        if (e.getActionCommand().equals("CancelSelection")) {
          setVisible(false);
          // action...
        }
        else if (e.getActionCommand().equals("ApproveSelection")) {
          setVisible(false);
          // action...
        }
      }
    });

    MouseInputListener resizeHook = new MouseInputAdapter() {
      private Point startPos = null;

      public void mousePressed(MouseEvent e) {
        if (gp.contains(e.getPoint())) 
          startPos = new Point(getWidth()-e.getX(), getHeight()-e.getY());
      }

      public void mouseReleased(MouseEvent mouseEvent) {
        startPos = null;
      }

      public void mouseMoved(MouseEvent e) {
        if (gp.contains(e.getPoint()))
          setCursor(Cursor.getPredefinedCursor(Cursor.SE_RESIZE_CURSOR));
        else
          setCursor(Cursor.getDefaultCursor());
      }

      public void mouseDragged(MouseEvent e) {
        if (startPos != null) {

          int dx = e.getX() + startPos.x;
          int dy = e.getY() + startPos.y;

          setSize(dx, dy);
          repaint();
        }
      }         
    };

    fc.addMouseMotionListener(resizeHook);
    fc.addMouseListener(resizeHook);
    fc.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 20));
    add(fc);

    setResizable(false);

    setMinimumSize(new Dimension(width, height));
    setDefaultCloseOperation(HIDE_ON_CLOSE);
    setLocationRelativeTo(null);
  }

  public static void main(String args[]) {
    System.out.println("Starting demo...");
    SwingUtilities.invokeLater(new Runnable() {

      @Override
      public void run() {
        new ResizeHookDemo().setVisible(true);
      }
    });
  }
}

答案 2 :(得分:0)

答案 3 :(得分:-2)

如果没有使用双缓冲解决,通常可以改善闪烁,您可以通过将true设置为每个面板来启用它.setDoubleBuffer(true);

要详细了解它:http://download.oracle.com/javase/tutorial/extra/fullscreen/doublebuf.html