¿Cómo dibujar en JPanel? (Swing / gráficos Java)

Estoy trabajando en un proyecto en el que estoy tratando de hacer un progtwig de pintura. Hasta ahora he usado Netbeans para crear una GUI y configurar el progtwig.

A partir de ahora puedo llamar a todos los coordinados necesarios para dibujar dentro de él, pero estoy muy confundido con cómo pintar realmente dentro de él.

Hacia el final de mi código tengo un bash fallido de dibujar dentro del panel.

¿Alguien puede explicar / mostrar cómo usar gráficos en un ejemplo como este?

Todos los ejemplos que he encontrado forman una clase y la extiendo con JPanel pero no sé si puedo hacerlo ya que se generó en netbeans.

Necesito dibujar dentro de un JPanel , dentro de mi JFrame . No sé dónde poner la clase de gráficos.

Clase JavaPaintUI

 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(); }//  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); } } } 

Captura de pantalla

Todo es un JFrame y la sección blanca en el centro es jPanel2 que es lo que quiero dibujar. captura de pantalla de algún código que no es esto

Tenga en cuenta los comentarios adicionales.

 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(); }//  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); } } } 

Captura de pantalla

enter image description here

Otros ejemplos: más adaptados a múltiples líneas y múltiples segmentos de línea

HFOE puso un buen enlace como el primer comentario sobre este hilo. Camickr también tiene una descripción de la pintura activa frente al dibujo de una BufferedImage en el artículo Acercamientos de Pintura Personalizados .

Ver también este enfoque usando pintura en una BufferedImage .

Al trabajar con interfaces gráficas de usuario, debe recordar que el dibujo en un panel se realiza en la cola de eventos Java AWT / Swing . No puede usar el objeto Graphics fuera de paint() / paintComponent() / etc. métodos.

Sin embargo, puede usar una técnica llamada ” Frame buffering “. Básicamente, debe tener una imagen de Buffered y dibujar directamente sobre ella (consulte su método createGraphics() , ese contexto de gráficos que puede conservar y reutilizar para múltiples operaciones en una misma instancia de BufferedImage , sin necesidad de volver a crearlo todo el tiempo, solo al crear una nueva instancia). Luego, en el JPanel paintComponent() tu JPanel , simplemente necesitas dibujar la instancia de BufferedImage en el JPanel . Usando esta técnica, puede realizar operaciones de zoom, traducción y rotación con bastante facilidad mediante transformaciones afines .

Aquí hay un ejemplo simple. Supongo que será fácil de entender:

 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); } } 

}

Y la salida se ve así:

Salida

Variación del código por Bijaya Bidari que es aceptado por Java 8 sin advertencias con respecto a las llamadas al método anulables en constructor:

 public class Graph extends JFrame { JPanel jp; public Graph() { super("Simple Drawing"); super.setSize(300, 300); super.setDefaultCloseOperation(EXIT_ON_CLOSE); jp = new GPanel(); super.add(jp); } public static void main(String[] args) { Graph g1 = new Graph(); g1.setVisible(true); } class GPanel extends JPanel { public GPanel() { super.setPreferredSize(new Dimension(300, 300)); } @Override public void paintComponent(Graphics g) { super.paintComponent(g); //rectangle originated at 10,10 and end at 240,240 g.drawRect(10, 10, 240, 240); //filled Rectangle with rounded corners. g.fillRoundRect(50, 50, 100, 100, 80, 80); } } }