我正在通过一本书(Filthy Rich Clients,不去引用)学习Java和Swing,并且在Linux(Oracle JDK 8)上尝试了以下简短示例代码:
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class OvalComponent extends JComponent {
public void paintComponent(Graphics g) {
g.setColor(getBackground());
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(Color.GRAY);
g.fillOval(0, 0, getWidth(), getHeight());
}
private static void createAndShowGUI() {
JFrame f = new JFrame("Oval");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(200, 200);
f.add(new OvalComponent());
f.setVisible(true);
}
public static void main(String args[]) {
Runnable doCreateAndShowGUI = new Runnable() {
public void run() {
createAndShowGUI();
}
};
SwingUtilities.invokeLater(doCreateAndShowGUI);
}
}
运行此代码时,我奇怪地观察到JFrame
边界上的以下“工件”:
在拖动窗口时保留此“伪像”,但在调整窗口大小时消失。我想了解为什么我在Linux上有这种奇怪的行为。这是Linux固有的吗(在Windows 7上我没有观察到任何伪像),并且应该/可以做些什么来修复此“错误”?
我还观察到,只需在super.paintComponent(Graphics g);
方法的开头调用paintComponent
就可以解决问题。但是,非常奇怪的是,书中的作者说,在这种特殊情况下,不必调用super.paintComponent()
。
我的主要问题是:为什么我在Java窗口中观察到这种黑色工件?
答案 0 :(得分:2)
与Paul一样,如上面的屏幕截图所示,我没有注意到右侧的伪影。话虽如此,这很可能是由于无法调用super方法引起的。调用它将导致组件的 背景 被绘制。
还有一些我建议在代码中实现的建议,每条建议之前都有代码注释,以讨论原因。
// A JPanel does some things automatically, so I prefer to use one
//public class OvalComponent extends JComponent {
public class OvalComponent extends JPanel {
// Use @Override notation!
@Override
public void paintComponent(Graphics g) {
// call the super method first..
super.paintComponent(g);
// this is better achieved with the call to super
//g.setColor(getBackground());
//g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(Color.GRAY);
g.fillOval(0, 0, getWidth(), getHeight());
}
// suggest a size for the layout manager(s) to use..
@Override
public Dimension getPreferredSize() {
return new Dimension(300, 300);
}
private static void createAndShowGUI() {
JFrame f = new JFrame("Oval");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// DON'T TRY TO GUESS WHAT SIZE THE FRAME SHOULD BE!
// f.setSize(200, 200);
f.add(new OvalComponent());
// Instead pack the top level container after components added
f.pack();
f.setVisible(true);
}
public static void main(String args[]) {
Runnable doCreateAndShowGUI = () -> {
createAndShowGUI();
};
SwingUtilities.invokeLater(doCreateAndShowGUI);
}
}