Reputation: 2237
I want to draw 2 (or more ) lines on JPanel
when the mouse drags. When i use super.paintComponent(g)
in my code, I couldn't draw 2 lines on the panel, however when I don't use super.paintComponent(g);
, the result is ugly, like the pic below :
I understand why the lines behaved like that.
How could I draw the lines on the panel when dragging the mouse?
BTW, the line drawn by g2d.draw(line2d)
sometimes it's not the smooth line (pic below)
My codes so far :
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.geom.Line2D;
import java.util.ArrayList;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.WindowConstants;
public class LineDrawing extends JPanel implements MouseMotionListener, MouseListener{
Point point1;
Point point2;
Line2D line2d;
public LineDrawing(){
super();
addMouseListener(this);
addMouseMotionListener(this);
}
@Override
public void paintComponent(Graphics g){
//super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
if(point1!=null && point2!=null){
g2d.setPaint(Color.RED);
g2d.setStroke(new BasicStroke(1.5f));
g2d.draw(line2d);
}
}
@Override
public void mouseDragged(MouseEvent e) {
point2 = e.getPoint();
line2d = new Line2D.Double(point1, point2);
repaint();
}
@Override
public void mouseMoved(MouseEvent e) {
}
@Override
public void mouseClicked(MouseEvent e) {
}
@Override
public void mousePressed(MouseEvent e) {
point1 = e.getPoint();
}
@Override
public void mouseReleased(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
public static void main(String a[]){
EventQueue.invokeLater(new Runnable(){
@Override
public void run() {
JFrame frame = new JFrame();
LineDrawing linedraw= new LineDrawing();
frame.add(linedraw);
frame.setSize(500,500);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setVisible(true);
}
});
}
}
Upvotes: 3
Views: 11478
Reputation: 168825
..draw 2 lines
That seems like the crux of the matter in this question.
Keep a collection of lines in an expandable list (e.g. ArrayList
) when clicking/dragging, add a new line to the list and call repaint()
. In paintComponent(Graphics)
, iterate the collection and draw each line.
BTW - I am guessing you have not minimized and restored your window while testing this. Your lines (beautiful or ugly) would disappear!
..they disappeared. What's the reason?
The methods paint()
and paintComponent()
are called whenever the GUI needs to redraw. They might be invoked after another window appears in front of the app., then it is brought back to the front. Another time is after being restored from minimized.
The options to retain the lines include:
BufferedImage
and put the image in (an ImageIcon
in) a JLabel
. This approach works well if the drawing area is of a fixed size & nothing is ever removed, and can accommodate ..millions of lines, arcs, semi-transparent areas, smaller images, text.. Using an image as a rendering surface, you would no longer need the ArrayList
, since all you do is add a new line to the image, and repaint the label to see the new line and all previous lines...the line is not the straight line.
That is because of the 'rendering hints' used when drawing the line. A screen made of aligned rows of pixels can only make vertical or horizontal lines perfectly. To give the 'illusion' of a straight & continuous line at any other angle, requires a technique known as dithering. Read the opening sections of Graphics2D
for more explanation and description of the RenderingHints
.
Upvotes: 5
Reputation: 1605
I don't know I get your question, but if you want to draw a continuous line. When dragging you have to update your last point possition.
@Override
public void mouseDragged(MouseEvent e) {
point2 = e.getPoint();
line2d = new Line2D.Double(point1, point2);
point1 = point2; // add this line
repaint();
}
Upvotes: 1