Pessoal, fiz um programinha que faz alguns desenhos em um JPanel, pra isso sobrescrevi o paintComponent…
só que quando de alguma forma acontece um resize no container que ta o painel, os desenhos desaparecem, tentei sobrescrever o repaint para evitar isso, mas naum deu em nada, alguem tem alguma ideia?
obrigado
Amigo, você está perdendo seu desenho quando a tela é redesenhada porque você precisa armazenar os pontos em algum lugar. Vou dar um exemplinho que já dei em outro post; leia-o e entenda-o.
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.util.List;
import java.util.ArrayList;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.WindowConstants;
class MeuCanvas extends JPanel {
private int x1, x2, y1, y2;
private Color color;
// Lista dos pontos a serem desenhados
private List<Point> points = new ArrayList<Point>();
public void addNewPoint (int pX, int pY) {
points.add (new Point (pX, pY));
}
public void clearPoints() {
points.clear();
}
public void setColor (Color pColor) {
color = pColor;
}
/**
* @see javax.swing.JComponent#paintComponent(java.awt.Graphics)
*/
protected void paintComponent(Graphics pG) {
super.paintComponent(pG);
Graphics2D g2d = (Graphics2D) pG.create();
g2d.setPaint(color);
for (Point point : points) {
g2d.fillOval(point.x - 5, point.y - 5, 10, 10);
}
g2d.dispose();
}
}
/**
*/
public class TesteDesenho extends JFrame {
private static final long serialVersionUID = 1L;
private MeuCanvas meuCanvas = null;
/**
* This is the default constructor
*/
public TesteDesenho() {
super();
initialize();
}
/**
* This method initializes this
*
* @return void
*/
private void initialize() {
this.setSize(300, 200);
this.setContentPane(getMeuCanvas());
this.setTitle("Teste de Desenho");
}
/**
* This method initializes meuCanvas
*
* @return javax.swing.JPanel
*/
private JPanel getMeuCanvas() {
if (meuCanvas == null) {
meuCanvas = new MeuCanvas();
meuCanvas.addMouseMotionListener(new MouseMotionAdapter() {
/**
* @see java.awt.event.MouseMotionAdapter#mouseDragged(java.awt.event.MouseEvent)
*/
public void mouseDragged(MouseEvent pE) {
int x1 = pE.getX(); int y1 = pE.getY();
meuCanvas.addNewPoint (x1, y1);
meuCanvas.setColor (Color.RED);
repaint();
}
});
}
return meuCanvas;
}
public static void main(String[] args) {
TesteDesenho td = new TesteDesenho();
td.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
td.setVisible(true);
}
}
Você também pode, ao invés de armazenar objetos que representam os pontos, usar uma abordagem “MS Paint”.
Ao invés de desenhar os pontos no JPanel, desenhos num BufferedImage.
Depois, o método repaint somente precisa repintar a imagem.
Você pode desenhar num BufferedImage obtendo o objeto Graphics2D da imagem:
BufferedImage img = new BufferedImage(...); //Inicialize com as dimensões do painel e características desejadas
Graphics2D g2d = img.createGraphics();
//Faça o desenho aqui normalmente.
g2d.dispose();
Outra vantagem é que depois fica fácil usar a classe ImageIO.write para salvar a imagem em qualquer formato que o Java suporte.
Olá, primeiramente, agradeço a dica dos dois =D
thingol, em tinha pensado em fazer isso que vc falou, só que pensei que era uma maneira muito árdua, pois se eu tiver uns 800 pontos, posso ter algum problema na memória, mas vou testar…
vinigodoy, nunca tentei isso, sempre desenhei no jpanel, mas vou fazer que vc falou, pq futuramente precisarei exportar a imagem, acho que a sua idéia vai ser legal,
obrigado
A classe do ponto, se for tridimensional, usando um double e associada a uma cor RGBA de 32 bits terá:
8 + 8 + 8 + 16 = 40 bytes.
800 pontos x 24 bytes = 32.000 bytes ou 31.5kB.
Você não tem isso em memória?
Na verdade, a solução do Thingol será mais econômica na maior parte das vezes, exceto talvez quando você tiver uma imagem completamente cheia de pontos. Isso, é claro, se você trabalhar somente com a classe de pontos e não usar classes mais econômicas, como retas e outras formas geométricas.
Agora, certamente é uma solução um pouco mais trabalhosa.
A minha solução é adequada se você quer fazer algo parecido com o CorelDraw (que trabalha com figuras geométricas), ou se você quer fazer undo/redo (nesse caso, você pode sempre ir removendo pontos da lista). É interessante também se você precisar de figuras redimensionáveis (nesse caso você precisa fazer as conversões de coordenadas dos pontos que estão acumulados, ou então aprender a usar AffineTransform.)
A solução do ViniGodoy é legal se você quiser fazer algo com o MS Paint (que trabalha com pixels).
Se você precisar fazer undo/redo, é necessário então ter uma lista de BufferedImages para você poder voltar atrás caso necessário.
De qualquer maneira, se você precisar desenhar uma reta ponto por ponto (sempre o professor inventa que você precisa desenhar uma reta ou elipse usando o algoritmo de Bresenham, ou coisa parecida), use a solução do ViniGodoy.
Blz pessoal, obrigado novamente