调用paint方法时Java清除屏幕 – 如何避免?

我试图在Java中的Canvas中绘制两行,分别调用两个方法,但是当我绘制第二行时,第一行消失(Java清除屏幕).我怎么能避免这种情况?我想看两条线.我已经看过油漆教程(如何制作像Windows上的Paint这样的程序)用户使用鼠标绘制线条,当绘制一条线时,另一条线不会消失.他们只是调用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()来获取Graphics对象,因为它将返回非持久的Graphics对象.而是绘制BufferedImage并在paint方法中显示或在paint方法中绘制(如果是AWT).
>由于这是一个Swing GUI,因此不要使用AWT组件进行绘制.使用JPanel并覆盖paintComponent(…)方法,而不是paint(…)方法.否则你将失去Swing图形的所有好处,包括自动双缓冲.
>应该在paintComponent(Graphics g)覆盖中调用super.paintComponent(g)方法,通常作为此方法内部的第一个方法调用.这使组件可以自己进行管家绘画,包括擦除需要擦除的绘图.
>阅读有关Swing图形的教程,因为大部分内容都在那里得到了很好的解释.例如,请看这里:

> Lesson: Performing Custom Painting
> Painting in AWT and Swing

编辑

>为了保持图像的持久性,我建议您绘制一个BufferedImage,然后在JPanel的paintComponent(…)方法中显示该图像.
>或者另一种选择是创建一个Shape对象集合,可能是一个ArrayList< Shape>并使用您想要绘制的Shapes填充它,然后在paintComponent(…)方法中将Graphics对象强制转换为Graphics2D对象并遍历Shape集合,使用g2d.draw(shape)绘制每个形状重复.

自Trash发布他的代码,…

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;
}
上一篇:SAP 获取批次信息函数(MSC3N)


下一篇:ruby formatting time