BUG NO JAVA? Falha de repintura de tela com o Windows 7!

17 respostas
P

Boa tarde senhoras e senhores do universo GUJ. Vamos ao problema: percebi esses dias que os últimos programas desenvolvidos com JAVA que se utilizam de uma JFrame para exibir seu conteúdo sofrem de um mal constante quando executado junto ao Windows 7. Todas as JFrame`s sofrem falha de repintura na tela chegando a travar completamente o conteúdo da JFrame após ampliação/redução automática feita pelo Windows 7.

Como causar o problema?
Execute um programa em java o qual utiliza uma JFrame para mostrar um conteúdo qualquer. Para servir de exemplo, use este código abaixo que copiei de uma pergunta feita por um dos colegas aqui no fórum (mas poderia ser qualquer outro):

import java.awt.Dimension; 
   import java.awt.FlowLayout; 
   import javax.swing.BorderFactory; 
   import javax.swing.JButton; 
   import javax.swing.JFrame; 
   import javax.swing.JLabel; 
   import javax.swing.JPanel; 
   import javax.swing.JTextField; 


   public class CadastroCliente1 extends JFrame { 
   
      private JTextField cpftxt; 
      private JTextField nometxt; 
      private JTextField ruatxt; 
      private JTextField estadociviltxt; 
      private JTextField telefone1txt; 
      private JTextField telefone2txt; 
      private JLabel cpflbl; 
      private JLabel nomelbl ; 
      private JLabel rualbl; 
      private JLabel estadocivillbl; 
      private JLabel telefone1lbl; 
      private JLabel telefone2lbl; 
      private JFrame Janela; 
      private JButton cadastrarbtn; 
      private JPanel pnlDadosPessoais; 
      private JPanel pnlEndereco; 
      private JPanel pnlContatos; 
   
      public static void main(String args[]) 
      
      { 
         new CadastroCliente1(); 
      
      } 
   
      public CadastroCliente1 () 
      
      { 
         nometxt = new JTextField(); 
         nometxt.setLocation(150, 100); 
         nometxt.setPreferredSize(new Dimension(100, 30)); 
         cpftxt = new JTextField(); 
         cpftxt.setLocation(90, 10); 
         cpftxt.setSize(100, 30); 
         ruatxt = new JTextField(); 
         ruatxt.setLocation(100,200); 
         ruatxt.setSize(100,30); 
         estadociviltxt = new JTextField(); 
         estadociviltxt.setLocation(90, 10); 
         estadociviltxt.setSize(100, 30); 
         telefone1txt = new JTextField(); 
         telefone1txt.setLocation(90, 10); 
         telefone1txt.setSize(100, 30); 
         telefone2txt = new JTextField(); 
         telefone2txt.setLocation(90, 10); 
         telefone2txt.setSize(100, 30); 
      
         nomelbl = new JLabel ("Nome: "); 
         nomelbl.setLocation(100, 10); 
         nomelbl.setSize(10, 30); 
         cpflbl = new JLabel ("CPF: "); 
         cpflbl.setLocation(100,50 ); 
         cpflbl.setSize(100, 30); 
         rualbl = new JLabel ("Rua : "); 
         rualbl.setLocation(10,20); 
         rualbl.setSize(150,50); 
         estadocivillbl= new JLabel ("Estado Civil: "); 
         estadocivillbl.setLocation(10,300); 
         estadocivillbl.setSize(150,50); 
         telefone1lbl= new JLabel ("Telefone Residencial: "); 
         telefone1lbl.setLocation(60,10); 
         telefone1lbl.setSize(150,20); 
         telefone2lbl= new JLabel ("Telefone Celular: "); 
         telefone2lbl.setLocation(10,350); 
         telefone2lbl.setSize(150,10); 
      
         cadastrarbtn = new JButton("Cadastrar"); 
         cadastrarbtn.setLocation(10,190 ); 
         cadastrarbtn.setSize(110, 30); 
      
         Janela = new JFrame(); 
         Janela.setTitle("Cadastro de Cliente "); 
         Janela.setLayout(null); 
         Janela.setLocationRelativeTo(null); 
         Janela.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
         Janela.setSize(800,500); 
         Janela.setVisible(true); 
      
      
         JPanel pnlDadosPessoais = new JPanel(); 
         pnlDadosPessoais.setBorder(BorderFactory.createTitledBorder("Dados Pessoais: ")); 
         pnlDadosPessoais.setSize(new Dimension(760, 150)); 
         pnlDadosPessoais.setBounds(10, 10, 760, 150); 
         pnlDadosPessoais.setLayout(new FlowLayout(FlowLayout.LEFT)); 
      
         JPanel pnlEndereco = new JPanel(); 
         pnlEndereco.setBorder(BorderFactory.createTitledBorder("Endereço: ")); 
         pnlEndereco.setBounds(10, 160, 760, 150); 
         pnlEndereco.setSize(new Dimension(760, 150)); 
         pnlEndereco.setLayout(new FlowLayout(FlowLayout.LEFT)); 
      
         JPanel pnlContatos = new JPanel(); 
         pnlContatos.setBorder(BorderFactory.createTitledBorder("Contatos: ")); 
         pnlContatos.setSize(new Dimension (760, 150)); 
         pnlContatos.setBounds(10, 310, 760, 150); 
         pnlContatos.setLayout(new FlowLayout(FlowLayout.LEFT)); 
      
      
         Janela.add(pnlContatos); 
         pnlContatos.add(telefone1lbl); 
         Janela.add(pnlDadosPessoais); 
         pnlDadosPessoais.add(nomelbl); 
         pnlDadosPessoais.add(nometxt); 
         pnlDadosPessoais.add(cpflbl); 
         pnlDadosPessoais.add(cpftxt); 
         pnlDadosPessoais.add(estadocivillbl); 
         pnlDadosPessoais.add(estadociviltxt); 
         Janela.add(pnlEndereco); 
         pnlEndereco.add(rualbl); 
         pnlEndereco.add(ruatxt); 
      
      
      
         Janela.show(); 
      
      } 
   }

Já com o programa em execução, clique na “borda” (para ampliar a janela, não arrastar) superior do JFrame e arraste ela para o topo da sua área de trabalho até que o windows 7 mostre rapidamente um círculo azul e uma sobra preta (contorno) do ajuste automático em volta da JFrame que ele fará de forma que fique entre o topo e a barra de tarefas da sua área de trabalho sem espaços e solte o botão do mouse. Agora repare que a tela do JFrame e seu conteúdo estão travados e poderá aparecer espaços em preto não repintados após ajuste automático da janela pelo Windows 7… um verdadeiro BUG! (Lembrando que este Win7 está utilizando todo o seu recurso gráfico ao máximo, com Aero).

E agora? Existe solução para correção?
Feliz 2012 com muita luz. 8)

17 Respostas

J

Não aconteceu comigo. Rodando no Windows 7 64 e JDK 1.7 64.

P

Joyle, arrasta a borda superior da JFrame para o topo da sua área de trabalho bem devagar, segurando o botão do mouse. Quando chegar em determinada altura da desktop, vai ver que o Windows 7 faz um rápido balão azul mostrando que a janela vai ficar ampliando do topo da desktop até a barra de tarefas, com a largura intácta… então solte o botão e veja o que acontece!

Para facilitar, vamos ilustrar a situação:

J

Foi exatamente isso que fiz! Por isso detalhei a versão do JDK que to usando. Outro detalhe é que o Windows 7 é o Home Premium.

P

Então, a versão é a mesma. A diferença é que estou com o Windows 7 Ultimate. A versão do JDK é a mesma. O Aero está ativado.
É um computador com i7-3960X 32GB DDR3-1600… Dual Nvidia GeForce GTX 580M GPU com 2GB GDDR5 (memória do vídeo).

Mais alguém está detectando o problema também? :shock:
Abraço.

V

Por favor, não coloque informações óbvias como [SEM SOLUÇÃO], [Ajuda] ou [Dúvida] nas tags informativas.

Aqui funcionou normal... E meu hardware é praticamente idêntico ao seu, e também uso o Aero.

Agora... esse código está extremamente mal escrito, contém uma série de erros:
1. O código estende JFrame, mas não usa o JFrame que estendeu;
2. O código chama o método show(), que é deprecated;
3. O código faz inserção de vários componentes, mesmo após a janela já estar visível (o setVisible é dado na linha 89). Não é tomado nenhum cuidado quanto a isso (como chamar invalidate);
4. O código posiciona elementos com setBounds, e só depois faz o setLayout.
5. O código não faz o setVisible na thread do Swing (através do EventQueue.invokeLater).
6. Usa layout null, que não dá garantias de multiplataforma.

Veja se o código abaixo melhora alguma coisa:
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class CadastroCliente1 {
	private JTextField cpftxt;
	private JTextField nometxt;
	private JTextField ruatxt;
	private JTextField estadociviltxt;
	private JTextField telefone1txt;
	private JTextField telefone2txt;
	private JLabel cpflbl;
	private JLabel nomelbl;
	private JLabel rualbl;
	private JLabel estadocivillbl;
	private JLabel telefone1lbl;
	private JLabel telefone2lbl;
	private JFrame Janela;
	private JButton cadastrarbtn;

	public static void main(String args[]) {
		EventQueue.invokeLater(new Runnable() {
			@Override
			public void run() {
				new CadastroCliente1();
			}
		});
	}

	public CadastroCliente1()

	{
		nometxt = new JTextField();
		nometxt.setLocation(150, 100);
		nometxt.setPreferredSize(new Dimension(100, 30));
		cpftxt = new JTextField();
		cpftxt.setLocation(90, 10);
		cpftxt.setSize(100, 30);
		ruatxt = new JTextField();
		ruatxt.setLocation(100, 200);
		ruatxt.setSize(100, 30);
		estadociviltxt = new JTextField();
		estadociviltxt.setLocation(90, 10);
		estadociviltxt.setSize(100, 30);
		telefone1txt = new JTextField();
		telefone1txt.setLocation(90, 10);
		telefone1txt.setSize(100, 30);
		telefone2txt = new JTextField();
		telefone2txt.setLocation(90, 10);
		telefone2txt.setSize(100, 30);

		nomelbl = new JLabel("Nome: ");
		nomelbl.setLocation(100, 10);
		nomelbl.setSize(10, 30);
		cpflbl = new JLabel("CPF: ");
		cpflbl.setLocation(100, 50);
		cpflbl.setSize(100, 30);
		rualbl = new JLabel("Rua : ");
		rualbl.setLocation(10, 20);
		rualbl.setSize(150, 50);
		estadocivillbl = new JLabel("Estado Civil: ");
		estadocivillbl.setLocation(10, 300);
		estadocivillbl.setSize(150, 50);
		telefone1lbl = new JLabel("Telefone Residencial: ");
		telefone1lbl.setLocation(60, 10);
		telefone1lbl.setSize(150, 20);
		telefone2lbl = new JLabel("Telefone Celular: ");
		telefone2lbl.setLocation(10, 350);
		telefone2lbl.setSize(150, 10);

		cadastrarbtn = new JButton("Cadastrar");
		cadastrarbtn.setLocation(10, 190);
		cadastrarbtn.setSize(110, 30);

		Janela = new JFrame();
		Janela.setTitle("Cadastro de Cliente ");
		Janela.setLayout(null);
		Janela.setLocationRelativeTo(null);
		Janela.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		Janela.setSize(800, 500);

		JPanel pnlDadosPessoais = new JPanel(new FlowLayout(FlowLayout.LEFT));
		pnlDadosPessoais.setBorder(BorderFactory
				.createTitledBorder("Dados Pessoais: "));
		pnlDadosPessoais.setSize(new Dimension(760, 150));
		pnlDadosPessoais.setBounds(10, 10, 760, 150);

		JPanel pnlEndereco = new JPanel(new FlowLayout(FlowLayout.LEFT));
		pnlEndereco.setBorder(BorderFactory.createTitledBorder("Endereço: "));
		pnlEndereco.setBounds(10, 160, 760, 150);
		pnlEndereco.setSize(new Dimension(760, 150));

		JPanel pnlContatos = new JPanel(new FlowLayout(FlowLayout.LEFT));
		pnlContatos.setBorder(BorderFactory.createTitledBorder("Contatos: "));
		pnlContatos.setSize(new Dimension(760, 150));
		pnlContatos.setBounds(10, 310, 760, 150);

		Janela.add(pnlContatos);
		pnlContatos.add(telefone1lbl);
		Janela.add(pnlDadosPessoais);
		pnlDadosPessoais.add(nomelbl);
		pnlDadosPessoais.add(nometxt);
		pnlDadosPessoais.add(cpflbl);
		pnlDadosPessoais.add(cpftxt);
		pnlDadosPessoais.add(estadocivillbl);
		pnlDadosPessoais.add(estadociviltxt);
		Janela.add(pnlEndereco);
		pnlEndereco.add(rualbl);
		pnlEndereco.add(ruatxt);
		Janela.setVisible(true);
	}
}
P

Fala Godoy, boa noite!

Realmente peço desculpa pela tag, foi ignorância da minha parte, você tem toda razão e eu estou errado.
Também agradeço muito a sua atenção em respoder ao tópico e pela correta escrita do código que peguei de um exemplo de um rapaz aqui neste mesmo fórum.

O problema é que não é só com esse código que ocorre a falha. É com todos! Testei esse mesmo código corrigido, e o problema persiste. :shock:

Eu estou começando a desconfiar que não estou sabendo explicar como provocar o erro… o mesmo está acontecendo aqui em 6 máquinas diferentes, com o mesmo S.O. (Win7 Ultimate), mesma versão JDK e a mesma configuração.

Tente ampliar a janela (não arrastar) até o topo e não solte o botão do mouse. Aguarde o Windows mostrar aquela sombra (borda preta) com fundo “tipo vidro” e aí então solte o botão e veja se está estável o sistema. Tente digitar na JTextField e ve se algo aparece.
(como está na TELA2 da imagem que postei acima)

Sucesso ViniGodoy, parabéns pela atuação constante de anos neste fórum. :wink:

:arrow: Gujeiros, por favor, não deixem de postar se está acontecendo o erro ou não…

V

As máquinas tem uma só imagem, ou são instalações diferentes? Seus Windows são originais?
A versão do JDK é a última? Já tentou atualizar? E os drivers da placa de vídeo, estão atualizados?

P

Vini, não, cada PC tem sua própria imagem, sendo quatro delas Ultimate, duas são Home. Todas originais. A versão do SDK é a 1.7, a última. Atualizações em dia. Drivers de video OK, também vierão junto com os PC`s novos e atualizados.
Complicado né? Eu também não sei mais… no XP (em uma das máquinas antigas) roda liso, perfeito! O bom e velho XP continua 100%. Vou tentar ainda esta semana verificar em computadores com Win7 de modelos diferentes para ter certeza do problema.
Caso persista o erro, vou fazer uma gravação da tela em vídeo e postar no YouTube para mostrar aqui, neste tópico, afim de que todos tenham conhecimento real do problema que está ocorrendo.

Grande Godoy, parabéns pelo esforço em ajudar, muito sucesso! :smiley:

P

Deixa acrescentar mais uma informação, que poderá ajudar a quem está tentando entender o BUG: ele ocorre em qualquer resolução de vídeo. Desde a mais baixa até a mais alta.
Outro detalhe, após o problema ocorrer, basta clicar na janela e reposicioná-la (agora não é ampliar de cima até embaixo, é arrastar a JFrame pela área de trabalho) para que volte ao normal.

Obrigado pessoal e peço por favor: se está tentando fazer o problema ocorrer e não ocorrer, poste aqui sua tentativa!
SAÚDE A TODOS :-o

D

Normal aqui. Win7 professional, JDK 7, geforce 2gb, 8gb ram, core i7 sandy-bridge.
Não acho que seja bug nem do JDK nem do Windows, mas sim algum probleminha com a sua máquina quando roda o Win7.

[]'s

G

Eu consegui reproduzir o problema.
Meu hardware é bastante diferente dos citados acima, então não vejo necessidade de listá-lo.
Quanto ao software: Java 1.7.0_01 32 bits, Windows 7 Professional 64 bits.

Ao pessoal que não conseguiu reproduzir o bug: sugiro que leiam com atenção a descrição de como reproduzi-lo e então tentem novamente.

E

Cara, a melhor coisa que tu pode fazer é reportar o problema pra oracle, pra ver se eles ajeitam…

P

Então, realmente estava desconfiado que o pessoal não estava conseguindo reproduzir o problema porque não consegui explicar de forma fácil como causar o BUG. :frowning: Mas nosso colega gpellizzoni conseguiu…
Pois é elissonandrade vou seguir seu conselho, acredito ser a única alternativa. Ontem, reproduzi o problema em computadores diferentes (até em notebooks) e o problema persiste para todas as versões Windows 7.

Eu acredito que como o Win7 faz esses ajustes automáticos de posicionamento e ampliação de janelas, o próprio esteja gerando incompatibilidades com o Java.
:arrow: Querem ver só? Muito simples: acione o listener para receber os eventos de State de uma JFrame, como segue no código abaixo…

import javax.swing.JFrame;
import java.awt.event.WindowStateListener;
import java.awt.event.WindowEvent;

public class Teste extends JFrame {
...
         addWindowStateListener( 
               new WindowStateListener() {
                  public void windowStateChanged(WindowEvent e){
                     System.out.println("Estado anterior do tamanho da janela: "+e.getOldState());
                     System.out.println("Estado atual do tamanho da janela: "+e.getNewState());
                  }});
...

Agora faça ajustes do tipo: arraste a janela para o canto direito ou esquerdo do seu monitor de forma que o Windows automaticamente posicione ao tamanho de meia tela cheia… Repare que o windowStateChanged não reconhece que a janela sofreu um reajuste. Se você minimizar a janela e em seguida restaurar, repare que a janela vai estar na posição antiga, ou seja, a janela não está mais ajustada na posição automática de meia tela e sim na posição anterior ao reajuste… !!!

Até aí, legal, o problema de travar a janela não ocorre e o sistema continua estável. Mas repare que esse reajuste o Java não reconheceu! O mesmo deve estar ocorrendo na ampliação da janela, conforme descrevi nas postagens anteriores deste tópico, com a diferença de travar a visualização inteira. O Java não reconhece esses eventos do Win7 para repintar a janela quando essas alterações ocorrem (ampliação e reposicionamento automático)… PQ digo repintura? Porque mesmo a visualização estando totalmente travada, o sistema continua trabalhando como se nada estivesse acontecendo na parte gráfica… botões continuam clicáveis, caixas de texto continuam recebendo texto… mas nada mais é visualizado, ou seja, repintado na tela.

Se mais alguém tiver algo a acrescentar, não poupe palavras nem idéias, por favor! Publique.
Saúde para todos em 2012! Sucesso senhores.

V

Consegui reproduzir. É bug mesmo. E já foi reportado e aceito:
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6630702
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6873928
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6898838

P

Show ViniGodoy, analisou e identificou muito bem o bug. :thumbup: Agora estou aliviado… Ufa!
Caramba, desde a época do Windows Vista já ocorria… a quase cinco anos atrás!! :shock:

Parabéns a todos que ajudaram, muita saúde!

H

Opa,

Que bom saber que isso ocorre com mais pessoas… eu já estava começando a achar que era meu laptop que estava com algum problema… =P Acho o Windows 7 meio bugado, eu uso o tema clássico do windows, e no chrome, às vezes quando clico na barra azul lá em cima, aparece a do windows por baixo, meio que entrelaçando com a azul do chrome. Bagulho estranho…

Outra coisa que acontece bastante é algo desse tipo:

Abri a telinha…

Cliquei no botão para abrir a outra tela…

Arrasto a nova tela e… a de trás bugou toda…

O único jeito pra limpar a tela bugada é maximizando e restaurando denovo… o.O

Nada como WinXP… =)

Valeu

P

Amigo, seu problema é realmente muito parecido com um outro problema em que ambos surgem o mesmo efeito. Para tal e, para que os assuntos dos tópicos não se misturem, abri um novo tópico neste mesmo fórum.
Segue URL: http://www.guj.com.br/java/261972-jpanel-com-jbutton-nao-e-sobreposto-por-outro-jpanel-sobreposicao-de-paineis-nao-funciona
Um abraço, não deixe de acompanhar! :wink:

Criado 26 de dezembro de 2011
Ultima resposta 2 de jan. de 2012
Respostas 17
Participantes 7