Ajuda com Desenho em JPanel!

4 respostas
F

Olá, pessoal! Sou novato aqui no fórum.
Estou fazendo um projetinho sobre física do ensino médio para faculdade. Para isso estou usando uma JFrame como janela principal e desenhando no modo gráfico todas as telas em JPanel para ir exibindo na janela principal conforme for preciso. Porém me deparei com um problema, em determinada tela, onde eu preciso fazer um desenho, nada acontece, a tela permanece cinza. Em princípio pensei que o código gerado pelo modo gráfico do NETBEANS pudesse estar interferindo em algo, mas eu fiz na mão essa tela e mesmo assim o problema persiste. Alguém pode me ajudar? Seguem o código da JFrame janela principal e JPanel que a tela do desenho, respectivamente:

Janela principal do programa

import javax.swing.*;
import java.awt.*;
import javax.swing.event.*;
import java.awt.event.*;

public class Principal extends JFrame implements ActionListener {
      
    JMenuBar menubar;
    JMenu menuArquivo, menuAjuda;
    JMenuItem itemSair, itemSobre;
    JButton btn_lin, 
            btn_lsim,
            btn_sup, 
            btn_ssim,
            btn_vol, 
            btn_vsim,
            btn_inicio;
    JPanel pn_centro, pn_botoes;
    Inicio tela_inicio;
    Linear tela_linear; 
    
    public Principal() {
        super("Dilatação Térmica 1.0");
        
        setLayout(new BorderLayout());
        tela_inicio = new Inicio();
        
        menubar = new JMenuBar();
        menuArquivo = new JMenu("Arquivo");
        menuAjuda = new JMenu("Ajuda");
        itemSair = new JMenuItem("Sair");
        itemSobre = new JMenuItem("Sobre");
        btn_lin = new JButton("Dilatação Linear");
        btn_lsim = new JButton("Simular");
        btn_sup = new JButton("Dilatação Superficial");
        btn_ssim = new JButton("Simular");
        btn_vol = new JButton("Dilatação Volumétrica");
        btn_lsim = new JButton("Simular");
        btn_inicio = new JButton("Início");
        pn_botoes = new JPanel();
        pn_centro = new JPanel();
        
        iniciaEventos();
        
        desenhaTela();
       
        setSize(800,600);                   
        
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setVisible(true);
    }

   public void iniciaEventos(){
        itemSair.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e){
                System.exit(0);
            }
        });
        
        itemSobre.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e){
               JFrame f_sobre = new JFrame("Dilatação Térmica 1.0");
               f_sobre.setSize(200,100);
               f_sobre.setVisible(true);
               f_sobre.setLocation(getSize().width/2, getSize().height/2);

            }
        });
        
        btn_lin.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e){

                pn_centro.removeAll();
                pn_centro.add(new Linear());
                
                JButton btn_lin2 = new JButton("Simular");
                pn_botoes.add(btn_lsim);
                
                pn_botoes.remove(btn_lin);
                pn_botoes.remove(btn_vol);
                pn_botoes.remove(btn_sup);
                        
                pn_centro.revalidate();
                repaint();
            }
        });
        
        btn_lsim.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e){
                pn_centro.removeAll();
                pn_centro.add(new LinearS());
                pn_botoes.remove(btn_lsim);
                pn_centro.revalidate();
                repaint();

            }
        });
        
        btn_inicio.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e){
                pn_centro.removeAll();
                desenhaTela();
                pn_centro.revalidate();
                repaint();
            }
        });
    }
    
    public void desenhaTela(){
       
        pn_centro.add(tela_inicio);
        add(pn_centro,BorderLayout.CENTER);

        menubar.add(menuArquivo);
        menubar.add(menuAjuda);
        menuArquivo.add(itemSair);
        menuAjuda.add(itemSobre);
        add(menubar, BorderLayout.NORTH);        
        
        menuArquivo.setMnemonic('a');
        menuAjuda.setMnemonic('h');
        itemSair.setMnemonic('s');
        
        pn_botoes.setLayout(new FlowLayout());        
        pn_botoes.add(btn_inicio);
        pn_botoes.add(btn_lin);
        pn_botoes.add(btn_sup);
        pn_botoes.add(btn_vol);
        
        //pn_centro.setOpaque(true);
        //pn_centro.setBackground(Color.WHITE);
        
        add(pn_botoes, BorderLayout.SOUTH);
    }
    
    public void actionPerformed(ActionEvent e){
        
    }

    public static void main(String args[]){
        Principal teste = new Principal();
    }
}

JPanel da tela a ser desenhada, chamada pelo evento actionPerformed do botão btn_lsim na janela principal

import java.awt.geom.GeneralPath;
import javax.swing.*;
import java.awt.*;

 public class LinearS extends JPanel
{   
        
        public LinearS(){
             this.setOpaque(true);
             repaint();
        }

        public void paintComponent(Graphics g)
        {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g;
            GeneralPath cubo = new GeneralPath();
           
            cubo.moveTo(100, 100);
            cubo.lineTo(200, 100);
            cubo.lineTo(200, 200);
            cubo.lineTo(100, 200);
            cubo.closePath();
            
            cubo.moveTo(150, 150);
            cubo.lineTo(250, 150);
            cubo.lineTo(250, 250);
            cubo.lineTo(150, 250);
            cubo.closePath();
            
            cubo.moveTo(150, 150);
            cubo.lineTo(100, 100);
            cubo.moveTo(250, 150);
            cubo.lineTo(200, 100);
            cubo.moveTo(250, 250);
            cubo.lineTo(200, 200);
            cubo.moveTo(150, 250);
            cubo.lineTo(100, 200);
            g2d.translate(100,100);
            g2d.draw(cubo);
        }
    
}

4 Respostas

T

Você não se esqueceu de setar o paint do objeto Graphics2D? Usualmente eu faria assim:

import java.awt.geom.GeneralPath;
import javax.swing.*;
import java.awt.*;

 public class LinearS extends JPanel
{   
        
        public LinearS(){
             this.setOpaque(true);
             repaint();
        }

        public void paintComponent(Graphics g)
        {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create(); // isto faz com que você trabalhe com uma cópia do objeto g original
            g2d.setPaint (Color.BLACK); // por exemplo; use a cor desejada para pintar o cubo
            GeneralPath cubo = new GeneralPath();
           
            cubo.moveTo(100, 100);
            cubo.lineTo(200, 100);
            cubo.lineTo(200, 200);
            cubo.lineTo(100, 200);
            cubo.closePath();
            
            cubo.moveTo(150, 150);
            cubo.lineTo(250, 150);
            cubo.lineTo(250, 250);
            cubo.lineTo(150, 250);
            cubo.closePath();
            
            cubo.moveTo(150, 150);
            cubo.lineTo(100, 100);
            cubo.moveTo(250, 150);
            cubo.lineTo(200, 100);
            cubo.moveTo(250, 250);
            cubo.lineTo(200, 200);
            cubo.moveTo(150, 250);
            cubo.lineTo(100, 200);
            g2d.translate(100,100);
            g2d.draw(cubo);
            g2d.dispose(); // usou create, tem de usar dispose ...
        }
    
}
F

thingol

Eu esqueci de colocar o setPaint no código aqui sim, mas eu já havia tentado isso, modifiquei o código de acordo com que você falou, mas nada… :frowning:

Será que algo na chamada desta tela pode estar causado isso?

btn_lsim.addActionListener(new ActionListener(){  
             public void actionPerformed(ActionEvent e){  
                 pn_centro.removeAll();  
                 pn_centro.add(new LinearS());  
                 pn_botoes.remove(btn_lsim);  
                 pn_centro.revalidate();  
                 repaint();  
   
             }  
         });
F

Problema resolvido, achei!! :slight_smile:

public void desenhaTela(){  
          
         pn_centro.setLayout(new BorderLayout()); //APENAS ESSA LINHA!!

         pn_centro.add(tela_inicio);  
         add(pn_centro,BorderLayout.CENTER);  
   
         menubar.add(menuArquivo);  
         menubar.add(menuAjuda);  
         menuArquivo.add(itemSair);  
         menuAjuda.add(itemSobre);  
         add(menubar, BorderLayout.NORTH);          
           
         menuArquivo.setMnemonic('a');  
         menuAjuda.setMnemonic('h');  
         itemSair.setMnemonic('s');  
           
         pn_botoes.setLayout(new FlowLayout());          
         pn_botoes.add(btn_inicio);  
         pn_botoes.add(btn_lin);  
         pn_botoes.add(btn_sup);  
         pn_botoes.add(btn_vol);  
           
         //pn_centro.setOpaque(true);  
         //pn_centro.setBackground(Color.WHITE);  
           
         add(pn_botoes, BorderLayout.SOUTH);  
     }

Eu esqueci de mudar o layout, o default é FlowLayout, então o painel ficava com tamanho zero…

ViniGodoy

Só não se esqueça de dar o create e o dispose no objeto Graphics, como o Thingol sugeriu.

É muito importante que o objeto Graphics que você recebe no parâmetro do PaintComponent não tenha seu estado alterado.

Ou então, você pode ter um aplicativo se comportando de maneira estranha (janelas não são pintadas, ou aparecem erradas). E, como isso acontece só de vez enquando e não é um problema de lógica em si, se torna um erro muito difícil de se encontrar.

Criado 29 de outubro de 2007
Ultima resposta 31 de out. de 2007
Respostas 4
Participantes 3