punto - ¿Cómo dibujar en JPanel?(Swing/gráficos Java)
metodos de la clase canvas en java (4)
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 BufferedImage 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 .
Estoy trabajando en un proyecto en el que estoy tratando de hacer un programa de pintura. Hasta ahora he usado Netbeans para crear una GUI y configurar el programa.
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 intento 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();
}// </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);
}
}
}
Captura de pantalla
Todo es un JFrame
y la sección blanca en el centro es jPanel2
que es lo que quiero dibujar.
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í:
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();
}// </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);
}
}
}
Captura de pantalla
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
.
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);
}
}
}