形状出现片刻然后消失

时间:2016-08-06 22:56:29

标签: java canvas graphics

我试图在java中的画布上绘制简单的形状(使用Eclipse)。画布显示正确的大小和颜色。然而,形状只出现一秒然后消失。当它们出现时,它们具有正确的尺寸,颜色和位置,但它们会在一秒左右后消失。似乎我写的下面代码中缺少一行,但我无法弄清楚它是什么。

import java.awt.*;
import java.awt.geom.Ellipse2D;

import javax.swing.*;

    /**
     * Draws simple shapes
     */


public class SimpleDraw2 {
    private JFrame frame;
    private static Canvas canvas;
    private Container contentPane;
    private static Graphics graphics;
    private Ellipse2D.Double circle;

    /**
     * Constructor
     * Creates canvas and frame
     */
    public SimpleDraw2() {
        frame = new JFrame("Draw picture");
        contentPane = frame.getContentPane();
        canvas = new Canvas();
        canvas.setSize(250, 250);
        canvas.setBackground(Color.YELLOW);
        canvas.setForeground(Color.BLUE);
        contentPane.add(canvas);
        frame.pack();
        frame.setVisible(true);

    }//end constructor

    /**
     * Draws two circles
     * @param g
     */
    public void paint(Graphics g){
        circle = new Ellipse2D.Double(125, 125, 50, 50);
        g = canvas.getGraphics();
        if(g != null){
            ((Graphics2D) g).fill(circle);
            g.setColor(Color.GREEN);
            g.fillOval(0, 0, 50, 50);
        }
    }//end method

    /**
     * @param args
     */
    public static void main(String[] args) {
        SimpleDraw2 draw = new SimpleDraw2();
        draw.paint(graphics);
    }//end main

}//end class

3 个答案:

答案 0 :(得分:-1)

啊......在SimpleDraw2.paint()方法中,你得到画布,然后调用它的paint()方法。 你不应该这样做。忽略SimpleDraw2.paint(),而是将您的绘图代码发布在canvas.paint()方法中。这样就可以正确绘制。

SimpleDraw2.paint()内部的画布Painintg实际上会绘制到画布,但只要重新绘制,所有形状都将被清除。

请勿直接调用paint(Graphics),就像在main()方法中那样,而是调用repaint()

答案 1 :(得分:-1)

<强> [增订]

哦差点忘了...通常你应该把你的代码放到paintComponent()方法中。查看四个测试类。

在v1中,您创建的画布对象将绘制在绘画上方。我不完全知道绘图周期中的内容窗格绘图是什么,以及绘制子组件和/或布局管理器。这可能是原因之一,即使我们不调用super.paint(),画布仍然会被绘制。

V2(和v4)让您可以最大程度地控制绘画周期,使用双/多缓冲可以更加轻松。

V3是最简单的,只是直接绘制到主框架,没有任何变量或特殊魔法。

在v4中,您还可以连接该回调。给你很好的控制,也很简单。

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Ellipse2D.Double;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.WindowConstants;



public class GraphicsPaint {
    public static void main(final String[] args) {
        new SimpleDraw2v1();
        new SimpleDraw2v2();
        new SimpleDraw2v3();
        new SimpleDraw2v4();
    }
}



class SimpleDraw2v1 {
    private final JFrame        frame;
    private static Canvas       canvas;
    private final Container     contentPane;
    private static Graphics     graphics;
    private Ellipse2D.Double    circle;

    /**
     * Constructor
     * Creates canvas and frame
     */
    public SimpleDraw2v1() {
        frame = new JFrame("Draw picture");
        frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); // important
        contentPane = frame.getContentPane();
        canvas = new Canvas();
        canvas.setSize(250, 250);
        canvas.setBackground(Color.YELLOW);
        canvas.setForeground(Color.BLUE);
        contentPane.add(canvas);
        frame.pack();
        frame.setVisible(true);

    }//end constructor

    /**
     * Draws two circles
     * @param g
     */
    public void paint(final Graphics g) {
        circle = new Ellipse2D.Double(125, 125, 50, 50);

        final Graphics2D g2 = ((Graphics2D) g);
        g2.fill(circle);
        g2.setColor(Color.GREEN);
        g2.fillOval(0, 0, 50, 50);
    }//end method

}//end class



class SimpleDraw2v2 extends JFrame {
    private static final long serialVersionUID = 2057752114790427629L;

    public SimpleDraw2v2() {
        setTitle("Painting v2");
        setDefaultCloseOperation(DISPOSE_ON_CLOSE);
        setContentPane(new MyDrawPanel());
        setBounds(200, 200, 800, 600);
        setVisible(true);
    }
}



class MyDrawPanel extends JPanel {
    private static final long serialVersionUID = 6483380689207640805L;

    @Override public void paint(final Graphics pG) {
        // this call (or not overwriting paint() in the first place) results in
        super.paint(pG);

        // these three calls, in this order. you can test it
        //      paintComponent(pG);
        //      paintBorder(pG);
        //      paintChildren(pG);

        final Double circle = new Ellipse2D.Double(125, 125, 50, 50);

        final Graphics2D g2 = ((Graphics2D) pG);
        g2.fill(circle);
        g2.setColor(Color.GREEN);
        g2.fillOval(0, 0, 50, 50);
    }
    @Override protected void paintComponent(final Graphics pG) {
        System.out.println("MyDrawPanel.paintComponent()");
        super.paintComponent(pG);
    }
    @Override protected void paintBorder(final Graphics pG) {
        System.out.println("MyDrawPanel.paintBorder()");
        super.paintBorder(pG);
    }
    @Override protected void paintChildren(final Graphics pG) {
        System.out.println("MyDrawPanel.paintChildren()");
        super.paintChildren(pG);
    }
}



class SimpleDraw2v3 extends JFrame {
    private static final long serialVersionUID = 2057752114790427629L;

    public SimpleDraw2v3() {
        setTitle("Painting v3");
        setDefaultCloseOperation(DISPOSE_ON_CLOSE);
        setBounds(200, 200, 800, 600);
        setVisible(true);
    }

    @Override public void paint(final Graphics pG) {
        super.paint(pG);

        final Double circle = new Ellipse2D.Double(125, 125, 50, 50);
        final Graphics2D g2 = ((Graphics2D) pG);
        g2.fill(circle);
        g2.setColor(Color.GREEN);
        g2.fillOval(0, 0, 50, 50);
    }
}



class SimpleDraw2v4 extends JFrame {
    private static final long serialVersionUID = 2057752114790427629L;

    public SimpleDraw2v4() {
        setTitle("Painting v4");
        setDefaultCloseOperation(DISPOSE_ON_CLOSE);
        setContentPane(new JPanel() {
            private static final long serialVersionUID = -8011251549484904282L;

            @Override public void paint(final Graphics pG) {
                super.paint(pG);
                paintShapes((Graphics2D) pG); // use this call
            }
            @Override protected void paintComponent(Graphics pG) {
                super.paintComponent(pG);
                paintShapes((Graphics2D) pG); // or this call
            }
        });
        setBounds(200, 200, 800, 600);
        setVisible(true);
    }

    protected void paintShapes(final Graphics2D pG) {
        final Double circle = new Ellipse2D.Double(125, 125, 50, 50);
        pG.fill(circle);
        pG.setColor(Color.GREEN);
        pG.fillOval(0, 0, 50, 50);
    }

    @Override public void paint(final Graphics pG) {
        super.paint(pG);
    }
}

答案 2 :(得分:-1)

谢谢,周杰伦!版本2到4运行良好。版本1仍然给出了空白画布。我花了一段时间来搞清楚,但最终我得到了它的工作。事实证明我应该使用重写的update()而不是paint()。所以这里是将带有坐标和高度宽度的椭圆放入黄色画布的代码:

import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.geom.Ellipse2D;
import java.util.Scanner;

/**
 * Draws simple shapes
 */
public class SimpleDraw5 {

private Frame frame;
private static MyCanvas canvas;
private static Graphics graphics;
private Panel panel;
Ellipse2D.Double circle;

/**
 * Draws blue ellipses on yellow canvas
 * @param args
 */
public static void main(String[] args) {
    SimpleDraw5 draw = new SimpleDraw5();
    Scanner scan = new Scanner(System.in);
    draw.addShapes();
    int test;
    boolean exit = false;
    while (exit == false){
        System.out.println("Draw another?");
        System.out.println("Enter 1 to keep drawing, 2 to close window "
                + "3 to stop but keep window open>");
        test = scan.nextInt();
        if(test == 1){
            draw.addShapes();
        }
        else if (test == 2)
            System.exit(0);
        else
            exit = true;
    }

}//end main

/**
 * Constructor
 * Creates canvas and frame
 */
public SimpleDraw5() {
    frame = new Frame("Draw picture");
    frame.addWindowListener(new WindowAdapter() {
        public void windowClosing(WindowEvent windowEvent){
            System.exit(0);
        } } );
    panel = new Panel();
    frame.add(panel);
    canvas = new MyCanvas();
    panel.add(canvas);
    frame.pack();
    frame.setVisible(true);
}


public void addShapes(){
    canvas.update(canvas.getGraphics());
    frame.pack();
    frame.setVisible(true);
}

/**
 * Returns circle set with paramenters
 * @param x - X coordinate
 * @param y - Y coordinate
 * @param height
 * @param width
 * @return - object of class Ellipse2D.Double
 */
public static Ellipse2D.Double getCircle(int x, int y, int height, int width){
    Ellipse2D.Double circle = new Ellipse2D.Double(x,y,height, width);
    return circle;
}//end method

/**
 * Returns "default" circle
 * @return - object of class Ellipse2D.Double
 */
public static Ellipse2D.Double getCircle(){
    Ellipse2D.Double circle = new Ellipse2D.Double(0,0,50, 50);
    return circle;
}//end method

/**
 * Inner class- defines canvas
 *
 */
class MyCanvas extends Canvas{

    private static final long serialVersionUID = 1L;
    private Ellipse2D.Double circle;

    /**
     * Constructor. Sets canvas size and colors
     */
    public MyCanvas(){
        setSize(250, 250);
        setBackground(Color.YELLOW);
        setForeground(Color.BLUE);

    }//end


    /* (non-Javadoc)
     * @see java.awt.Canvas#paint(java.awt.Graphics)
     */
    public void paint(Graphics g){
        super.paint(g);
        frame.setVisible(true);
    }//end method


    /* (non-Javadoc)
     * @see java.awt.Canvas#update(java.awt.Graphics)
     */
    public void update(Graphics g){
        g = this.getGraphics();
        g.setColor(Color.BLUE);
        Scanner scan = new Scanner(System.in);
        System.out.println("Enter x");
        int x = scan.nextInt();
        System.out.println("Enter y");
        int y = scan.nextInt();
        System.out.println("Enter w");
        int w = scan.nextInt();
        System.out.println("Enter h");
        int h = scan.nextInt();
        Ellipse2D.Double circle = getCircle(x,y,w,h);
        ((Graphics2D) g).fill(circle);
        ((Graphics2D) g).draw(circle);
        graphics = g;
    }//end method   
}//end inner class
}//end class