How to draw in JPanel? (Swing/graphics Java)

231,425

Solution 1

Note the extra comments.

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;

class JavaPaintUI extends JFrame {

    private int tool = 1;
    int currentX, currentY, oldX, oldY;

    public JavaPaintUI() {
        initComponents();
    }

    private void initComponents() {
        // we want a custom Panel2, not a generic JPanel!
        jPanel2 = new Panel2();

        jPanel2.setBackground(new java.awt.Color(255, 255, 255));
        jPanel2.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED));
        jPanel2.addMouseListener(new MouseAdapter() {
            public void mousePressed(MouseEvent evt) {
                jPanel2MousePressed(evt);
            }
            public void mouseReleased(MouseEvent evt) {
                jPanel2MouseReleased(evt);
            }
        });
        jPanel2.addMouseMotionListener(new MouseMotionAdapter() {
            public void mouseDragged(MouseEvent evt) {
                jPanel2MouseDragged(evt);
            }
        });

        // add the component to the frame to see it!
        this.setContentPane(jPanel2);
        // be nice to testers..
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        pack();
    }// </editor-fold>

    private void jPanel2MouseDragged(MouseEvent evt) {
        if (tool == 1) {
            currentX = evt.getX();
            currentY = evt.getY();
            oldX = currentX;
            oldY = currentY;
            System.out.println(currentX + " " + currentY);
            System.out.println("PEN!!!!");
        }
    }

    private void jPanel2MousePressed(MouseEvent evt) {
        oldX = evt.getX();
        oldY = evt.getY();
        System.out.println(oldX + " " + oldY);
    }


    //mouse released//
    private void jPanel2MouseReleased(MouseEvent evt) {
        if (tool == 2) {
            currentX = evt.getX();
            currentY = evt.getY();
            System.out.println("line!!!! from" + oldX + "to" + currentX);
        }
    }

    //set ui visible//
    public static void main(String args[]) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                new JavaPaintUI().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify
    private JPanel jPanel2;
    // End of variables declaration

    // This class name is very confusing, since it is also used as the
    // name of an attribute!
    //class jPanel2 extends JPanel {
    class Panel2 extends JPanel {

        Panel2() {
            // set a preferred size for the custom panel.
            setPreferredSize(new Dimension(420,420));
        }

        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);

            g.drawString("BLAH", 20, 20);
            g.drawRect(200, 200, 200, 200);
        }
    }
}

Screen Shot

enter image description here

Other examples - more tailored to multiple lines & multiple line segments

HFOE put a good link as the first comment on this thread. Camickr also has a description of active painting vs. drawing to a BufferedImage in the Custom Painting Approaches article.

See also this approach using painting in a BufferedImage.

Solution 2

When working with graphical user interfaces, you need to remember that drawing on a pane is done in the Java AWT/Swing event queue. You can't just use the Graphics object outside the paint()/paintComponent()/etc. methods.

However, you can use a technique called "Frame buffering". Basically, you need to have a BufferedImage and draw directly on it (see it's createGraphics() method; that graphics context you can keep and reuse for multiple operations on a same BufferedImage instance, no need to recreate it all the time, only when creating a new instance). Then, in your JPanel's paintComponent(), you simply need to draw the BufferedImage instance unto the JPanel. Using this technique, you can perform zoom, translation and rotation operations quite easily through affine transformations.

Solution 3

Here is a simple example. I suppose it will be easy to understand:

import java.awt.*;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Graph extends JFrame {
JFrame f = new JFrame();
JPanel jp;


public Graph() {
    f.setTitle("Simple Drawing");
    f.setSize(300, 300);
    f.setDefaultCloseOperation(EXIT_ON_CLOSE);

    jp = new GPanel();
    f.add(jp);
    f.setVisible(true);
}

public static void main(String[] args) {
    Graph g1 = new Graph();
    g1.setVisible(true);
}

class GPanel extends JPanel {
    public GPanel() {
        f.setPreferredSize(new Dimension(300, 300));
    }

    @Override
    public void paintComponent(Graphics g) {
        //rectangle originates at 10,10 and ends at 240,240
        g.drawRect(10, 10, 240, 240);
        //filled Rectangle with rounded corners.    
        g.fillRoundRect(50, 50, 100, 100, 80, 80);
    }
}

}

And the output looks like this:

Output

Share:
231,425
Nick R
Author by

Nick R

Updated on December 18, 2020

Comments

  • Nick R
    Nick R over 3 years

    I'm working on a project in which I am trying to make a paint program. So far I've used Netbeans to create a GUI and set up the program.

    As of right now I am able to call all the coordinated necessary to draw inside it but I am very confused with how to actually paint inside it.

    Towards the end of my code I have a failed attempt at drawing inside the panel.

    Can anyone explain/show how to use graphics in a example like this?

    All examples I have found make a class and extend it with JPanel but I don't know if I can do this since it was generated in netbeans.

    I need to draw inside a JPanel, inside my JFrame. I don't know where to put the graphics class.

    JavaPaintUI Class

    package javapaint;
    
    import java.awt.*;
    import javax.swing.*;
    
    public class JavaPaintUI extends javax.swing.JFrame {
    
    public JavaPaintUI() {
        initComponents();
    }
    
    
    private void initComponents() {
    
    
        jPanel2 = new javax.swing.JPanel();
    
        jPanel2.setBackground(new java.awt.Color(255, 255, 255));
        jPanel2.setBorder(javax.swing.BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.RAISED));
        jPanel2.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mousePressed(java.awt.event.MouseEvent evt) {
                jPanel2MousePressed(evt);
            }
            public void mouseReleased(java.awt.event.MouseEvent evt) {
                jPanel2MouseReleased(evt);
            }
        });
        jPanel2.addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
            public void mouseDragged(java.awt.event.MouseEvent evt) {
                jPanel2MouseDragged(evt);
            }
        });
        pack();
    }// </editor-fold>                        
    
    int currentX, currentY, oldX, oldY;
    
    private void jPanel2MouseDragged(java.awt.event.MouseEvent evt) {                                     
        if (tool == 1) {
            currentX = evt.getX();
            currentY = evt.getY();
            oldX = currentX;
            oldY = currentY;
            System.out.println(currentX + " " + currentY);
            System.out.println("PEN!!!!");
        }
    
    }                                    
    
    private void jPanel2MousePressed(java.awt.event.MouseEvent evt) {                                     
        oldX = evt.getX();
        oldY = evt.getY();
        System.out.println(oldX + " " + oldY);
    }                                    
    
    
    //mouse released//
    private void jPanel2MouseReleased(java.awt.event.MouseEvent evt) {                                      
        if (tool == 2) {
            currentX = evt.getX();
            currentY = evt.getY();
            System.out.println("line!!!! from" + oldX + "to" + currentX);
        }
    }                                     
    
    //set ui visible//
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
    
            public void run() {
                new JavaPaintUI().setVisible(true);
            }
        });
    }
    
    // Variables declaration - do not modify                     
    private javax.swing.JPanel jPanel2;
    // End of variables declaration                   
    
    class jPanel2 extends JPanel {
    
        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
    
            g.drawString("BLAH", 20, 20);
            g.drawRect(200, 200, 200, 200);
        }
    }
    }
    

    Screen shot

    The whole thing is a JFrame and the white section in the center is jPanel2 which is what I want to draw on. screen shot of some code that is not this