4

さまざまな形を描くペイント アプレットに取り組んでいます。マウスをドラッグしながら線を描きたい。問題は、線が表示されると、下の画像のようになることです。

ここに画像の説明を入力

私は1つのポイント(開始点)を使用して構築されたクラスラインを持っており、setDragPointドラッグ中にラインをペイントするためにマウスドラッグポイントを取得するメソッドがありdrawingImage、ドラッグモードで描画中にちらつきが多すぎます。なぜそれが起こるのですか?

import java.applet.*;
import java.awt.event.*;
import java.awt.*;
import java.util.*;

public class PaintBrush extends Applet implements MouseListener, MouseMotionListener {

Shape shape;
Point startPoint;
Point dragPoint;
ArrayList<Shape> shapes;
Choice shapeChoice;
Choice colorChoice;
Choice fillChoice;
Image drawingImage;
Graphics drawGraphics;
String shapeString, colorString, fillString;
boolean isDragMode;

public void init() {
    shapes = new ArrayList<Shape>();
    shapeChoice = new Choice();
    shapeChoice.addItem("Line");
    shapeChoice.addItem("Rectangle");
    shapeChoice.addItem("RoundRect");
    shapeChoice.addItem("Oval");
    shapeChoice.addItem("FreeHand");

    add(shapeChoice);

    colorChoice = new Choice();
    colorChoice.addItem("Red");
    colorChoice.addItem("Green");
    colorChoice.addItem("Blue");

    add(colorChoice);

    fillChoice = new Choice();
    fillChoice.addItem("Filled");
    fillChoice.addItem("Hollow");
    add(fillChoice);

    shapeString = shapeChoice.getSelectedItem();
    colorString = colorChoice.getSelectedItem();
    fillString = fillChoice.getSelectedItem();

    drawingImage = createImage(getSize().width, getSize().height);
    drawGraphics = drawingImage.getGraphics();
    System.out.println("set up image");
    drawGraphics.setColor(Color.black);
    drawGraphics.fillRect(0, 0, getSize().width, getSize().height);
    drawGraphics.setColor(Color.orange);
    drawGraphics.drawRect(0, 0, getSize().width - 1, getSize().height - 1);
    drawGraphics.drawRect(1, 1, getSize().width - 3, getSize().height - 3);
    startPoint = new Point(0, 0);
    dragPoint = new Point(0, 0);
    addMouseListener(this);
    addMouseMotionListener(this);
}

public void mouseEntered(MouseEvent e) {
}

public void mouseExited(MouseEvent e) {
}

public void mouseClicked(MouseEvent e) {
}

public void mousePressed(MouseEvent e) {

    System.out.println("Pressed");

    startPoint.x = e.getX();
    startPoint.y = e.getY();
    repaint();

    switch (shapeString) {
        case "Line":
            shape = new Line(startPoint.x, startPoint.y);  //step 1 here i construct a new line using the start point (the point at which the mouse is pressed)

            break;
        case "FreeHand":
            shape = new FreeShape();
            break;
    }


    }

public void mouseReleased(MouseEvent e) {
    if (isDragMode) {
        shapes.add(shape);
        isDragMode = false;
     }
    repaint();

}

public void mouseMoved(MouseEvent e) {
}

public void mouseDragged(MouseEvent e) {
    System.out.println("Dragged");
    isDragMode = true;
    dragPoint.x = e.getX();
    dragPoint.y = e.getY();

    switch (shapeString) {
        case "Line":
            shape.setDragPoint(dragPoint.x, dragPoint.y);  //here i set the drag points to the already created line at step 1 
              break;
        case "FreeHand":
            shape = new FreeShape();
            break;
    }

    shape.drawWhileDragging(drawGraphics); // i call this method to draw while mouse is dragging

    repaint();


}

public void paint(Graphics g) {

  update(g);
}
 public void update(Graphics g) {

  // create an off-screen graphics drawing environment if none
  //existed
  // or if the user resized the applet drawing area to a different
 // size
   if (drawingImage == null)
{

System.out.println("Image is Null");
    drawingImage = createImage(getSize().width,getSize().height);
drawGraphics = drawingImage.getGraphics();
}



  // erase the previous image
  drawGraphics.setColor(Color.black);
  drawGraphics.fillRect(0,0,getSize().width,getSize().height);
  drawGraphics.setColor(Color.orange);
  drawGraphics.drawRect(0,0,getSize().width-1,getSize().height-1);
  drawGraphics.drawRect(1,1,getSize().width-3,getSize().height-3);  

   for(Shape s:shapes)
         s.draw(drawGraphics);

  // paint the offscreen image to the applet viewing window
  g.drawImage(drawingImage,0,0,this);

   }
 }


abstract class Shape {

Color shapeColor;
boolean filled;

abstract void draw(Graphics g);

void drawWhileDragging(Graphics g) {
}

void setDragPoint(int x, int y) {
}
}

 class Line extends Shape {

private Point startPoint;
private Point currentPoint;

public Point getStartPoint() {
    return startPoint;
}

public Point getCurrentPoint() {
    return currentPoint;
}

public void setStartPoint(Point point) {
    this.startPoint = point;
}

public void setCurrentPoint(Point point) {
    this.currentPoint = point;
}

void drawWhileDragging(Graphics g) {
    g.drawLine(startPoint.x, startPoint.y, currentPoint.x, currentPoint.y); 
}

public void draw(Graphics g) {
    g.drawLine(startPoint.x, startPoint.y, currentPoint.x, currentPoint.y);
}

Line() {
    startPoint = new Point(0, 0);
    currentPoint = new Point(0, 0);
}

Line(int x1, int y1) {
    this();
    this.startPoint.x = x1; 
    this.startPoint.y = y1;
}

void setDragPoint(int x, int y) {
    this.currentPoint.x = x;
    this.currentPoint.y = y;
    System.out.println("Current-X:" + currentPoint.x + " currentPoint-Y" + currentPoint.y);
    System.out.println("start-X:" + startPoint.x + " startPoint-Y" + startPoint.y);
  }

 }

class FreeShape extends Shape {

private ArrayList<Point> dragPoints = new ArrayList<Point>();

public ArrayList<Point> getDragPoints() {
    return dragPoints;
}

public void setDragPoints(Point point) {
    dragPoints.add(point);
}

public void draw(Graphics g) {
}

public FreeShape() {
  }
}


class Rectangle extends Shape {

public void draw(Graphics g) {
   }
 }


class Oval extends Shape {

public void draw(Graphics g) {
   }
 }
4

2 に答える 2

1

最近、似たようなタイプのアプリを書きました。これがスクリーンショットです。ご覧のとおり、完全には開発されていません。ここに画像の説明を入力してください

今、私もあなたが今直面しているのと同じような問題に直面しました。あなたがしなければならないことはです。

  • すべてのペイント操作をダブルバッファリング
  • repaintを呼び出して画面をクリアしないでください。Repaint実際には、最初に画面が背景色で塗りつぶされます。これが、表示されているちらつきです。

現在のスクリーンキャンバスのコピーをで作成できますImage。はImage、描画操作のたびに更新されます。したがって、自分が行うことを呼び出して画面をクリアする代わりに、キャンバスにrepaintを描画します。Imageこれは、ダブルバッファリングのようなものです。

repaintコードでは、マウスをドラッグするたびに呼び出しています。それがちらつきの原因です。


アップデート

新しく更新されたコードで見つけた3つの主要な問題

  • メソッドではdrawWhileDragging、ライングラフィックスコンテキストの描画色を変更していません。したがって、線は実際には黒で描画され、背景も黒になります。その結果、何も見えなくなります。
  • これと同じ方法で、のグラフィックスコンテキスト(つまり参照)を渡しますdrawingImage。その結果、線は実際には画面上ではなく、画面外の画像上に描画されます。
  • メソッドではmouseDragged、ドラッグするたびにrepaintを呼び出します。その結果、実際には何も描かれていません

私は自分のマシンでコードを実行し、必要な変更を加えました。短くするために、変更されたメソッドのみを投稿しています。

これが更新されたmouseDraggedメソッドです

    public void mouseDragged(MouseEvent e) {
        System.out.println("Dragged");
        isDragMode = true;
        dragPoint.x = e.getX();
        dragPoint.y = e.getY();

        switch (shapeString) {
            case "Line":
                shape.setDragPoint(dragPoint.x, dragPoint.y);  //here i set the drag points to the already created line at step 1
                break;
            case "FreeHand":
                shape = new FreeShape();
                break;
        }

        getGraphics().drawImage(drawingImage, 0,0,null); //Added this line
        shape.drawWhileDragging(getGraphics()); // i call this method to draw while mouse is dragging
    }

これが更新されたdrawWhileDraggingメソッドです

    void drawWhileDragging(Graphics g) {
        g.setColor(Color.ORANGE);
        g.drawLine(startPoint.x, startPoint.y, currentPoint.x, currentPoint.y);
        g.setColor(Color.BLACK);
    }

さて、色をオレンジに設定しました。あなたがしなければならないのは、Choiceメニューに従って色を設定することです。

他の形状を描画する場合にも、同様のアナロジーを実装できます。

于 2012-12-29T06:01:32.007 に答える
0

あなたが抱えている問題は、ダブルバッファリングを実行しようとしている方法に帰着します。行の位置を更新するときにバッキング バッファーをクリアするのではなく、ブラック ボードに描画するように、単純に連続して描画します。

代わりに、グラフィック コンテンツをクリアして更新を再適用する必要があります。驚くべきことに、これはpaint実際に行うことの一部ですが、super.paint

paintトップレベルのコンテナをオーバーライドする必要はめったになく、トップレベルのコンテナのメソッドをオーバーライドする必要もめったにありません。他のすべてとは別に、ダブルバッファリングはありません。

代わりに、代わりに次のようなものを使用してJPanelください。

色を除いて、例を更新しました。色は実際にはシェイプによって維持され、ペイント時に適用される必要があります。

public class BadPaint06 extends JApplet {

    public void init() {
        setLayout(new BorderLayout());
    }

    @Override
    public void start() {
        add(new PaintPane());
    }

    public class PaintPane extends JPanel implements MouseListener, MouseMotionListener {

        Shape shape;
        Point startPoint;
        Point dragPoint;
        ArrayList<Shape> shapes;
        Choice shapeChoice;
        Choice colorChoice;
        Choice fillChoice;
        Image drawingImage;
        Graphics drawGraphics;
        String shapeString, colorString, fillString;
        boolean isDragMode;

        public PaintPane() {
            shapes = new ArrayList<Shape>();
            shapeChoice = new Choice();
            shapeChoice.addItem("Line");
            shapeChoice.addItem("Rectangle");
            shapeChoice.addItem("RoundRect");
            shapeChoice.addItem("Oval");
            shapeChoice.addItem("FreeHand");

            add(shapeChoice);

            colorChoice = new Choice();
            colorChoice.addItem("Red");
            colorChoice.addItem("Green");
            colorChoice.addItem("Blue");

            add(colorChoice);

            fillChoice = new Choice();
            fillChoice.addItem("Filled");
            fillChoice.addItem("Hollow");
            add(fillChoice);

            shapeString = shapeChoice.getSelectedItem();
            colorString = colorChoice.getSelectedItem();
            fillString = fillChoice.getSelectedItem();

            startPoint = new Point(0, 0);
            dragPoint = new Point(0, 0);
            addMouseListener(this);
            addMouseMotionListener(this);
        }

        @Override
        public void invalidate() {

            drawingImage = null;

            super.invalidate(); 

        }

        public void mouseEntered(MouseEvent e) {
        }

        public void mouseExited(MouseEvent e) {
        }

        public void mouseClicked(MouseEvent e) {
        }

        public void mousePressed(MouseEvent e) {

            startPoint.x = e.getX();
            startPoint.y = e.getY();
            repaint();

            switch (shapeString) {
                case "Line":
                    shape = new Line(startPoint.x, startPoint.y);  //step 1 here i construct a new line using the start point (the point at which the mouse is pressed)

                    break;
                case "FreeHand":
                    shape = new FreeShape();
                    break;
            }


        }

        public void mouseReleased(MouseEvent e) {
            if (isDragMode) {
                shapes.add(shape);
                isDragMode = false;
            }
            repaint();

        }

        public void mouseMoved(MouseEvent e) {
        }

        public void mouseDragged(MouseEvent e) {
            System.out.println("Dragged");
            isDragMode = true;
            dragPoint.x = e.getX();
            dragPoint.y = e.getY();

            switch (shapeString) {
                case "Line":
                    shape.setDragPoint(dragPoint.x, dragPoint.y);  //here i set the drag points to the already created line at step 1 
                    break;
                case "FreeHand":
                    shape = new FreeShape();
                    break;
            }

            repaint();


        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);

            System.out.println("In Paint");
            if (drawingImage == null) {
                drawingImage = createImage(getSize().width, getSize().height);
                drawGraphics = drawingImage.getGraphics();
                System.out.println("set up image");
                drawGraphics.setColor(Color.black);
                drawGraphics.fillRect(0, 0, getSize().width, getSize().height);
                drawGraphics.setColor(Color.orange);
                drawGraphics.drawRect(0, 0, getSize().width - 1, getSize().height - 1);
                drawGraphics.drawRect(1, 1, getSize().width - 3, getSize().height - 3);
                drawGraphics.dispose();
            }

            g.drawImage(drawingImage, 0, 0, this);

            for (Shape shape : shapes) {
                shape.draw(g);
            }


            if (shape != null) {
                shape.drawWhileDragging(g); // i call this method to draw while mouse is dragging
            }

        }
    }

    abstract class Shape {

        Color shapeColor;
        boolean filled;

        abstract void draw(Graphics g);

        void drawWhileDragging(Graphics g) {
        }

        void setDragPoint(int x, int y) {
        }
    }

    class Line extends Shape {

        private Point startPoint;
        private Point currentPoint;

        public Point getStartPoint() {
            return startPoint;
        }

        public Point getCurrentPoint() {
            return currentPoint;
        }

        public void setStartPoint(Point point) {
            this.startPoint = point;
        }

        public void setCurrentPoint(Point point) {
            this.currentPoint = point;
        }

        void drawWhileDragging(Graphics g) {
            if (currentPoint != null) {
                g.drawLine(startPoint.x, startPoint.y, currentPoint.x, currentPoint.y);
            }
        }

        public void draw(Graphics g) {
            if (currentPoint != null) {
                g.drawLine(startPoint.x, startPoint.y, currentPoint.x, currentPoint.y);
            }
        }

        Line() {
            startPoint = new Point(0, 0);
//            currentPoint = new Point(0, 0);
        }

        Line(int x1, int y1) {
            this();
            this.startPoint.x = x1;
            this.startPoint.y = y1;
        }

        void setDragPoint(int x, int y) {
            currentPoint = new Point(x, y);
//            this.currentPoint.x = x;
//            this.currentPoint.y = y;
            System.out.println("Current-X:" + currentPoint.x + " currentPoint-Y" + currentPoint.y);
            System.out.println("start-X:" + startPoint.x + " startPoint-Y" + startPoint.y);
        }
    }

    class FreeShape extends Shape {

        private ArrayList<Point> dragPoints = new ArrayList<Point>();

        public ArrayList<Point> getDragPoints() {
            return dragPoints;
        }

        public void setDragPoints(Point point) {
            dragPoints.add(point);
        }

        public void draw(Graphics g) {
        }

        public FreeShape() {
        }
    }

    class Rectangle extends Shape {

        public void draw(Graphics g) {
        }
    }

    class Oval extends Shape {

        public void draw(Graphics g) {
        }
    }
}
于 2012-12-29T07:16:27.983 に答える