Java慢速2D性能 – resize

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

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

使用OpenGL加速关闭resize:

[查看全屏] 缓慢的大小调整

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

使用OpenGL加速resize:

在此处输入图像描述

我试图启用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());

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

http://sofzh.miximages.com/java/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); } }); } } 

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

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

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

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

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

要了解更多信息,请访问: http : //download.oracle.com/javase/tutorial/extra/fullscreen/doublebuf.html