Domanda

I am newbie to Graphics Programming. I want to draw multiple shapes like Line, Rectangle and Oval by Dragging the mouse. I tried to accomplish this task but failed.

My Output Looks like this. enter image description here

Here is My Code :

public class JavaDraw extends JPanel implements ActionListener,
    MouseMotionListener, MouseListener {

private JButton btnLine, btnRect, btnEclipse, btnPointer;
private DrawShape drawShape;
private Vector<Line2D.Double> vecLine;
private Vector<Rectangle2D.Double> vecRectangle;
private Vector<Ellipse2D.Double> vecEllipse;
private int left, right, top, bottom;
private Point startPoint, endPoint;

public JavaDraw(int width, int height) {
    this();
    setSize(width, height);
    setBackground(Color.orange);
}

public JavaDraw() {

    setLayout(new FlowLayout(FlowLayout.CENTER));

    createControl();
    addControl();
    addListners();
}

private void createControl() {
    btnEclipse = new JButton("Eclipse");
    btnLine = new JButton("Line");
    btnRect = new JButton("Rectangle");
    btnPointer = new JButton("Pointer");

    vecEllipse = new Vector<>();
    vecLine = new Vector<>();
    vecRectangle = new Vector<>();

    startPoint = new Point();
    endPoint = new Point();
}

private void addControl() {

    add(btnLine);
    add(btnRect);
    add(btnEclipse);
    add(btnPointer);
}

private void addListners() {
    addActionListenerToControl();
    addMouseListenerToControl();
    addMouseMotionListenerToControl();
}

private void addActionListenerToControl() {
    btnEclipse.addActionListener(this);
    btnLine.addActionListener(this);
    btnPointer.addActionListener(this);
    btnRect.addActionListener(this);
}

private void addMouseListenerToControl() {
    addMouseListener(this);
}

private void addMouseMotionListenerToControl() {
    addMouseMotionListener(this);
}

private void resizeShape(int x, int y) {
    endPoint.x = x;
    endPoint.y = y;
    updateBounds(startPoint, endPoint);
}

private void drawShape(Graphics g, boolean xor, DrawShape dm) {

    if (drawShape == DrawShape.DRAW_RECT)
        g.drawRect(left, top, Math.abs(left - right),
                Math.abs(top - bottom));
    else if (drawShape == DrawShape.DRAW_ELLIPSE)
        g.drawOval(left, top, Math.abs(left - right),
                Math.abs(top - bottom));
    else if (drawShape == DrawShape.DRAW_LINE)
        g.drawLine(startPoint.x, startPoint.y, endPoint.x, endPoint.y);
}

void updateBounds(Point pt1, Point pt2) {
    left = (pt1.x < pt2.x) ? pt1.x : pt2.x;
    right = (pt1.x > pt2.x) ? pt1.x : pt2.x;
    top = (pt1.y < pt2.y) ? pt1.y : pt2.y;
    bottom = (pt1.y > pt2.y) ? pt1.y : pt2.y;
}

@Override
public void actionPerformed(ActionEvent e) {
    Graphics g = getGraphics();
    g.setColor(Color.black);
    g.setXORMode(getBackground());

    if (e.getSource() == btnEclipse) {
        drawShape = DrawShape.DRAW_ELLIPSE;
    } else if (e.getSource() == btnLine) {
        drawShape = DrawShape.DRAW_LINE;
    } else if (e.getSource() == btnRect) {
        drawShape = DrawShape.DRAW_RECT;
    } 
    g.setPaintMode();
}

@Override
public void mouseDragged(MouseEvent e) {
    Graphics g = getGraphics();
    g.setColor(Color.black);
    g.setXORMode(getBackground());

    resizeShape(e.getX(), e.getY());
    drawShape(g, true, drawShape);

}

@Override
public void mouseMoved(MouseEvent e) {
}

@Override
public void mouseClicked(MouseEvent e) {
}

@Override
public void mouseEntered(MouseEvent e) {
}

@Override
public void mouseExited(MouseEvent e) {
}

@Override
public void mousePressed(MouseEvent e) {
    startPoint = e.getPoint();
}

@Override
public void mouseReleased(MouseEvent e) {
}

}

enum DrawShape {
    DRAW_LINE, DRAW_RECT, DRAW_ELLIPSE
}

But if i Call repaint() method then previously drawn shapes get disappears.

Pls help me with it.

Thanks in Advance.

È stato utile?

Soluzione

Don't use getGrapchic(). You need to learn the basics of custom painting. See Performing Custom Painting. Basically what you want to do is override paintComponent and do your painting there.

@Override
protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    Graphics2D g2 = (Graphics2D)g;
    // draw here.
}

When ever you repaint() the panel, the paintComponent will be implicitly called. So you could do something like

@Override
protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    Graphics2D g2 = (Graphics2D)g;
    for (Rectangle2D rect: rectangles) {
        g2.fill(rect);
    }
}

You could then, for instance, add a new Rectangle2D object to the List<Rectangle2D> rectagles, and there would be another rectangle drawn on the canvas.

Also you may want to look at this answer, which shows how you can create the shape by dragging the mouse

enter image description here

The code in the example only uses one rectangle, but you could easily modify it to draw a List of rectangles. And every time the mouse is pressed, it will add a new rectangle to the list, while still allowing you to drag the mouse to size the current rectangle obtained from the mouse press. Examine the link. Hope it helps.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top