Thema in zeichnen von Linien, während Sie die Maus ziehen
Arbeite ich auf einem Farb-applet, das zeichnet verschiedene Formen. Ich möchte, um Linien zu zeichnen, während Sie die Maus ziehen. Das problem ist, dass wenn die Zeilen erscheinen, sind Sie wie im Bild unten gezeigt.
Habe ich die Klasse Linie, die konstruiert wird, mit einem Punkt (Startpunkt)
und es hat eine Methode namens setDragPoint
nimmt, dass die Maus bewegen Sie die Punkte, um zu malen, Linien ziehen, während auch die drawingImage
macht zu viele flackert beim zeichnen im ziehen-Modus. Warum ist das passiert?
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) {
}
}
public class PaintBrush extends Applet..
Es sollte verlängernJApplet
in diesem Jahrtausend.Cannot switch on a value of type String. Only convertible int values or enum constants are permitted
, Hat es dir angezeigt?- Ein bisschen außerhalb des Themas: Ihre Kopie von Windows 7 ist nicht echt, eh.
- Schauen Sie auf meine aktualisierte Antwort
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich geschrieben habe, eine ähnliche Art von Anwendung vor kurzem. Hier ist der screenshot. Es ist noch nicht voll entwickelt, wie Sie sehen können.
Nun, ich habe auch vor ähnlichen Problemen, wie Sie nun konfrontiert sind. Was Sie tun müssen, ist.
Repaint
eigentlich zuerst füllt den Bildschirm mit der hintergrund-Farbe & und das ist das flimmern Sie sehen.Können Sie eine Kopie des aktuellen Bildschirm-Leinwand in einem
Image
. DieImage
wird aktualisiert, nachdem alle Zeichenoperationen. Also Statt der clearing-Bildschirm durch den Aufrufrepaint
was Sie tun, ist ziehen Sie dieImage
auf der Leinwand. Dies ist, wie doppelte Pufferung.In Ihrem code, den Sie anrufen
repaint
jedes mal, wenn die Maus gezogen wird. Das ist die Ursache für das flimmern.UPDATE
Drei große Fragen fand ich in Ihrem neu aktualisierten code
drawWhileDragging
Methode ändern Sie nicht die Linie Grafiken Rahmen zeichnen Farbe. Also die Zeile ist eigentlich schwarz gezeichnet, und dein hintergrund ist auch schwarz. Als Ergebnis Sie kann nichts sehen.drawingImage
. Als Ergebnis der Zeile ist tatsächlich Rückschlüsse auf die offscreen-Bild, nicht auf dem Bildschirm.mouseDragged
Methode, die Sie aufrufen von repaint nach jeder ziehen. Als ein Ergebnis ist eigentlich nichts lackiertHabe ich ausführen von code auf meinem Rechner und die notwendigen änderungen vorgenommen haben.Ich bin Entsendung nur die Methoden geändert, es kurz zu halten.
Hier ist die aktualisierte
mouseDragged
MethodeHier ist die aktualisierte
drawWhileDragging
MethodeGut, ich habe die Farbe auf orange. Was Sie tun müssen, ist, um die Farbe nach der
Choice
Menü.Können Sie implementieren eine ähnliche Analogie zum zeichnen auch für andere Formen.
Den Punkt, den Sie haben kommt darauf an, wie Sie "versuchen" zu führen Doppel-Pufferung. Dann lieber löschen der backing-Puffer wenn Sie ein update für die line-position, Sie einfach kontinuierlich malen, um es ein wenig wie eine Zeichnung auf einem schwarzen Brett....
Stattdessen müssen Sie zum löschen der Grafiken, Inhalte und erneut das updates - überraschend, das ist Teil der was
paint
eigentlich nicht, aber man kann nie rufen Siesuper.paint
Gibt es selten überschreiben müssen eine top-level-container, noch sollten Sie nur selten überschreiben müssen die
paint
Methode von einem top-level container. Abgesehen von allem anderen, es nicht double-buffered.Verwenden Sie stattdessen so etwas wie
JPanel
statt.Habe ich aktualisiert, die Ihrem Beispiel, ohne Farbe. Farbe sollte eigentlich erhalten werden, indem die Form und werden angewendet, wenn es gemalt ist.
drawWhileDragging
unddraw
Methoden sind die gleichen, ich bin mir nicht sicher, was für einen Unterschied Sie sind angenommen zu haben