Problema com JFrame e paint

17 respostas
M

Boa noite a todos!

Sou novo aqui no forum e no java tambem. Estou com um problema em meu programa. Uso o paint g para desenhar a imagem (layout) que declarei anteriormente mas ao usar o g.drawImage, a imagem não aparece. Na verdade o paint parece não funcionar. Outro problema que tenho é que quando clico no botão para calcular meus valores, dá o seguinte o erro:

at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:994)

at java.lang.Double.valueOf(Double.java:475)

at EfeitoFotoeletrico$calcular.actionPerformed(EfeitoFotoeletrico.java:175)

at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1995)

at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2318)

at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387)

at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242)

at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:236)

at java.awt.Component.processMouseEvent(Component.java:6263)

at javax.swing.JComponent.processMouseEvent(JComponent.java:3267)

at java.awt.Component.processEvent(Component.java:6028)

at java.awt.Container.processEvent(Container.java:2041)

at java.awt.Component.dispatchEventImpl(Component.java:4630)

at java.awt.Container.dispatchEventImpl(Container.java:2099)

at java.awt.Component.dispatchEvent(Component.java:4460)

at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4574)

at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4238)

at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4168)

at java.awt.Container.dispatchEventImpl(Container.java:2085)

at java.awt.Window.dispatchEventImpl(Window.java:2475)

at java.awt.Component.dispatchEvent(Component.java:4460)

at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)

at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)

at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)

at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)

at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)

at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)

at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)

O código segue abaixo:

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

public class EfeitoFotoeletrico extends JFrame {
	
	 Image Im = new ImageIcon ( getClass ( ).getResource ( "/layout.jpg" ) ).getImage ( );  	

	 JFrame tela = new JFrame(); //Cria a tela do programa
	 

	 double h = 6.63E-34; //Constante de Planck em J.s
	 double ce = 1.60E-19; //Carga do eletron em C
	 double c = 3.00E+8; //Velocidade da luz em m/s
	 double m = 9.00E-31; //Massa do Elétron
	 	
	 double co; //Comprimento de onda
	 double f; //Frequencia
	 double I; //Intensidade do feixe
	 double V; //Potencial aplicado
	 double V0; //Potencial de corte
	 double ie; //Corrente eletrica
	 double Ec; //Energia cinetica
	 double T; //Função trabalho
	 double ve; //Velocidade do elétron; 
	
     
     //Cria os campos onde serão inseridos os dados
     JTextField TCompOnda = new JTextField();  
     JTextField TFuncTrabalho = new JTextField();
     JTextField TPotencAplic = new JTextField();
     JTextField TIntensidade = new JTextField();
     JTextField EnergiaCinetica = new JTextField();
     JTextField VeloEletron = new JTextField();
     
                                     
	 //Cria os rótulos                                     
     JLabel rotulo1  = new JLabel("<html>Comprimento de Onda:</html>");  
     JLabel rotulo2  = new JLabel("<html>Função Trabalho:</html>");
     JLabel rotulo3  = new JLabel("<html>Potencial Aplicado:</html>");
     JLabel rotulo4  = new JLabel("<html>Intensidade do feixe:</html>");
     JLabel rotulo5  = new JLabel("<html>Energia Cinetica: </html>");
     JLabel rotulo6  = new JLabel("<html>Velocidade do Elétron:</html>");
     JLabel rotulo7  = new JLabel("<html>Potencial de Corte:</html>");
     JLabel rotulo8  = new JLabel("<html>Corrente Gerada:</html>");
     
     //Cria o butão             
     JButton entra = new JButton("CALCULAR");  
     
       
    public EfeitoFotoeletrico() {
    
    //Configurando a tela
         tela.setLayout(null);  
         tela.setSize(1024,768);  
         tela.setVisible(true);  
         tela.setLocationRelativeTo(null);
         tela.setTitle("Efeito Fotoelétrico");
       	 tela.setDefaultCloseOperation(EXIT_ON_CLOSE);  
       	 	
   
       	 
       
    //Adicionando todos os itens na tela                                 
         tela.add(rotulo1);
         tela.add(rotulo2);
         tela.add(rotulo3);
         tela.add(rotulo4);
         tela.add(rotulo5);
         tela.add(rotulo6);
         tela.add(rotulo7);
         tela.add(rotulo8);     
           
         tela.add(TCompOnda);
         tela.add(TFuncTrabalho);
         tela.add(TPotencAplic);
         tela.add(TIntensidade);
         tela.add(EnergiaCinetica);
         tela.add(VeloEletron);
         
         tela.add(entra);
         
  
         
     //Posicionando e configurando os itens na tela                                                             
         rotulo1.setVisible(true);  
         rotulo1.setSize(80,80);  
         rotulo1.setLocation(10,10);
                   
    	 rotulo2.setVisible(true);  
         rotulo2.setSize(80,80);  
         rotulo2.setLocation(100,10);  
    
 		 rotulo3.setVisible(true);  
         rotulo3.setSize(80,80);  
         rotulo3.setLocation(190,10);  
    
         rotulo4.setVisible(true);  
         rotulo4.setSize(80,80);  
         rotulo4.setLocation(280,10);  
    
    
         rotulo5.setVisible(true);  
         rotulo5.setSize(80,80);  
         rotulo5.setLocation(400,10);  
         	
      	 rotulo6.setVisible(true);  
         rotulo6.setSize(80,80);  
         rotulo6.setLocation(400,100);  
         	
         rotulo7.setVisible(true);  
         rotulo7.setSize(80,80);  
         rotulo7.setLocation(400,200);  
         	
         rotulo8.setVisible(true);  
         rotulo8.setSize(80,80);  
         rotulo8.setLocation(400,300); 
         	
         TCompOnda.setVisible(true);  
         TCompOnda.setSize(80,50);  
         TCompOnda.setLocation(10,90); 
         	
         TFuncTrabalho.setVisible(true);  
         TFuncTrabalho.setSize(80,50);  
         TFuncTrabalho.setLocation(100,90); 
         	
         TPotencAplic.setVisible(true);  
         TPotencAplic.setSize(80,50);  
         TPotencAplic.setLocation(190,90); 
         	
         TIntensidade.setVisible(true);  
         TIntensidade.setSize(80,50);  
         TIntensidade.setLocation(280,90);
         
         EnergiaCinetica.setVisible(true);
         EnergiaCinetica.setSize(80,50);
         EnergiaCinetica.setLocation(490,25);
         EnergiaCinetica.enable(false);
         
         VeloEletron.setVisible(true);
         VeloEletron.setSize(80,50);
         VeloEletron.setLocation(490,120);
         VeloEletron.enable(false); 
        
         entra.setVisible(true);  
         entra.setSize(100,40);  
         entra.setLocation(100,150);  
              
       	 entra.addActionListener(new calcular()); // Inicia o processo de ação no butão  
    	
    }
    
       class calcular implements ActionListener{    
         
          public void actionPerformed(ActionEvent e){    
                 
                      //Procedimentos a serem executados ao clicar no botão:  
                      
                      //Lendo os dados das caixas de texto
                        String FT = TFuncTrabalho.getText();
                        String PA = TPotencAplic.getText();
                        String CPO = TCompOnda.getText();
                        String IF = TIntensidade.getText();
                      
                       //Jogando os dados transformados em double nas variaveis   
                       T = Double.valueOf(FT);
                       V = Double.valueOf(PA);
                       co = Double.valueOf(CPO);
                       I = Double.valueOf(IF);     
                                        
                       //Calculando os valores                 
                        f = c / (co / [telefone removido]);
                        Ec = f * h - T;
                        ve = Math.sqrt((2 * m) / Ec);
                        V0 = Ec / ce;
                        
                        //Exibindo na tela
                       String Ec2 = String.valueOf(Ec);     
                       EnergiaCinetica.setText(Ec2);
                       
                       String VelEle = String.valueOf(ve);
                       VeloEletron.setText(VelEle); 
                                                                   
                                    }    
          
                  
 }
    
    	public static void main(String args[]){

		JFrame p = new EfeitoFotoeletrico();
		
		}


                          	
          public void paintComponent(Graphics g) {
          	
	    	g.drawImage (Im,0,0,this);
     		
			}
            

    
}

Alguem pode me ajudar?

17 Respostas

V

Oi. Vá no post ali em cima, clique em “Editar”, e depois coloque seu código entre as tags code:

Seu código

Senão fica impossível de ler.

E

Olá! Bem vindo ao GUJ!

Use a tag CODE para colocar seu código. Ele ficará melhor para ler.

1: O seu método public void paintComponent(Graphics g) não está sendo chamado. Por isso o seu problema não está no g.drawImage().

2: Tire a instrução Im = new ImageIcon(getClass().getResource("orly.jpg")).getImage(); do escopo da classe e faça assim:
Image Im;

    public EfeitoFotoeletrico() {
        Im = new ImageIcon(getClass().getResource("/layout.jpg")).getImage();
        // ... outras declarações aqui
    }
porque está dando NullPointerException.

3: Percebi que vc extendeu a classe JFrame e ainda criou um objeto JFrame tela = new JFrame(); //Cria a tela do programa.
Se vc extendeu a classe JFrame, a sua tela já está aí; não precisa fazer os dois. Aconselho vc excluir a declaração tela.

Fora isso, está tudo funcionando perfeitamente.

M

Olá!

Obrigado pela dica, agora ficou legal pra ler.

Sobre o código, como faço para chamar o método public void paintComponent(Graphics g)? E sobre a declaração tela, se excluir como faço para configurar a tela e adicionar os itens?

Obrigado pela ajuda!

Abraços,

Marcelo.

V

O paintComponent é para filhos de JComponent. No caso do JFrame (que é filho de JWindow e não JComponent) você deve sobrescrever o método paint(). Dá uma lida no artigo conhecendo o JFrame, do Ponto V!

M

Boa tarde Vini,

li o seu topico e achei bem explicativo.

Já rescrevi a função paint:

public void paintComponent(Graphics g) {

Mas ainda não funciona.

O que pode estar havendo?

Abraço,

Marcelo.

V

Você sobrescreveu paintComponent ou paint?

Coloque um @Override em cima da função para confirmar que se trata de uma sobrescrita.

E

Faz o que o Vini está mandando que vai funcionar.
vc tem que sobrescrever o metodo paint().

M

Olá, bom dia!

Desculpe mas ainda não entendi como sobrescrever o método paint. Estou fazendo assim:

public void paintComponent(Graphics g) {
          	         	
            super.paintComponent(g);
	    
        	g.drawImage (Im,0,0,this); }

Mas ao compilar, essa instrução super.paintComponent não é aceita.

Aguardo, obrigado.

V

Sim, pq o método paintComponent só existe em filhos de JComponent. Como JFrame é um filho de JWindow, o único método que existe é o paint. Sem a palavra component.

Então, vc deve sobrescrever assim:

@Override public void paint(Graphics g) { super.paint(g); g.drawImage (Im,0,0,this); }

M

Sim, fiz exatamente isso. Compila normal mas a imagem ou qualquer instrução de desenho, ainda não aparece. Será preciso um repaint() em algum lugar?

@Override
            public void paint(Graphics g) {
          	         	
            super.paint(g);
	    	g.drawImage (Im,0,0,this);
	         		
			}
M

Olá,

retificando a informação:

A imagem apareceu quando tentei redimensionar a tela e clicar em algo. O problema é que ela ficou por cima de tudo (botões, labels e caixas de texto). Como faço para resolver este problema?

Abraço,

Marcelo.

V

Na verdade, se você quer colocar uma imagem de fundo, então é melhor sobrescrever um JPanel.

O paint do JFrame (como expliquei no artigo), chama os métodos paintComponent, paintChildren e paintBorder de todos os componentes que estiverem dentro dele. Por isso, na chamada super.paint(g), esses componentes já estarão pintados.

Quando vc chama o drawImage, a imagem é pintada sobre eles.

Dê uma olhada nesse painel aqui:
http://www.guj.com.br/posts/list/56248.java#295271

Se você sobrescreve o paint de um JWindow, o ideal é que você não misture essa sobrescrita com as classes do Swing. Se você precisa misturar, é melhor fazer componentes, filhos de JComponent.

M

Não conheço bem a estrutura de um JPanel. Teria que rescrever todo esse programa usando JPanel ao invés de JFrame?

Como seria?

V

O JPanel é um container.

Quando você faz:

tela.add(umObjeto);

Na verdade você está fazendo:

tela.getContentPane().add(umObjeto);

O código, na verdade, vai ficar muito parecido. Você vai criar um JPanel, adicionar na sua tela, e então adicionar os componentes no JPanel e não na tela diretamente.

M

:!:

M

Será que eu não posso criar um JPanel dentro do construtor mantendo a minha estrutura do JFrame, assim:

JPanel panel = new JPanel() {
    		 public void paintComponent(Graphics g) {          
			 super.paintComponent(g);    
                 	
          
	    	g.drawImage (Im,0,0,this);
	        g.fillRect(10,10,10,10); 		
			}            	 

    };
        
    getContentPane().add(panel);
    	
    }

Mas esta imagem não aparece…

M

Muito obrigado Vini!

Consegui resolver o problema com o JPanel.

Abraços!

Marcelo.

Criado 17 de fevereiro de 2010
Ultima resposta 20 de fev. de 2010
Respostas 17
Participantes 3