我试图用java在画布上画两行,分别调用两个方法,但是当我画第二行时,第一行就消失了(java清除了屏幕)。我怎样才能避免呢?我想看看这两条线。我看过画图教程(如何制作像windows上的画图一样的程序),用户用鼠标画线,画一条线时,另一条不会消失。他们只是调用paint方法,它并没有清除屏幕。
如果有人能帮助我,我将不胜感激。
谢谢。
视图类import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JFrame;
public class CircuitTracePlotView extends JFrame {
private CircuitTracePlot circuitTracePlot;
public CircuitTracePlotView() {
this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
this.getContentPane().add(circuitTracePlot = new CircuitTracePlot(), BorderLayout.CENTER);
this.pack();
this.setSize(250,250);
this.setLocationRelativeTo(null);
this.setVisible(true);
circuitTracePlot.drawLine();
circuitTracePlot.drawOval();
}
}
class CircuitTracePlot extends Canvas {
private final static short LINE = 1;
private final static short OVAL = 2;
private int paintType;
private int x1;
private int y1;
private int x2;
private int y2;
public CircuitTracePlot() {
this.setSize(250,250);
this.setBackground(Color.WHITE);
}
private void setPaintType(int paintType) {
this.paintType = paintType;
}
private int getPaintType() {
return this.paintType;
}
public void drawLine() {
this.setPaintType(LINE);
this.paint(this.getGraphics());
}
public void drawOval() {
this.setPaintType(OVAL);
this.paint(this.getGraphics());
}
public void repaint() {
this.update(this.getGraphics());
}
public void update(Graphics g) {
this.paint(g);
}
public void paint(Graphics g) {
switch (paintType) {
case LINE:
this.getGraphics().drawLine(10, 10, 30, 30);
case OVAL:
this.getGraphics().drawLine(10, 20, 30, 30);
}
}
}
主要类别
import javax.swing.SwingUtilities;
import view.CircuitTracePlotView;
public class Main {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
CircuitTracePlotView cr = new CircuitTracePlotView();
}
});
}
}
最佳答案:
你几乎不应该直接给paint(...)打电话。我一方面可以数出我需要做的次数。
不要通过对组件调用getGraphics()来获取图形对象,因为这样会返回一个非持久图形对象。相反,要么在bufferedimage中绘制并在paint方法中显示,要么在paint方法中绘制(如果awt)。
因为这是一个swing gui,所以不要使用awt组件来绘制。使用jpanel并重写paintComponent(...)方法,而不是paint(...)方法。否则,您将失去swing图形的所有好处,包括自动双缓冲。
super.paintComponent(g)方法应该在paintComponent(Graphics g)重写中调用,通常作为此方法内部的第一个方法调用。这使组件可以自己进行内务处理绘制,包括擦除需要擦除的绘图。
请阅读有关swing图形的教程,因为大部分内容都在这里得到了很好的解释。例如,请看这里:
Lesson: Performing Custom Painting
Painting in AWT and Swing
编辑
为了让图像保持不变,我建议您绘制一个bufferedimage,然后在jpanel的paintComponent(...)方法中显示该图像。
或者另一个选项是创建一个形状对象集合,可能是一个ArrayList并用您要绘制的形状填充它,然后在paintComponent(...)方法中将图形对象转换为一个graphics2d对象,并在迭代时用g2d.draw(shape)遍历形状集合,绘制每个形状。
自从垃圾贴出他的密码…import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class CircuitTracePlot2 extends JPanel {
private static final int PREF_W = 250;
private static final int PREF_H = PREF_W;
private int drawWidth = 160;
private int drawHeight = drawWidth;
private int drawX = 10;
private int drawY = 10;
private PaintType paintType = PaintType.LINE;
public CircuitTracePlot2() {
}
@Override
public Dimension getPreferredSize() {
return new Dimension(PREF_W, PREF_H);
}
public void setPaintType(PaintType paintType) {
this.paintType = paintType;
repaint();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (paintType == null) {
return;
}
switch (paintType) {
case LINE:
g.drawLine(drawX, drawY, drawWidth, drawHeight);
break;
case OVAL:
g.drawOval(drawX, drawY, drawWidth, drawHeight);
break;
case SQUARE:
g.drawRect(drawX, drawY, drawWidth, drawHeight);
default:
break;
}
}
private static void createAndShowGui() {
final CircuitTracePlot2 circuitTracePlot = new CircuitTracePlot2();
JFrame frame = new JFrame("CircuitTracePlot2");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(circuitTracePlot);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
int timerDelay = 2 * 1000;
new Timer(timerDelay , new ActionListener() {
private int paintTypeIndex = 0;
@Override
public void actionPerformed(ActionEvent arg0) {
paintTypeIndex++;
paintTypeIndex %= PaintType.values().length;
circuitTracePlot.setPaintType(PaintType.values()[paintTypeIndex]);
}
}).start();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
enum PaintType {
LINE, OVAL, SQUARE;
}