>不要从顶级容器(如JFrame)扩展,你不会添加任何有益的东西.
>避免油漆到顶层容器.而是使用像JPanel这样的东西.
>避免覆盖绘画,改为使用paintComponent.有关详细信息,请参见
Performing Custom Painting
这不是绘画的工作方式(我不会尝试重写你的代码来制作它).
当重绘系统决定需要更新UI的一部分或全部时,将调用Paint来响应许多事件.绘制是破坏性的,也就是说,当调用paint时,Graphics将被完全刷新,需要您从头开始“重建”输出.
代替.
编写一个递归算法,可以绘制到像BufferedImage这样的东西,然后在paintComponent中绘制…
更新
Swing中的绘画由RepaintManager控制,它有责任确定重绘屏幕的内容和时间.你似乎认为油漆是你可以控制的东西,当它不是时.
您需要准备好完全重新绘制UI或准备好可以根据需要绘制到UI上的缓冲区.
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.geom.AffineTransform;
import java.awt.geom.Path2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class SierpinskisGasket {
public static void main(String[] args) {
new SierpinskisGasket();
}
public SierpinskisGasket() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
BaseShape base = new BaseShape(Math.min(getWidth(), getHeight()));
Rectangle bounds = base.getBounds();
int x = (getWidth() - bounds.width) / 2;
int y = (getHeight() - bounds.height) / 2;
base.transform(AffineTransform.getTranslateInstance(x, y));
g2d.fill(base);
g2d.dispose();
}
}
public class BaseShape extends Path2D.Float {
public BaseShape(float size) {
float subSize = size / 2f;
Triangle top = new Triangle(subSize);
top.transform(AffineTransform.getTranslateInstance((size - subSize) / 2, 0));
append(top, false);
Triangle left = new Triangle(subSize);
left.transform(AffineTransform.getTranslateInstance(0, subSize));
append(left, false);
Triangle right = new Triangle(subSize);
right.transform(AffineTransform.getTranslateInstance(subSize, subSize));
append(right, false);
}
}
public class Triangle extends Path2D.Float {
public Triangle(float size) {
moveTo(size / 2f, 0);
lineTo(size, size);
lineTo(0, size);
closePath();
}
}
}
你永远不应该从可以改变UI状态并触发另一个重绘的paint中调用任何东西,否则你将最终在重绘的最终循环中最终消耗你的CPU.