Sou novo no fórum e estou com um problemão aqui. Tenho dois sistemas Java Desktop que desenvolvi há cerca de três anos, usando netbeans e windows xp. Esta semana fui fazer umas atualizações e percebi que algumas funções antigas e estáveis não estavam mais funcionando direito. Revisei o código e não havia erro. Lembrei-me então que o sistema do IRPF (Java) também não quis abrir declarações na minha máquina. Testei ele de novo e continua não abrindo. Então testei tudo num note com windows 7 basic e tudo funcionou normal como antes. Decidi formatar minha máquina, passei o combofix, avira, testei diferentes jre’s e não resolveu. Liguei para meus clientes e vi que as máquinas que estão rodando xp estão com o mesmo problema no java. Li uma reportagem de que a Kapersky descobriu um virus que afeta o javaw.exe, mas não deu solução (http://superdicas.com.br/blog/?p=824).
Boa Tarde, descobri algumas coisas. O windows 7 estava com a jre 1.6.0, na qual tudo roda bonito. As jres mais recentes não executam os programas citados corretamente. No site da sun está escrito que eles recomendam usar as versões mais novas, e se algum programa antigo não funcionar, o desenvolvedor deve atualizar o sistema para a jre mais nova. Desculpem a ignorância, mas existe algum meio de eu saber quais funções foram afetadas ou vou ter que testar o sistema todo de novo? Sinceramente, entendo que uma atualização deve melhorar as coisas, não travá-las.
V
ViniGodoy
O que não está funcionando direito? Que tipo de erro está dando?
Sem descrever exatamente que tipo de problema você está tendo, vai ser difícil te ajudar…
E
entanglement
Tem muita gente que escreve sistemas que só funcionam em uma determinada versão do JDK - por exemplo, tem gente que testa a versão e checa se é exatamente 1.6; se for 1.7 não funciona. Pode ter ocorrido isso.
Outra coisa é que tem muita gente que escreve sistemas usando alguma classe que não está documentada (tipicamente algo como “com.sun.*” ) que são classes que podem não estar mais disponíveis em uma versão posterior do JDK, até porque a Oracle (Sun) não documentou as classes justamente para você não as usar. Aí os programas acabam quebrando.
Eu tenho o costume de, se tenho um sistema muito complexo, e houver uma atualização do JDK (do tipo 6 para 7) testar o sistema todo de novo porque pode realmente haver alguma coisa do tipo “funcionava antes por acaso - por acidente - e agora que corrigiram um determinado bug o sistema não funciona mais porque dependia desse bug”.
Ou então, o que é mais fácil, distribuir a versão exata do JDK com a qual testei o sistema.
Pense bem - isso é mais ou menos o que ocorre quando você tem um joguinho que funcionava bem no Windows XP e pára de funcionar no Windows 7. Houve uma atualização e pode ser que o joguinho não funcione mais porque ele dependia de alguma particularidade do Windows XP que não existe mais no Windows 7 ou então funciona de jeito diferente.
G
gambazinho
entanglement:
Pense bem - isso é mais ou menos o que ocorre quando você tem um joguinho que funcionava bem no Windows XP e pára de funcionar no Windows 7. Houve uma atualização e pode ser que o joguinho não funcione mais porque ele dependia de alguma particularidade do Windows XP que não existe mais no Windows 7 ou então funciona de jeito diferente.
com todo respeito, Dr. Entanglement, mas vossa excelência não acha que isso ta errado? afinal a JVM existe para isso, esse conceito de multiplataforma. não importa onde meu programa irá rodar, tendo a jvm instalada ele vai funcionar independente de SO instalado… sempre acreditei nesse princípio.
E
entanglement
Estou fazendo uma comparação com a parte de versionamento do Windows - você deve saber que a prática é diferente da teoria e do marketing.
Felizmente, no caso do Java, a teoria (write once, run anywhere) está bem próxima da realidade (write once, test anywhere) - tanto é que tenho uma aplicação que roda direitinho em Java 6 e 7 em Windows, Linux e MacOSX sem que eu tivesse de mexer muito nela (apenas acertar algumas coisinhas).
Provavelmente o tal sistema que não inicia em Java 7 do amirfenix deve ter apenas alguma bobeirinha que talvez seja questão de mexer em algumas poucas linhas de código.
V
ViniGodoy
Isso me lembra uma frase que li certa vez: “Em teoria, a teoria funciona na prática. Na prática, não.”
Pense bem - isso é mais ou menos o que ocorre quando você tem um joguinho que funcionava bem no Windows XP e pára de funcionar no Windows 7. Houve uma atualização e pode ser que o joguinho não funcione mais porque ele dependia de alguma particularidade do Windows XP que não existe mais no Windows 7 ou então funciona de jeito diferente.
com todo respeito, Dr. Entanglement, mas vossa excelência não acha que isso ta errado? afinal a JVM existe para isso, esse conceito de multiplataforma. não importa onde meu programa irá rodar, tendo a jvm instalada ele vai funcionar independente de SO instalado… sempre acreditei nesse princípio.
Isso não é verdade. Existem muitos parâmetros que você precisa levar em conta. Entre o java 1.6 e java 1.7 existe uma grande diferença no quesito “compilador, otimizador, e gerenciamento de memória”. O hotspot do java 1.7 trabalha de maneira diferente do 1.6. O otimizador é bem mais agressivo.
Por exemplo, quando você roda um “bytecode” gerado pelo compilador do jdk 1.6 na jvm 1.7, a otimização do hotspot dessa última pode arrancar partes importantes do seu programa. Por isso alguns chegam a travar e nem a rodar na jvm mais nova.
Como o pessoal postou mais acima “write once run anywhere” é uma coisa complicada de se conseguir. Você precisa pesar essas variáveis e constantes que foram citadas.
A
amirfenix
Boa noite a todos.
Até agora o problema que encontrei foi este: Tenho uma aplicação com validação de data em uma JFormattedTextfield. Supondo que digito uma data inválida e a seguir clico no botão salvar,o focusLost do campo data deve primeiro validar a data, exibir a mensagem de erro e retornar o foco para o campo data, impedindo a execução do código do botão salvar. Tudo funciona desta forma na jre 1.6.0, mas acima desta jre ocorre que o sistema executa primeiro o actionPerformed do botão salvar e depois o focuslost do campo data, gravando dados errados. Por uma questão de prioridade, o botão não poderia ser executado antes que terminasse o código do focusLost. Alguém sabe o que está acontecendo?
Grato,
Amir
D
douglaskd
cola o código do evento do botão aqui
A
amirfenix
Douglas, obrigado pela atenção, mas o botão é só um exemplo. Na verdade qualquer componente recebe o foco e pode ser acionado antes de rodar o focuslost. De qq forma aí vai:
Matriculam=newMatricula(txt_datamat.getText(),curso_atual,func_atual,h_atual,alunos_mat,ta_observ.getText());//testa se mudou horário ou professorif(op.equals("altera")&&((m.getProfessor_mat().getCodpessoa()!=mat_atual.getProfessor_mat().getCodpessoa())||(m.getHorario_mat().getCodHorario()!=mat_atual.getHorario_mat().getCodHorario()))){mudar_aulas=true;}if(op=="novo"){inti=JOptionPane.showConfirmDialog(this," Após a confirmação não será possível alterar a data da matrícula e o curso escolhido.\n Deseja prosseguir ?","Confirmar Matrícula",JOptionPane.YES_NO_OPTION);if(i==JOptionPane.YES_OPTION){mat_atual=m;fm.insereMat(mat_atual);mat_atual=fm.navegaMat(4);preencheCampos(mat_atual);JOptionPane.showMessageDialog(this,"Matrícula efetuada com sucesso.");op="";habilitaControles(true);//chamada do método para consolidar aula experimentalconsolidaAulaExperimental();//chamada do método para gerar aulasmatGerarAulas(mat_atual.getDataMatricula());}}if(op=="altera"||op=="reativando"){mat_atual=m;mat_atual.setCodMatricula(Integer.parseInt(txt_codigo.getText()));fm.alteraMat(mat_atual);intcod=mat_atual.getCodMatricula();mat_atual=fm.buscaMat(cod);preencheCampos(mat_atual);//checa existencia dos alunos nas aulasfau.checaIntegridadePresencas(cod,mat_atual.getAlunosAtivos());JOptionPane.showMessageDialog(this,"Alteração efetuada com sucesso.");if(op=="reativando"){matGerarAulas(dataReativacao_temp);}op="";dataReativacao_temp="";habilitaControles(true);}if(op.equals("reativar_excepcional")){JOptionPane.showMessageDialog(this,"Esta matrícula possui alunos ativos. A mesma será reativada.");habilitaControles(true);if(reativaMat()==true){btn_alterarActionPerformed(evt);op="reativando";InformaDatainfdata=newInformaData(mat_atual.getDataMatricula()," reativação:");dataReativacao_temp=infdata.getData();}}}}catch(Exceptionerro){JOptionPane.showMessageDialog(this,"Erro ao gravar matrícula : "+erro);}finally{if(mudar_aulas==true){JOptionPane.showMessageDialog(null,"Esta matrícula teve professor e/ou horário alterados. Clique em OK para atualizar as aulas.");CancelaAulasca=newCancelaAulas();ca.setMatricula(mat_atual.getCodMatricula());ca.setVisible(true);}}}
B
Bruno_M_Gasparotto
Cara, não posso contribuir muito com o assunto, passei só pra ler mesmo, mas posta seus códigos utilizando a tag Code, pra ficar mais legível pro pessoal.
Abraços,
T
thingol
Estranho… eu escrevi um programinha bem bobinho e não vi esse comportamento curioso que você disse (até procurei na Internet para ver se alguém estava reclamando dessa diferença de comportamento e não consegui achar ninguém que reclamasse disso).
Ele indicou que estava executando sempre primeiramente o Focus Lost e depois o Action Performed, não importando se era Java 1.7 ou 1.6.
packageguj;importjava.awt.EventQueue;importjava.awt.event.ActionEvent;importjava.awt.event.ActionListener;importjava.awt.event.FocusAdapter;importjava.awt.event.FocusEvent;importjavax.swing.JButton;importjavax.swing.JFormattedTextField;importjavax.swing.JFrame;importjavax.swing.JPanel;importjavax.swing.border.EmptyBorder;importnet.miginfocom.swing.MigLayout;publicclassTesteDiferencaComportamentoJava6e7extendsJFrame{privateJPanelcontentPane;privateJFormattedTextFieldformattedTextField;privateJButtonbtnNewButton;/** * Launch the application. */publicstaticvoidmain(String[]args){System.out.println("Rodando sob Java "+System.getProperty("java.version"));EventQueue.invokeLater(newRunnable(){publicvoidrun(){try{TesteDiferencaComportamentoJava6e7frame=newTesteDiferencaComportamentoJava6e7();frame.setVisible(true);}catch(Exceptione){e.printStackTrace();}}});}/** * Create the frame. */publicTesteDiferencaComportamentoJava6e7(){setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);setBounds(100,100,450,300);contentPane=newJPanel();contentPane.setBorder(newEmptyBorder(5,5,5,5));setContentPane(contentPane);contentPane.setLayout(newMigLayout("","[grow]","[]"));contentPane.add(getFormattedTextField(),"flowx,cell 0 0,growx");contentPane.add(getBtnNewButton(),"cell 0 0");}privateJFormattedTextFieldgetFormattedTextField(){if(formattedTextField==null){formattedTextField=newJFormattedTextField();formattedTextField.addFocusListener(newFocusAdapter(){@OverridepublicvoidfocusLost(FocusEvente){System.out.println("Focus Lost");}});}returnformattedTextField;}privateJButtongetBtnNewButton(){if(btnNewButton==null){btnNewButton=newJButton("New button");btnNewButton.addActionListener(newActionListener(){publicvoidactionPerformed(ActionEvente){System.out.println("Action Performed");}});}returnbtnNewButton;}}
V
ViniGodoy
Esse é um exemplo de recomendação do fabricante não seguida. Em Swing, não devemos validar coisas no FocusLost ou qualquer outro evento.
Para isso existem classes como Document e InputVerifier.
A
amirfenix
Thingol, eu já tinha visto uma reclamação parecida aqui no GUJ, mas sem solução:
Já tinha também pensado em mudar a validação nos termos que o ViniGodoy falou, mas não me conformo com esse comportamento esquisito do focuslost. É como pegar a garrafa antes de abrir a geladeira. Independente da validação, o focuslost tem que vir primeiro.
Bom, continuo na busca.
Obrigado a todos pela colaboração.
Amir
A
amirfenix
Caro Viny,
Peguei o exemplo da classe InputVerifier do próprio site da Oracle e fiz algumas mudanças. Troquei a JtextField por JFormattedTextField (pra ficar igual ao projeto), e a segunda JTextfield por um botão. O exemplo funciona quando a questão são os eventos de foco, mas se implemento o ActionPerformed do botão, este é executado independentemente da validação. Em suma, deu no mesmo. A validação é executada mas não impede que o botão rode seu código. A validação existe para interromper o processo, senão não adianta de nada . Segue o código:
importjava.awt.*;importjava.util.*;importjava.awt.event.*;importjavax.swing.*;// This program demonstrates the use of the Swing InputVerifier class.// It creates two text fields; the first of the text fields expects the// string "pass" as input, and will allow focus to advance out of it// only after that string is typed in by the user.publicclassVerifierTest2extendsJFrame{publicVerifierTest2(){JFormattedTextFieldtf1=newJFormattedTextField("Type \"pass\" here");getContentPane().add(tf1,BorderLayout.NORTH);tf1.setInputVerifier(newPassVerifier());JButtontf2=newJButton();getContentPane().add(tf2,BorderLayout.SOUTH);/* tf2.addFocusListener(new FocusAdapter() { @Override public void focusGained(FocusEvent e) { JOptionPane.showMessageDialog(null, "ganhou foco"); } }); */tf2.addActionListener(newActionListener(){@OverridepublicvoidactionPerformed(ActionEvente){JOptionPane.showMessageDialog(null,"Action Performed");}});WindowListenerl=newWindowAdapter(){publicvoidwindowClosing(WindowEvente){System.exit(0);}};addWindowListener(l);}classPassVerifierextendsInputVerifier{publicbooleanverify(JComponentinput){JFormattedTextFieldtf=(JFormattedTextField)input;return"pass".equals(tf.getText());}}publicstaticvoidmain(String[]args){Framef=newVerifierTest2();f.pack();f.setVisible(true);}}
Enfim, como o botão executa o ActionPerformed se não poderia receber o foco?
Desde já agradeço a ajuda,
Abraço
Amir
E
entanglement
Você está confundindo “foco” (que é algo essencial para os componentes que têm carets, como um JTextField) com o fato de poder executar um ActionPerformed (um botão pode estar até na ordem de varredura dos tabs, mas um botão não precisa estar focado para funcionar (embora chame o foco para si se ele for clicado).
Impedir o botão de receber o foco não é suficiente.
A
amirfenix
Bom dia a todos. Prossegui com a implementação do InputVerifier, incluindo o método de validação que exibe os JOptionPane com as mensagens de erro. Pra minha surpresa, após o JOptionPane ser executado, o ActionPerformed do botão salvar não é executado, e o foco volta para o campo validado, exatamente como eu queria. O único inconveniente é que o botão cancelar também não é executado, mas basta limpar o campo data pra ignorar a verificação. Esta implementação me atende, mas ainda não sei se é segura. Comentários adicionais são muito bem vindos.