鼠标绘制Java时处理闪烁

时间:2016-04-05 07:45:56

标签: java

package first_shape_drawing;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Scanner;

import javax.swing.JFrame;
import javax.swing.Timer;

public class DrawingProgram extends JFrame {
    private final static int DELAY = 10000;

    Drawing drawing = new Drawing();

    // INNER Class
    class MyMouseHandler extends MouseAdapter
    {        
        public void mousePressed(MouseEvent e)
        {
            drawing.mousePressed(e.getPoint());
            repaint();
        }
        public void mouseReleased(MouseEvent e)
        {
            drawing.mouseReleased(e.getPoint());
            repaint();
        }
        public void mouseDragged(MouseEvent e)
        {
            drawing.mouseDragged(e.getPoint());
            repaint();
        }
    }

    DrawingProgram()
    {
        super("My Drawing Program");
        setSize(800, 400);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        MyMouseHandler mmh = new MyMouseHandler();
        addMouseListener(mmh);
        addMouseMotionListener(mmh);
        setVisible(true);
    }
    public void paint(Graphics g)
    {
        Dimension dimen = getSize();
        Insets insets = getInsets();
        int top = insets.top;
        int left = insets.left;
        g.setColor(Color.white);
        g.fillRect(0, 0, dimen.width, dimen.height);
        drawing.draw(g);
        String str = drawing.toString();
        System.out.println(str); 
    }

    public static void main(String[] args) {

        DrawingProgram dp = new DrawingProgram();
        Scanner keyboard = new Scanner(System.in);

        boolean continueFlag=true;
        while(continueFlag)
        {
            System.out.println("Cmds: r,o,l,s,p,a,q,?,f,d,b,m,g");
            String str = keyboard.next().toLowerCase();
            if (str.length() == 0) continue;

            switch(str.charAt(0))
            {
            case 'r':
                dp.drawing.setDrawType(DrawType.rectangle);
                break;
            case 'o':
                dp.drawing.setDrawType(DrawType.oval);
                break;
            case 'l':
                dp.drawing.setDrawType(DrawType.line);
                break;
            case 's':
                dp.drawing.setDrawType(DrawType.scribble);
                break;
            case 'p':
            case 'a':
                dp.drawing.setDrawType(DrawType.polygon);
                break;
            case 'q':
                continueFlag = false;
                break;
            case 'f':
                dp.drawing.setFilled(true);
                break;
            case 'd':
                dp.drawing.setFilled(false);
                break;
            case 'b':
                dp.drawing.setColor(Color.blue);
                break;
            case 'm':
                dp.drawing.setColor(Color.magenta);
                break;
            case 'g':
                dp.drawing.setColor(Color.green);
                break;
            default: // '?' comes here
                System.out.println("r - drawType= Rectangle");
                System.out.println("o - drawType= Oval");
                System.out.println("l - drawType= Line");
                System.out.println("s - drawType= Scribble");
                System.out.println("p - drawType= Polygon");
                System.out.println("a - another Polygon");
                System.out.println("q - quit");
                System.out.println("f - filled objects");
                System.out.println("d - draw objects (not filled)");
                System.out.println("b - Use Blue Color");
                System.out.println("m - Use magenta Color");
                System.out.println("g - Use Green Color");
                break;
            }
        }
        System.out.println("Exitting the Drawing Program");
        dp.dispose();
        keyboard.close();

    }
}

我每次画画时如何防止这种情况发生闪烁?我已经检查了其他一些问题以及其他一些网站,但我无法确定如何实现我想要的内容。基本上,每当我去绘画时,面板都会闪烁。

如果这也是相关的,这里是Drawing.java

package first_shape_drawing;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.util.ArrayList;

enum DrawType {scribble, oval,  rectangle, polygon, line};

class DrawingProperties
{
    DrawType drawType;
    boolean filled;
    Color color;
    DrawingProperties(DrawType drawType, Color color, boolean filled)
    {
        this.drawType = drawType;
        this.color = color;
        this.filled = filled;
    }
    public String toString()
    {
        return drawType + " color=" + color +" filled="+ filled;
    }
}

public class Drawing {
    DrawingProperties drawingProperties = new DrawingProperties(DrawType.rectangle, Color.blue, false);
    ArrayList<Shape> shapeArr = new ArrayList<Shape>();
    Shape inProgress = null;

    public String toString()
    {
        return drawingProperties.toString();
    }
    public void draw(Graphics g)
    {
        for (int i=0; i < shapeArr.size(); i++)
        {
            Shape s = shapeArr.get(i);
            s.draw(g);
        }
        if (inProgress != null)
            inProgress.draw(g);
    }
    public void setColor(Color color)
    {
        drawingProperties.color = color;
    }

    public void setFilled(boolean filled)
    {
        drawingProperties.filled = filled;
    }
    public void setDrawType(DrawType drawType)
    {
        drawingProperties.drawType = drawType;
    }

    public void mousePressed(Point p)
    {
        switch(drawingProperties.drawType)
        {
        case rectangle:
            inProgress = new Rectangle(drawingProperties.color, drawingProperties.filled);
            break;
        case oval:
            inProgress = new Oval(drawingProperties.color, drawingProperties.filled);
            break;
        case line:
            inProgress = new Line(drawingProperties.color);
            break;
        case scribble:
            inProgress = new Scribble(drawingProperties.color);
            break;
        }
        inProgress.firstPoint(p);
    }

    public void mouseDragged(Point p)
    {
        switch(drawingProperties.drawType)
        {
        case rectangle:
        case oval:
        case scribble:
        case line:
            inProgress.subsequentPoint(p);
            break;
        }
    }
    public void mouseReleased(Point p)
    {
        inProgress.subsequentPoint(p);
        shapeArr.add(inProgress);
        inProgress = null;
    }

}

abstract class Shape
{
    Color color;
    Shape ( Color c)
    {
        color =c;
    }
    abstract void firstPoint(Point p);
    abstract void draw(Graphics g);
    abstract void subsequentPoint(Point p);
}
class Rectangle extends Shape
{
    boolean filled=false;
    Point start;
    Point lastPoint;
    Rectangle(Color c, boolean filled)
    {
        super(c);
        lastPoint = start;
        this.filled = filled;
    }
    @Override
    void firstPoint(Point p) {
        start =p;
        lastPoint =p;
    }
    @Override
    void draw(Graphics g) {
        g.setColor(color);
        int x = Math.min(start.x, lastPoint.x);
        int y = Math.min(start.y, lastPoint.y);
        int w = Math.abs(start.x - lastPoint.x);
        int h = Math.abs(start.y - lastPoint.y);
        if (filled)
            g.fillRect(x, y, w, h);
        else
            g.drawRect(x, y, w, h);

    }
    @Override
    void subsequentPoint(Point p) {
        lastPoint =p;

    }
}

class Scribble extends Shape
{
    ArrayList<Point> points= new ArrayList<Point>();
    Scribble(Color c)
    {
        super(c);
    }
    @Override
    void firstPoint(Point p) {
        points.add(p);

    }
    @Override
    void draw(Graphics g) {
        g.setColor(color);
        for (int i=1; i < points.size(); i++)
        {            
            Point first = points.get(i-1);
            Point next = points.get(i);
            g.drawLine(first.x, first.y, next.x, next.y);
        }

    }
    @Override
    void subsequentPoint(Point p) {
        points.add(p);

    }
}

class Oval extends Shape {
    boolean filled=false;
    Point start;
    Point lastPoint;
    Oval(Color c, boolean filled)
    {
        super(c);
        lastPoint = start;
        this.filled = filled;
    }
    @Override
    void firstPoint(Point p) {
        start =p;
        lastPoint =p;
    }
    @Override
    void draw(Graphics g) {
        g.setColor(color);
        //oval is int x, int y, int width, int height
        int x = Math.min(start.x, lastPoint.x);
        int y = Math.min(start.y, lastPoint.y);
        int w = Math.abs(start.x - lastPoint.x);
        int h = Math.abs(start.y - lastPoint.y);
        if (filled)
            g.fillOval(x, y, w, h);
        else
            g.drawOval(x, y, w, h);

    }
    @Override
    void subsequentPoint(Point p) {
        lastPoint =p;

    }
}
class Line extends Shape
{
    Point start;
    Point lastPoint;
    Line(Color c)
    {
        super(c);
    }
    @Override
    void firstPoint(Point p) {
        start =p;
        lastPoint =p;
    }
    @Override
    void draw(Graphics g) {
        g.setColor(color);
        g.drawLine(start.x, start.y, lastPoint.x, lastPoint.y);
    }
    @Override
    void subsequentPoint(Point p) {
        lastPoint =p;
    }
}

2 个答案:

答案 0 :(得分:0)

不确定正确的方法是什么,但问题出在哪里:

    g.setColor(Color.white);
    g.fillRect(0, 0, dimen.width, dimen.height);

您可以在任何绘图之前删除整个面板,即先将其全部涂成白色。这不是必要的。

删除这两行,你的闪烁就会停止。

结果可能会出现其他问题,但在绘图之前擦除整个面板几乎总是闪烁的。

答案 1 :(得分:0)

如果你想避免闪烁,你必须在图像上绘制所有内容并在paint()中绘制该图像。

public void paint(Graphics g)
{
    Dimension dimen = getSize();
    Insets insets = getInsets();
    int top = insets.top;
    int left = insets.left;
    if(im!=null) {
      Graphics g2=im.getGraphics();
      g2.setColor(Color.white);
      g2.fillRect(0, 0, im.getWidth(null), im.getHeight(null));
      drawing.draw(im);
      g.drawImage(im, 0, 0, this);
    }
    String str = drawing.toString();
    System.out.println(str); 
}

您将图像定义为

Image im;

并在设置为visible后在构造函数中启动它:

    setVisible(true);
    im=createImage(getWidth(), getHeight());

然后你有另外一个这样的绘制功能

public void draw(Image im)
{

  Graphics g=im.getGraphics();
    for (int i=0; i < shapeArr.size(); i++)
    {
        Shape s = shapeArr.get(i);
        s.draw(g);
    }
    if (inProgress != null)
        inProgress.draw(g);
}