Problemas com exibição de gráficos

16 respostas
F

Tirei este programa do livro Use a Cabeça Java, quando executo aparecem somente um botão do lado direito e outro na parte inferior da janela, mas não aparece o circulo que, segundo o livro deveria aparecer.
Alguém sabe explicar o porquê?

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

public class SimpleGui3C implements ActionListener {
	
	JFrame frame;
	
	public static void main (String[] args) {
		SimpleGui3C gui = new SimpleGui3C();
		gui.go();
	}
	
	public void go() {
		frame = new JFrame();
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		JButton button = new JButton("Change colors");
		JButton button01 = new JButton("novo");
		
		button.addActionListener(this);
		
		MyDrawPanel drawPanel = new MyDrawPanel();
		
		frame.getContentPane().add(BorderLayout.SOUTH, button);
		frame.getContentPane().add(BorderLayout.EAST, button01);
		frame.getContentPane().add(BorderLayout.CENTER, drawPanel);
		frame.setSize(300,300);
		frame.setVisible(true);
	}
	
	public void actionPerformed(ActionEvent event) {
		frame.repaint();
	}
}

	
class MyDrawPanel extends JPanel {
	public void paintComponet(Graphics g) {
		g.fillRect(0,0,this.getWidth(), this.getHeight());
		
		int red = (int) (Math.random() * 255);
		int green = (int) (Math.random() * 255);
		int blue = (int) (Math.random() * 255);
		
		Color randomColor = new Color(red,green,blue);
		g.setColor(randomColor);
		g.fillOval(70,70,100,100);
	}
}

16 Respostas

ViniGodoy

Oi, formate o seu código usando a tag code:
http://www.guj.com.br/posts/list/50115.java

Você deve tirar uma cópia do objeto Graphics antes de usa-lo. Isso é muito importante e caso você não faça isso, pode gerar problemas sérios no visual da sua aplicação.

Para fazer isso é só deixar o seu método assim:

class MyDrawPanel extends JPanel {
   public void paintComponet(Graphics graphics) {
      Graphics2D g = (Graphics2D) graphics.create(); //Cria a cópia
      g.fillRect(0,0,this.getWidth(), this.getHeight());

      int red = (int) (Math.random() * 255);
      int green = (int) (Math.random() * 255);
      int blue = (int) (Math.random() * 255);

      Color randomColor = new Color(red,green,blue);
      g.setColor(randomColor);
      g.fillOval(70,70,100,100);
      d.dispose(); //Libera a cópia.
   }
}
F

Obrigado pela dica sobre a formatação, e desculpa aí... coisa de iniciante.

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

public class SimpleGui3C implements ActionListener {
	
	JFrame frame;
	
	public static void main (String[] args) {
		SimpleGui3C gui = new SimpleGui3C();
		gui.go();
	}
	
	public void go() {
		frame = new JFrame();
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		JButton button = new JButton("Change colors");
		JButton button01 = new JButton("novo");
		
		button.addActionListener(this);
		
		MyDrawPanel drawPanel = new MyDrawPanel();
		
		frame.getContentPane().add(BorderLayout.SOUTH, button);
		frame.getContentPane().add(BorderLayout.EAST, button01);
		frame.getContentPane().add(BorderLayout.CENTER, drawPanel);
		frame.setSize(300,300);
		frame.setVisible(true);
	}
	
	public void actionPerformed(ActionEvent event) {
		frame.repaint();
	}
}

/*	
class MyDrawPanel extends JPanel {
	public void paintComponet(Graphics g) {
		g.fillRect(0,0,this.getWidth(), this.getHeight());
		
		int red = (int) (Math.random() * 255);
		int green = (int) (Math.random() * 255);
		int blue = (int) (Math.random() * 255);
		
		Color randomColor = new Color(red,green,blue);
		g.setColor(randomColor);
		g.fillOval(70,70,100,100);
	}
}
*/
class MyDrawPanel extends JPanel {  
    public void paintComponet(Graphics graphics) {  
       Graphics2D g = (Graphics2D) graphics.create(); //Cria a cópia  
       g.fillRect(0,0,this.getWidth(), this.getHeight());  
   
       int red = (int) (Math.random() * 255);  
       int green = (int) (Math.random() * 255);  
       int blue = (int) (Math.random() * 255);  
   
       Color randomColor = new Color(red,green,blue);  
       g.setColor(randomColor);  
       g.fillOval(70,70,100,100);  
       g.dispose(); //Libera a cópia.  
    }  
}

Não funcionou. A imagem fica assim.

[img]http://i324.photobucket.com/albums/k338/fredericodossantos/SimpleGui3C.jpg[/img]

ViniGodoy

Aquilo não ia funcionar mesmo. Era só uma boa prática do Swing. Mas não afeta o resultado final da pintura.
Eu não tinha olhado o resto do seu código porque estava sem formatação, e fica ruim de ler. Então, só vi o ponto onde quase todo mundo erra.

No seu actionPerformed tente fazer o seguinte:

public void actionPerformed(ActionEvent event) { drawPanel.revalidate(); frame.repaint(); }

Claro que para fazer isso você terá que guardar o drawPanel numa propriedade, e não simplesmente numa variável local.

Sem esse comando, o Swing identifica que não houve alterações nem no frame e nem no painel, e ignora solenemente o seu comando de repaint. Sem esse comando, vc pode tentar minimizar e maximizar sua janela. O painel deve mudar de cor do mesmo jeito (já que isso também causa um repaint() completo).

PS: Se quiser fazer um tutorial mais divertido que esse da Kathy, tente esse aqui:
http://www.cokeandcode.com/node/6

Ele é mais sobre Java2D do que Swing, mas o resultado é mais animador.

F

guardar o drawPanel numa propriedade?
Desculpe, pode explicar melhor?

ViniGodoy

Basta fazer como você fez com o frame:

public class SimpleGui3C implements ActionListener {   
       
    private JFrame frame;   
    private MyDrawPanel drawPanel; //Aqui, uma propriedade.
    //Resto do código aqui
}
Fernando_Generoso_da

Acho que o problema é o nome do teu método:

public void paintComponet(Graphics graphics)

deveria ser:

protected void paintComponent(Graphics g).

Fernando Rosa

ViniGodoy

Bem observado. Por isso é uma boa usar a tag @Override, sempre que sobrescrever um método.

Esse erro já teria sido pego de cara.

F

Fiz as modificações sugeridas, mas... continua não funcionando.
Alguém poderia executar este fonte e verificar se o resultado é o mesmo?

import javax.swing.*;  
 import java.awt.*;  
 import java.awt.event.*;  
   
 public class SimpleGui3C implements ActionListener {  
       
     private JFrame frame;  
     private MyDrawPanel drawPanel; 
        
     public static void main (String[] args) {  
         SimpleGui3C gui = new SimpleGui3C();  
         gui.go();  
     }  
       
     public void go() {  
         frame = new JFrame();  
         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  
         JButton button = new JButton("Change colors");  
         JButton button01 = new JButton("novo");  
           
         button.addActionListener(this);  
           
         drawPanel = new MyDrawPanel();  
           
         frame.getContentPane().add(BorderLayout.SOUTH, button);  
         frame.getContentPane().add(BorderLayout.EAST, button01);  
         frame.getContentPane().add(BorderLayout.CENTER, drawPanel);  
         frame.setSize(300,300);  
         frame.setVisible(true);  
     }  
       
     public void actionPerformed(ActionEvent event) {  
	     drawPanel.revalidate();
         frame.repaint();  
     }  
 }  
   
       
class MyDrawPanel extends JPanel {  
   protected void paintComponet(Graphics graphics) {  
      Graphics2D g = (Graphics2D) graphics.create(); //Cria a cópia  
      g.fillRect(0,0,this.getWidth(), this.getHeight());  
  
      int red = (int) (Math.random() * 255);  
      int green = (int) (Math.random() * 255);  
      int blue = (int) (Math.random() * 255);  
  
      Color randomColor = new Color(red,green,blue);  
      g.setColor(randomColor);  
      g.fillOval(70,70,100,100);  
      g.dispose(); //Libera a cópia.  
   }  
}
ViniGodoy

Nesse código que vc colou o seu paintComponent continua com nome errado.

Eu rodei aqui, só troquei o nome do método para o certo e funcionou de cara.

F

ViniGodoy, você poderia postar o código que funcionou?

ViniGodoy

Posso, mas qual a dificuldade de acrescentar uma letra "n" na palavra paintComponent?

import javax.swing.*;  
 import java.awt.*;  
 import java.awt.event.*;  
   
 public class SimpleGui3C implements ActionListener {  
       
     private JFrame frame;  
     private MyDrawPanel drawPanel; 
        
     public static void main (String[] args) {  
         SimpleGui3C gui = new SimpleGui3C();  
         gui.go();  
     }  
       
     public void go() {  
         frame = new JFrame();  
         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  
         JButton button = new JButton("Change colors");  
         JButton button01 = new JButton("novo");  
           
         button.addActionListener(this);  
           
         drawPanel = new MyDrawPanel();  
           
         frame.getContentPane().add(BorderLayout.SOUTH, button);  
         frame.getContentPane().add(BorderLayout.EAST, button01);  
         frame.getContentPane().add(BorderLayout.CENTER, drawPanel);  
         frame.setSize(300,300);  
         frame.setVisible(true);  
     }  
       
     public void actionPerformed(ActionEvent event) {  
	     drawPanel.revalidate();
         frame.repaint();  
     }  
 }  
   
       
class MyDrawPanel extends JPanel {
	@Override
   protected void paintComponent(Graphics graphics) {  
      Graphics2D g = (Graphics2D) graphics.create(); //Cria a cópia  
      g.fillRect(0,0,this.getWidth(), this.getHeight());  
  
      int red = (int) (Math.random() * 255);  
      int green = (int) (Math.random() * 255);  
      int blue = (int) (Math.random() * 255);  
  
      Color randomColor = new Color(red,green,blue);  
      g.setColor(randomColor);  
      g.fillOval(70,70,100,100);  
      g.dispose(); //Libera a cópia.  
   }  
}
F

Você negritou e eu nem percebi :shock: , foi mal, desculpa aí.
Eu fiz essa modificação na versão original e funcionou de cara. O pior é que, na versão com erro, compilou beleza, só não dava o resultado esperado.
De qualquer forma eu fico muito agradecido pela ajuda! Valeu, um abraço! :smiley:

F

fredericodossantos:
Você negritou e eu nem percebi :shock: , foi mal, desculpa aí.
Eu fiz essa modificação na versão original e funcionou de cara. O pior é que, na versão com erro, compilou beleza, só não dava o resultado esperado.
De qualquer forma eu fico muito agradecido pela ajuda! Valeu, um abraço! :smiley:

Compilou porque foi criado um novo método para a classe MyDrawPanel cujo nome era paintComponet que nunca era chamado, ao invés de se sobrepor ao método paintComponent da classe JPanel a qual MyDrawPanel extende. Estou certo?

ViniGodoy

Está certo. Por isso é importante usar o @Override sempre que vc estender uma classe e reimplementar um método. Assim o compilador consegue saber de sua intenção (que é a de sobrescrever alguma coisa) e pode te avisar que o método em questão não está sobrescrevendo nada. É especialmente útil se vc mudar o nome do método na classe pai (aí o compilador não deixa vc esquecer de mudar também na classe filha).

Só tem uma coisa errada. Embora a palavra extensão seja mesmo com “x” a palavra estender é com “s”.

Isso porque a palavra estender vem do latim vulgar e a palavra extensão do latim clássico.
E porque o português não seria o português sem pegadinhas como essa… :wink:

F

Valeu, eu nem percebi que havia escrito com “X” agora que você fez a observação e eu reli a mensagem foi que notei, fica extranho :stuck_out_tongue: mesmo. Muito Obrigado, novamente!

ViniGodoy

Acho que é pq no Java a gente “extends” muito. :lol:

Criado 27 de julho de 2008
Ultima resposta 31 de jul. de 2008
Respostas 16
Participantes 3