Java在调用paint方法时清除屏幕-如何避免这种情况? [英] Java clears screen when calling paint method - how to avoid that?

查看:236
本文介绍了Java在调用paint方法时清除屏幕-如何避免这种情况?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图用Java在Canvas中绘制两条线,分别调用两种方法,但是当我绘制第二条线时,第一条消失了(Java清除了屏幕).我该如何避免呢?我想看两行.我看过绘画教程(如何制作Windows上的绘画"之类的教程),在该教程中,用户使用鼠标绘制线,而绘制一条线时,另一条不会消失.他们只是调用paint方法,而不会清除屏幕.

I'm trying to draw two lines in a Canvas in Java, calling two methods separately, but when I draw the second line, the first one disapears (Java clears the screen). How can I avoid that? I want to see the two lines. I've seen paint tutorials (how to make a program like the Paint on Windows) where the user uses the mouse to draw lines and when one line is drawn, the other do not disappear. They just call the paint method and it does not clear the screen.

如果有人可以帮助我,我将不胜感激. 谢谢.

I'll be grateful if anyone can help me. Thanks.

查看课程

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图形的所有好处,包括自动双缓冲.
  • super.paintComponent(g)方法应在paintComponent(Graphics g)替代中调用,通常是该方法内部的第一个方法调用.这样一来,该组件就可以自己进行内部管理绘画,包括擦除需要擦除的图纸.
  • 阅读有关Swing图形的教程,因为其中的大部分内容都得到了很好的解释.例如,请在这里查看:
    • 课程:执行自定义绘画
    • AWT和Swing中的绘画
      • You almost never should call paint(...) directly. I can count the times that I've needed to do this on one hand.
      • Do not get a Graphics object by calling getGraphics() on a component as that will return a non-durable Graphics object. Instead either draw in a BufferedImage and display that in the paint method or draw in the paint method (if AWT).
      • Since this is a Swing GUI, don't use an AWT component to draw in. Use a JPanel and override the paintComponent(...) method, not the paint(...) method. Otherwise you lose all benefits of Swing graphics including automatic double buffering.
      • The super.paintComponent(g) method should be called in the paintComponent(Graphics g) override, often as the first method call inside of this method. This lets the component do its own housekeeping painting, including erasing drawings that need to be erased.
      • Read the tutorials on Swing graphics as most of this is all well explained there. For e.g., please have a look here:
        • Lesson: Performing Custom Painting
        • Painting in AWT and Swing
        • 修改

          • 要使图像持久存在,建议您绘制一个BufferedImage,然后在JPanel的paintComponent(...)方法中显示该图像.
          • 或者另一个选择是创建一个Shape对象的集合,也许是一个ArrayList<Shape>,并用您要绘制的Shapes进行填充,然后在paintComponent(...)方法中将Graphics对象转换为Graphics2D对象,然后遍历Shape集合,并在迭代时使用g2d.draw(shape)绘制每个形状.
          • To have your images persist, I suggest that you draw to a BufferedImage and then display that Image in your JPanel's paintComponent(...) method.
          • Or another option is to create a Collection of Shape objects, perhaps an ArrayList<Shape> and fill it with the Shapes you'd like to draw, and then in the paintComponent(...) method cast the Graphics object to a Graphics2D object and iterate through the Shape collection drawing each shape with g2d.draw(shape) as you iterate.

          自垃圾桶发布代码以来,...

          Since Trash posted his code,...

          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;
          }
          

          这篇关于Java在调用paint方法时清除屏幕-如何避免这种情况?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆