Draw a line in a JPanel with button click in Java
graphics, java, jpanel, line, swing
Solution
It may be easier to draw lines using the following approach:
- click to mark the first endpoint
- drag to show the line in progress
- release to mark the second endpoint
This related example may offer some additional guidance.
Addendum
- The example below implements the outline above.
- I've update the example to show how to use a panel of buttons to affect the drawing.
- See also this related example that uses the `Action` interface with key bindings.
- I've updated this example to use Key Bindings.
LinePanel.java
import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
/**
* @see https://stackoverflow.com/questions/6991648
* @see https://stackoverflow.com/questions/6887296
* @see https://stackoverflow.com/questions/5797965
*/
public class LinePanel extends JPanel {
private MouseHandler mouseHandler = new MouseHandler();
private Point p1 = new Point(100, 100);
private Point p2 = new Point(540, 380);
private boolean drawing;
public LinePanel() {
this.setPreferredSize(new Dimension(640, 480));
this.addMouseListener(mouseHandler);
this.addMouseMotionListener(mouseHandler);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.blue);
g2d.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setStroke(new BasicStroke(8,
BasicStroke.CAP_ROUND, BasicStroke.JOIN_BEVEL));
g.drawLine(p1.x, p1.y, p2.x, p2.y);
}
private class MouseHandler extends MouseAdapter {
@Override
public void mousePressed(MouseEvent e) {
drawing = true;
p1 = e.getPoint();
p2 = p1;
repaint();
}
@Override
public void mouseReleased(MouseEvent e) {
drawing = false;
p2 = e.getPoint();
repaint();
}
@Override
public void mouseDragged(MouseEvent e) {
if (drawing) {
p2 = e.getPoint();
repaint();
}
}
}
private class ControlPanel extends JPanel {
private static final int DELTA = 10;
public ControlPanel() {
this.add(new MoveButton("\u2190", KeyEvent.VK_LEFT, -DELTA, 0));
this.add(new MoveButton("\u2191", KeyEvent.VK_UP, 0, -DELTA));
this.add(new MoveButton("\u2192", KeyEvent.VK_RIGHT, DELTA, 0));
this.add(new MoveButton("\u2193", KeyEvent.VK_DOWN, 0, DELTA));
}
private class MoveButton extends JButton {
KeyStroke k;
int dx, dy;
public MoveButton(String name, int code,
final int dx, final int dy) {
super(name);
this.k = KeyStroke.getKeyStroke(code, 0);
this.dx = dx;
this.dy = dy;
this.setAction(new AbstractAction(this.getText()) {
@Override
public void actionPerformed(ActionEvent e) {
LinePanel.this.p1.translate(dx, dy);
LinePanel.this.p2.translate(dx, dy);
LinePanel.this.repaint();
}
});
ControlPanel.this.getInputMap(WHEN_IN_FOCUSED_WINDOW)
.put(k, k.toString());
ControlPanel.this.getActionMap()
.put(k.toString(), new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
MoveButton.this.doClick();
}
});
}
}
}
private void display() {
JFrame f = new JFrame("LinePanel");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(this);
f.add(new ControlPanel(), BorderLayout.SOUTH);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
new LinePanel().display();
}
});
}
}
Problem
I want to draw a line in a JPanel. This is my GUI and I want a line in the JPanel in white. I find many examples but the problem is the how to use it. In many exmples, always they draw in a JFrame that extends from a JPanel. I want to add the Panel to the Frame and add some buttons to draw lines in many directions and use the X button in center to clean the JPanel. This is the code of the interface: ``` import java.awt.BorderLayout; import java.awt.EventQueue; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.border.EmptyBorder; import java.awt.Color; import javax.swing.JScrollPane; import javax.swing.JLabel; import javax.swing.ImageIcon; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; public class circuit extends JFrame { private JPanel contentPane; /** * Launch the application. */ public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { public void run() { try { circuit frame = new circuit(); frame.setVisible(true); } catch (Exception e) { e.printStackTrace(); } } }); } /** * Create the frame. */ public circuit() { setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setBounds(100, 100, 559, 332); contentPane = new JPanel(); contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); setContentPane(contentPane); contentPane.setLayout(null); JScrollPane scrollPane = new JScrollPane(); scrollPane.setBounds(10, 21, 359, 255); contentPane.add(scrollPane); JPanel panel = new JPanel(); scrollPane.setViewportView(panel); panel.setBackground(Color.WHITE); JLabel label = new JLabel("New label"); label.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent arg0) { ///////////// } }); label.setIcon(new ImageIcon("C:\\Users\\achermen\\Desktop\\up.png")); label.setBounds(447, 66, 46, 48); contentPane.add(label); JLabel label_1 = new JLabel("New label"); label_1.setIcon(new ImageIcon("C:\\Users\\achermen\\Desktop\\down.png")); label_1.setBounds(447, 159, 46, 48); contentPane.add(label_1); JLabel label_2 = new JLabel("New label"); label_2.setIcon(new ImageIcon("C:\\Users\\achermen\\Desktop\\right.png")); label_2.setBounds(495, 112, 46, 48); contentPane.add(label_2); JLabel label_3 = new JLabel("New label"); label_3.setIcon(new ImageIcon("C:\\Users\\achermen\\Desktop\\left.png")); label_3.setBounds(398, 112, 46, 48); contentPane.add(label_3); JLabel label_4 = new JLabel("New label"); label_4.setIcon(new ImageIcon("C:\\Users\\achermen\\Desktop\\1303860240_list-remove.png")); label_4.setBounds(447, 112, 46, 48); contentPane.add(label_4); } } ``` This is the code to draw a line ``` public void paint(Graphics graphics) { graphics.drawLine(10, 20, 300, 310); } ``` So how to use this lines .... Thanks in advance. Best regards, Ali