I need a JPanel
, which draws lines following the mouse pointer while it is dragged, and when released it needs to stop drawing.
It turns out that whenever you draw two or more rows in a row, they connect to the previous rows, this should not happen.
How do you manage to drag lines without them binding themselves, similar to Microsoft Paint software?
Here's my code:
package test;
import java.awt.BorderLayout;
import java.awt.Cursor;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.util.ArrayList;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
//Essa classe tem o objetivo de imitar o recurso de desenhar linhas do softwere paint, da Microsoft.
public class DrawingSketch extends JFrame {
private static final long serialVersionUID = 5661286812709693531L;
private JPanel contentPane;
private JPanel draft;
private int x;
private int y;
private ArrayList<Integer> cX = new ArrayList<>();
private ArrayList<Integer> cY = new ArrayList<>();
private Integer xa;
private Integer ya;
protected int mX;
protected int mY;
public int i;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
DrawingSketch frame = new DrawingSketch();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public DrawingSketch() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 900, 700);
setLocationRelativeTo(null);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
contentPane.setLayout(new BorderLayout(0, 0));
setContentPane(contentPane);
draft = new Draft();
draft.addMouseMotionListener(new MouseMotionAdapter() {
@Override
public void mouseDragged(MouseEvent e) {
setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));
//As coordenadas x e y estão sendo armazenadas nas coleções cX e CY respectivamente.
cX.add(e.getX());
cY.add(e.getY());
draft.repaint();
}
});
draft.addMouseListener(new MouseAdapter() {
@Override
public void mouseReleased(MouseEvent e) {
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
}
});
contentPane.add(draft, BorderLayout.CENTER);
draft.setLayout(null);
}
public class Draft extends JPanel {
/**
*
*/
private static final long serialVersionUID = 4886600019364448097L;
public Draft() {
}
@Override
protected void paintComponent(Graphics g) {
// TODO Auto-generated method stub
super.paintComponent(g);
for (i = 1; i < largerBeetweenXeY(cX.size(), cY.size()); i++) {
// x é o valor final de x.
x = cX.get(i);
//y é o valor final de y.
y = cY.get(i);
// xa é o valor inicial de x.
xa = cX.get(i - 1);
// ya é o valor inicial de y.
ya = cY.get(i - 1);
// Observação, se for usada a formula: xa = cX.get(i) e ya = cY.get(i), sem o i -1, o que é obtido e uma sequência de pontos
// desconexos, ou seja, com espaço vazio entre eles. As formulas xa = cX.get(i - 1) e ya = cY.get(i - 1), garantem que a linha
// fique perfeita, no entanto, com o traçado de duas ou mais linhas, as linhas se ligam, o que não deveria acontecer.
Graphics2D g1 = (Graphics2D)g;
RenderingHints rh = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g1.setRenderingHints(rh);
g1.drawLine(xa, ya, x, y);
}
}
}
/**
* @param int size valor de x.
* @param int size2 valor de y.
* Verifica o limite da iteração em paintComponent.
*/
public int largerBeetweenXeY(int size, int size2) {
if (size > size2) {
return size;
} else {
return size2;
}
}
}