Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Draw a line in a JPanel with button click in Java

I want to draw a line in a JPanel. This is my GUI and I want a line in the JPanel in white.

enter image description here

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

like image 402
Ali Ben Messaoud Avatar asked Apr 26 '11 23:04

Ali Ben Messaoud


People also ask

Can you draw on JPanel?

Instead, in Swing, we usually draw on a JPanel. Turns out, you can draw on most Swing components, but are not advised to draw on top-level components like JFrame. The all-important technique of overriding paintComponent() (and, sometimes, repaint()): Like AWT, Swing does not maintain "bit-mapped memory".

How do you draw a line in a frame in Java?

Java Applet | Draw a line using drawLine() method x1 – It takes the first point's x coordinate. y1 – It takes first point's y coordinate. x2 – It takes second point's x coordinate. y2 – It takes second point's y coordinate.

Which method is used to draw a line between two points in Java?

The drawLine() method of the Graphics class is used to draw a line between two points.


3 Answers

It may be easier to draw lines using the following approach:

  1. click to mark the first endpoint
  2. drag to show the line in progress
  3. release to mark the second endpoint

This related example may offer some additional guidance.

Addendum

  1. The example below implements the outline above.
  2. I've update the example to show how to use a panel of buttons to affect the drawing.
  3. See also this related example that uses the Action interface with key bindings.
  4. 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();
            }
        });
    }
}
like image 179
trashgod Avatar answered Sep 19 '22 03:09

trashgod


Is this going to work like an etch-a-sketch? Then you need to track the current position of the point.

   Point current = new Point(0, 0); //for example.

Then when the user clicks the buttons you can simply increment or decrement x and y accordingly.

On left arrow:

   current.setX(current.getX() - INC);

where INC could be a variable that specifies the length of the distance to draw the line. Maybe 5? Always set a second point p1 to the previous location though.

It is always easier to create a class that extends Canvas or JPanel to draw on rather than draweing directly on the JFrame.

e.g.

public class Circuit extends JFrame {
  Point p1, current;

  JPanel drawPanel;

  //your other declarations

  public Circuit(){
         super();
         drawPanel = new DrawPanel();
         p1 = new Point(0, 0);
         current = new Point(0, 0);
         add(drawPanel, BorderLayout.CENTER);
         //your other code
  }

  class DrawingPanel extends JPanel{

        public void paintComponent(Graphics g){
             g.drawLine(p1.getX(), p1.getY(), current.getX(), current.getY());
        }
  }


   //the rest of your code.
}
like image 27
Vincent Ramdhanie Avatar answered Sep 18 '22 03:09

Vincent Ramdhanie


There is a simple answer for triggering graphics: e.g. The following code can be placed inside a click event and used for drawing a few simple objects on a jPanel. jPanel1 in this case was situated on one side of a tabbed jPanel7 and next to the triggering button. To do this in netbeans GUI, the code was placed inside the button action event. Once the usual errors appeared for not having the proper imports, right click on the code and click on "fix imports". Bingo, all is well :-) Warning: the setBackground command for the panel will override the graphics object. If you set the background color without using the graphics object, you will not see your objects!

Graphics g = jPanel1.getGraphics();  
g.setColor(Color.blue);
    g.drawLine( 0, 50,  20, 50);
    g.setColor(Color.white); 
    g.fillRect(40, 50,  20, 20); 
    g.setColor(Color.blue); 
    g.drawRect(40, 50,  20, 20); 
    g.drawOval(80, 50,  20, 20); 
    g.setColor(Color.green); 
    g.fillOval(80, 50,  18, 18);   

This restores your faith in true love :-) The difficulty here is that any change or repaint will erase your effort. This approach is specifically discouraged by the Java founders. But in the current rendition of Netbeans Swing, where extending the jPanel is made difficult by locking code changes, this approach could be your only short term solution. A simple persistent graphic extension for the jPanel would be a most welcome addition to the current Netbeans Swing environment, a graphics panel. This would allow you to drag and drop the graphics panel and then get on with the event driven use of that panel. 40 other IDE's already have this, it seems Java has been slow to add this feature.

like image 22
Edward Kimble Avatar answered Sep 18 '22 03:09

Edward Kimble