我正在开发一个绘制不同形状的绘图小程序。我想在拖动鼠标的同时画线。问题是当线条出现时,它们如下图所示。
我有一个使用一个点(起点)构造的类线
它有一个名为 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) {
}
}
最佳答案
我最近写了一个类似类型的应用程序。这是屏幕截图。如您所见,它还没有完全开发。
现在,我也遇到了和你现在面临的类似问题。你要做的是。
- 双缓冲所有绘画操作
- 不要通过调用 repaint 来清除屏幕。
Repaint
实际上首先用背景色填充屏幕 & 这就是您看到的闪烁。
您可以在 Image
中复制当前屏幕 Canvas 。 Image
将在每次绘图操作后更新。因此,不是通过调用 repaint
来清除屏幕,而是在 Canvas 上绘制 Image
。这就像双缓冲。
在您的代码中,每次拖动鼠标时都会调用 repaint
。这就是闪烁的原因。
更新
我在您新更新的代码中发现的三个主要问题
- 在
drawWhileDragging
方法中,您没有更改线条图形上下文绘制颜色。所以这条线实际上是用黑色画的,你的背景也是黑色的。因此,您什么也看不到。 - 在相同的方法中,您将传递
drawingImage
的图形上下文(即引用)。因此,这条线实际上是在屏幕外的图像上绘制的,而不是在屏幕上。 - 在
mouseDragged
方法中,您在每次拖动后调用重绘。结果实际上什么都没有画
我已经在我的机器上运行了您的代码并进行了必要的更改。为了简短起见,我只发布更改后的方法。
这是更新后的 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
菜单设置颜色。
您也可以对绘制其他形状实现类似的类比。
关于java - 鼠标拖动时画线问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14078882/