O que devo fazer pra salvar os desenhos do drawLine e demais funções quando eu minimizar a tela do jframe, já que o desenho está sendo deletado.
Como está o seu código? Pois, se você está inicializando o JFrame usando o invokeLater e usando corretamente as funções de desenho, o próprio Java se encarrega de manter o estado do desenho. Geralmente, não precisa de nada a mais.
Exemplo:
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Janela2D extends JFrame{
public Janela2D(){
super("Desenho 2D");
setExtendedState(JFrame.MAXIMIZED_BOTH);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
getContentPane().add(new Painel());
}
public static void main(String[] args){
java.awt.EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
Janela2D janela = new Janela2D();
janela.setVisible(true);
}
});
}
}
class Painel extends JPanel{
@Override
protected void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.drawLine(10, 10, 300, 300);
}
}
Abraço.
O método create
cria uma cópia do Graphics
.
Você deveria desenhar no próprio Graphics
e não na cópia dele.
Faça assim:
protected void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g; // desenha no próprio Graphics recebido por parâmetro
g2.drawLine(10, 10, 300, 300);
// não chama o dispose
}
Boa observação. Editei meu post para refletir isso.
Só pra esclarecer, existe alguma diferença prática? A documentação não é muito clara a respeito.
Abraço.
Aqui o código do meu jFrame, enviei tudo, talvez tenha coisas desnecessárias.
public void paintLine(Graphics g, int x1, int y1, int x2, int y2) {
Graphics2D g2 = (Graphics2D) g;
g2.setColor(this.cor);
g2.setStroke(new BasicStroke(this.tamanho));
g2.drawLine(x1, y1, x2, y2);
}
public void paintPencil(Graphics g, int x1, int y1) {
Graphics2D g2 = (Graphics2D) g;
g2.setStroke(new BasicStroke(this.tamanho));
g2.setColor(this.cor);
g2.drawLine(x1, y1, x1, y1);
}
public void paintQuadrado(Graphics g, int x1, int y1, int x2, int y2) {
Graphics2D g2 = (Graphics2D) g;
g2.setStroke(new BasicStroke(this.tamanho));
this.l = x2 - x1;
this.h = y2 - y1;
if (this.l < 0) {
this.l *= -1;
x1 -= l;
}
if (this.h < 0) {
this.h *= -1;
y1 -= h;
}
g2.setColor(this.cor);
if(this.preencher == false){
g2.drawRect(x1, y1, this.l, this.h);
}else{
g2.fillRect(x1, y1, this.l, this.h);
}
}
public void paintClear(Graphics g, int x1, int y1, int x2, int y2){
this.l = x2 - x1;
this.h = y2 - y1;
g.clearRect(x1, y1, this.l, this.h);
}
public void paintCircle(Graphics g, int x1, int y1, int x2, int y2){
Graphics2D g2 = (Graphics2D) g;
g2.setStroke(new BasicStroke(this.tamanho));
this.l = x2 - x1;
this.h = y2 - y1;
if (this.l < 0) {
this.l *= -1;
x1 -= l;
}
if (this.h < 0) {
this.h *= -1;
y1 -= h;
}
g2.setColor(this.cor);
if(this.preencher == false){
g2.drawOval(x1, y1, this.l, this.h);
}else{
g2.fillOval(x1, y1, this.l, this.h);
}
}
private void formMousePressed(java.awt.event.MouseEvent evt) {
if (this.ferramenta.equals("Linha")) {
this.x1 = evt.getX();
this.y1 = evt.getY();
}
if (this.ferramenta.equals("Quadrado")) {
this.x1 = evt.getX();
this.y1 = evt.getY();
}
if(this.ferramenta.equals("Borracha")){
this.x1 = evt.getX();
this.y1 = evt.getY();
}
if(this.ferramenta.equals("Circulo")){
this.x1 = evt.getX();
this.y1 = evt.getY();
}
}
private void formMouseReleased(java.awt.event.MouseEvent evt) {
if (this.ferramenta.equals("Linha")) {
this.x2 = evt.getX();
this.y2 = evt.getY();
Graphics g = getGraphics();
paintLine(g, x1, y1, x2, y2);
}
if (this.ferramenta.equals("Quadrado")) {
this.x2 = evt.getX();
this.y2 = evt.getY();
Graphics g = getGraphics();
paintQuadrado(g, x1, y1, x2, y2);
}
if (this.ferramenta.equals("Borracha")) {
this.x2 = evt.getX();
this.y2 = evt.getY();
Graphics g = getGraphics();
paintClear(g, x1, y1, x2, y2);
}
if (this.ferramenta.equals("Circulo")) {
this.x2 = evt.getX();
this.y2 = evt.getY();
Graphics g = getGraphics();
paintCircle(g, x1, y1, x2, y2);
}
}
private void formMouseClicked(java.awt.event.MouseEvent evt) {
}
private void formMouseMoved(java.awt.event.MouseEvent evt) {
if(this.ferramenta.equals("Lapis")) {
this.x2 = evt.getX();
this.y2 = evt.getY();
}
}
private void formMouseDragged(java.awt.event.MouseEvent evt) {
if(this.ferramenta.equals("Lapis")){
this.x1 = evt.getX();
this.y1 = evt.getY();
Graphics g = getGraphics();
paintPencil(g, x1, y1);
Graphics2D g2 = (Graphics2D) g;
g2.setStroke(new BasicStroke(this.tamanho));
g2.drawLine(x1, y1, x2, y2);
this.x2 = this.x1;
this.y2 = this.y1;
}
}
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new NOW().setVisible(true);
}
});
}
Seu código está desenhando os polígonos apenas 1 vez, quando o mouse é solto (mouseReleased). Isso faz com que cada chamada ao método paint do JFrame apague tudo, e é isso que acontece quando a janela é alterada (minimizada, redimensionada, movida, etc). Essa estrutura não vai servir para o que você quer (estou supondo que é um programa de desenho para formas geométricas ou similar).
Não dá pra te passar o código todo, mas o que você precisa é armazenar as formas a serem desenhadas e redesenhar todas elas no repaint. Você pode armazenar as coordenadas e tipos dos objetos a serem desenhados, ou mesmo instâncias de classes que derivem de Shape, como Rectangle2D. Eu acredito que seja possível salvar o desenho completo . Pode também criar classes para as suas formas, se quiser abstrair outras operações.
A grosso modo, seria algo assim:
public class ClasseDoJFrame extends JFrame{
private Painel painel;
public Janela2D(){
super("Desenho 2D");
setExtendedState(JFrame.MAXIMIZED_BOTH);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
painel = new Painel();
getContentPane().add(painel);
}
private void formMouseReleased(java.awt.event.MouseEvent evt) {
this.x2 = evt.getX();
this.y2 = evt.getY();
this.painel.addRectangle(x1, y1, x2, y2);
}
}
class Painel extends JPanel{
private List<Shape> objetos = new LinkedList<Shape>();
@Override
protected void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
for(Shape s : objetos){
g2.draw(s);
}
}
public void addRectangle(int x1, int y1, int x2, int y2){
this.objetos.add(new Rectangle2D.Float(x1, y1, x2, y2));
}
}
Obs: não testei o código. Podem ser necessários ajustes.
Com base nisso, você pode criar os outros métodos para as demais formas. Pode inclusive criar alguma classe abstrata para Ferramenta e estender as ferramentas a partir dela. Assim, tendo apenas 1 ferramenta ativa a cada momento, não precisa desse monte de ifs no mouseReleased.
Abraço.