Java2D - JTabbedPane e JPanel nao mantem o desenho?

Salve galera.

Seguinte, to com um duvida aqui q ainda naum encontrei como resolver. Eu tenho um JTabbedPane q possui duas abas, o que acontece eh q consigo desenhar em todas elas, porem quando eu troco de abas o desenho some, nao sei pq naum mantem, tentei colocar repaint(false); porem naum tive resultado ainda.
O mesmo acontece se eu minimizo e maximizo.

Pq isso acontece ??? Como fazer para resolver isso, e o desenho se mantenha quando trocar de aba no JTabbedPane ou minimizar e maximizar ???

obrigado.

O Java2D não tem nenhuma obrigação de manter para você o desenho. Por isso o evento chama-se “repaint” (repintar).

Existe duas maneiras de você dar a sensação de que o desenho se mantém:
a) Redesenhar tudo no repaint (para isso vc terá que ter uma representação OO do que foi pintado). Isso permite também que você dê recursos para o usuário alterar o que foi desenhado, como o Corel faz;
b) Desenhar tudo numa BufferedImage, e no repaint apenas desenhar essa BufferedImage no painel. A vantagem é que é mais rápido de implementar e mais fácil. A desvantagem é que isso vai ocupar bastante memória, mesmo que seu usuário não faça desenho nenhum.

Sobre obrigação, realmente naum falei disso, pois sei q ninguem muito menos um componente tem obrigação de fazer alguma coisa sem q seja programado. O que estava procurando era uma maneira de manter o desenho, depois de minimizado ou trocando de abas no jtabbed.
Mas vlw pela resposta, eu ja tinha visto algumas coisas de BufferedImage e tbm vi sobre o uso de memória.

vlw ae

Se você usar a Graphics2D ao invés da Graphics, existe uma versão do método draw que recebe objetos, da classe Ellipsis, Rectangle, Line, Point…
A vantagem de trabalhar com eles é justamente o fato de que você pode armazenar esses objetos numa lista e repinta-los depois.

:wink:

Vini, eu to usando a Graphics2D…

veja.

//jpanel paneldesenho onde sera feito os desenhos
public class PanelDesenho extends JPanel{
    public void paintComponent(Graphics g){
          Graphics2D g2d = (Graphics2D)g;
    }
}

PanelDesenho pd = new PanelDesenho();
Graphics2D g2d = (Graphics2D)pd.getGraphics();
g2d.drawLine(20,20, 100, 100);

vlw, obrigado.

Sim, mas vc não está usando a versão do método draw que comentei. Nele vc faria assim para criar uma linha:

Line2D line = new Line2D.Double(20, 20, 100, 100); g2d.draw(line);

Como falei, a vantagem de criar objetos é que vc poderia guarda-los numa lista, sempre que fossem criados. E aí só fazer:

for (Shape shape : createdShapes) { g2d.draw(shape); }

Acho que o Fernando não entendeu como é que se desenha alguma coisa em Java 2D. Normalmente você não pega diretamente o contexto de um outro componente e desenha nele, como você fez - isso é uma coisa muito frágil porque qualquer redimensionamento ou sobreposição que ocorrer irá destruir uma parte do seu desenho. Em vez disso, há duas coisas que se podem fazer:

a) O modo de “desenhar uma lista de Shapes”, que requer que você tenha uma lista (ou outra estrutura de dados mais complexa) dos objetos a serem desenhados, funciona assim: você cria uma classe derivada de JPanel cujo método paintComponent pega essa lista e desenha, Shape por Shape, os objetos a serem desenhados. Isso funciona bem se você quer ter algo que é basicamente orientado a figuras (não é um “Microsoft Paint” da vida, e sim um mini-Corel Draw). e onde seja fácil redimensionar, girar etc. as figuras. Para redesenhar a sua tela, você chama o método repaint da sua classe derivada de JPanel - o repaint irá chamar o paintComponent eventualmente.

b) O modo de “desenhar sobre uma BufferedImage” requer que você crie uma classe derivada de JPanel cujo método paintComponent pega um BufferedImage (que você deve ter criado antes) e a desenha na tela. Então, quando você quer desenhar algo nesse BufferedImage, você simplesmente pega o objeto Graphics2D associado a essa BufferedImage e desenha o que você quer; para transferir o BufferedImage para a tela, você chama o método repaint da sua classe derivada de JPanel - o repaint irá chamar o paintComponent eventualmente. Isso é mais adequado para você fazer um “Paint” mas tem um probleminha, como você deve ter descoberto: não é fácil você redimensionar, girar etc. as figuras porque você não está trabalhando com figuras, e sim com pontos :frowning:

Para mais detalhes é melhor ver os artigos do ViniGodoy no PontoV.
http://pontov.com.br/site/

Entaum, a maneira como eu estava tentando fazer eh a seguinte.

//aqui o JPanel onde faco os desenhos.
public class JPanelDesktopWork extends JPanel implements MouseListener, MouseMotionListener{
    public JPanelDesktopWork(){
      this.setBackground(Color.BLACK);
    }

    public void paintComponent(Graphics g){
       Graphics2D g2d = (Graphics2D)g;
    }
}


public class DrawLines { //classe encarregada de desenhar apenas linhas, mas tera tbm as classes encarregadas de desenhar Rectangles, Ellipses etc..
    private JPanelDesktopWork jdw;
    
    public DrawLines(JPanelDesktopWork jdw){
        this.jdw = jdw;
    }

    public void drawLine(){
        Graphics2D g2d = (Graphics2D)this.jdw.getGraphics();
        Line2D line = new Line2D.Double(20, 20, 100, 100);  
        g2d.draw(line);  
    }
}


//JFrame Principal
public class FramePrincipal extends javax.swing.JFrame {    
    JTabbedPane jTP; //aqui um JTabbedPane q controla as apresentacoes dos Paineis de desenho
    ArrayList<JPanelDesktopWork> listDeskWork = new ArrayList<JPanelDesktopWork>(); //aqui um array de todos os panels desenho q vai se abrindo no projeto

    public FramePrincipal(){
         begin();
    }

    public void begin(){ //metodo de inicializacao
        this.setExtendedState(MAXIMIZED_BOTH);
        this.setLayout(new BorderLayout());
        this.add(panelNorth, BorderLayout.NORTH);
        this.jTP = new JTabbedPane();        
        this.getContentPane().add(this.jTP, BorderLayout.CENTER); 
        int location = JTabbedPane.BOTTOM;
        this.jTP.setTabPlacement(location);       
        this.add(panelSouth, BorderLayout.SOUTH);       
        getFonts();
        addDeskArea();
    }


     public void addDeskArea(){ //aqui onde add os panels ao jtabbed para desenhos 
        DesktopArea deskArea = new DesktopArea(this.jTP); 
        JPanelDesktopWork deskWork = new JPanelDesktopWork();        
        this.listDeskWork.add(deskWork);
        
        this.jTP.add(deskWork);           
        this.jTP.setTabComponentAt(jTP.getTabCount() -1, deskArea);
        this.jTP.setSelectedIndex(jTP.getTabCount() -1);
        
        /*Show coordinates*/
        deskWork.addMouseMotionListener(new MouseMotionListener() { //exibe coordenadas da area do JPanel em um JLabel
            @Override
            public void mouseDragged(MouseEvent e) {
                throw new UnsupportedOperationException("Not supported yet.");
            }

            @Override
            public void mouseMoved(MouseEvent e) {                
                lblCoordinate.setText("x:" + e.getX() + "  y:" + e.getY());
            }
        });
        /*close show coordinates*/
        
        btnLineDraw.addActionListener(new ActionListener() { //aqui qdo clico no JButton LineDraw, escolho a forma q quero desenhar e ja eh exiba  no panel de desenho.
            @Override
            public void actionPerformed(ActionEvent e) {                                
                int i = jTP.getSelectedIndex();
                DrawLine dl = new DrawLine(listDeskWork.get(i));
                dl.setLine();                
            }
            
        });
    }
    

basicamente eh esta forma q estava tentando fazer, lendo os posts de vcs vou dar uma estudada nessa lista de Shapes…

vlw, obrigado.

encontrei um exemplo a q estou seguindo para criar uma lista de shapes, muito legal.

vejam: http://www.java2s.com/Tutorial/Java/0261__2D-Graphics/Mousedraganddraw.htm

obrigado

Galera, consegui fazer em partes, soh ta faltando qdo maximizar o desenho ser exibido novamente. No click do JButton eu consegui faze-lo ser exibido novamente, mas ao maximizar naum.

public class FramePrincipal extends JFrame{
    private JButton btnClick1, btnClick2, btnClear;
    Paint p = new Paint();
    
    public FramePrincipal(){
        super("teste");
        this.setSize(800,600);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        this.setLayout(new BorderLayout());
        this.getContentPane().add(p, BorderLayout.CENTER);
        
        JPanel pBtn = new JPanel();
        btnClick1 = new JButton("teste1");
        btnClick1.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {                
                p.criaLine();
            }
        });        
        btnClick2 = new JButton("teste2");
        btnClick2.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {               
                p.recriaLine();
            }
        });
        btnClear = new JButton("limpar");
        btnClear.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
               repaint();
            }
        });
        
        WindowListener li = new WindowAdapter() {
            public void windowDeiconified(WindowEvent e) {
                System.out.println("maximizou");
                p.recriaLine();
            }
        };
        this.addWindowListener(li);                
        pBtn.add(btnClick1);
        pBtn.add(btnClick2);
        pBtn.add(btnClear);
        this.getContentPane().add(pBtn, BorderLayout.NORTH);
    }
    
    public static void main(String[] args){
        new FramePrincipal().setVisible(true);
    }
    
}




public class Paint extends JPanel{
    private Graphics2D g2d;
    ArrayList<Shape> shapes = new ArrayList<Shape>();
    
    public Paint(){
        
    }
    
    public void paintComponent(Graphics g){
        Graphics2D g2d = (Graphics2D)g;
    }
    
    public void criaLine(){
        g2d = (Graphics2D)getGraphics();
        Line2D line = new Line2D.Double(20,20,100,100);
        g2d.draw(line);
        shapes.add(line);
    }
    
    public void recriaLine(){
        for(Shape s : shapes){
            g2d.draw(s);
        }
        
    }
}

Alguma dica ???