I am using Windows 7 with Aero, and have a very fast graphics card (Radeon 6870) that I use for gaming.
I have some issues when resizing very simple programs I make with java. For instance, this program does absolutely nothing. It has no action listeners, no loops. It's simply a GUI interface with buttons.
Resizing with OpenGL acceleration off:
[View fullscreen]
It takes about a second to resize the components. For me that's very noticeable.
Resizing with OpenGL acceleration on:
I have tried to enable OpenGl acceleration to solve this problem. I compiled the JAR and
run it with java -Dsun.java2d.opengl=true -jar C:\Test.jar
. The result is slightly less black areas around the window, but much more flickering. In fact the flickering shows up as grey in the screenshot above.
Is the issue present in any other software?
No. Eclipse, Netbeans, Chrome and other applications have been tested. None have this issue. Therfore I must conclude that there must be some problem with the code. Various people have run this code and said they have "No issues". If you are going to test it, please make sure you resize the window from the smallest size to the largest size of the screen, whilst moving the mouse in circular motion.
Code:
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));
开发者_Python百科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();
}
});
}
}
Note that the issue is still present without this line: UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
I started to notice that for two of my recent Java programs.
I had a look at NetBeans' configuration file, and found the following would improve the situation a lot:
public static void main(final String... args) {
System.setProperty("sun.java2d.noddraw", Boolean.TRUE.toString());
...
Which is the same as -Dsun.java2d.noddraw=true
on the JVM command line.
This trick improves repaint rate in Win7+Aero: setting resizable to null, and providing own resize hook. Its aint perfect, but still alot better.. check my example:
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);
}
});
}
}
If you are running it on Win 7 with Aero, it is known problem:
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6898838
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6873928
Usually Flickering can be improved if not solved using double buffering, you can enable it by setting true to each of the panels .setDoubleBuffer(true);
To read more about it : http://download.oracle.com/javase/tutorial/extra/fullscreen/doublebuf.html
精彩评论