Múltiplas JComboBoxes interagindo entre si(Baixa Performance)

8 respostas
Ironlynx

Fala pessoal!!!
Eu tô com um probleminha aqui:
Tenho uma JComboBox que ao ser selecionada, dispara uma notificação para outras, pegando cada objeto selecionado, e adicionando um dado valor a uma variável em cada uma delas para depois ser adicionado a uma fórmula.Mesmo agendando uma Thread, a performance cai pacas, provavelmente pq quando eu mexo em uma, todas são notificadas.
A minha principal é assim:

String [] uso={"Residencial","Diverso"}; JComboBox usoCombo=new JComboBox(uso); usoCombo.setSelectedIndex(0); usoCombo.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e) { JComboBox cb = (JComboBox)e.getSource(); String selected = (String)cb.getSelectedItem(); if(selected.equals("Residencial")) updateCombos("Residencial"); else if(selected.equals("Diverso")) updateCombos("Diverso"); } });//fim da classe interna de usoCombo
Em update combos eu pego cada uma das comboboxes, pego o valor selecionado e adiciono um valor a uma dada variável para uso posterior em uma fórmula.Uso Java Mustang, mas fica tão lerdo que parece 1.3… :shock:
Alguém já fez algo parecido???

8 Respostas

Ironlynx

Humm… minha explicação ficou meio turva, vou criar uma “primitiva”, para o pessoal entender o problema:
Basicamente seria algo assim:

String [] uso={"Residencial","Diverso"}; JComboBox usoCombo=new JComboBox(uso); usoCombo.setSelectedIndex(0); usoCombo.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e) { JComboBox cb = (JComboBox)e.getSource(); String selected = (String)cb.getSelectedItem(); if(selected.equals("Residencial")) finalidade="R"; else if(selected.equals("Diverso")) finalidade="D"; } });//fim da classe interna de usoCombo

E verificaria em cada Combo dependente(por exemplo):

String[] estrutura={"Concreto","Madeira","Alvenaria","Metálica"};
    	   JComboBox estruturaCombo=new JComboBox(estrutura);
    	          estruturaCombo.setSelectedIndex(0);
    	          estruturaCombo.addActionListener(new ActionListener(){
 			public void actionPerformed(ActionEvent e) {
 				JComboBox cb = (JComboBox)e.getSource();
                String selected = (String)cb.getSelectedItem();
                 if(selected.equals("Concreto")){
                    if(finalidade.equals("R"))
                    	conta_estrutura=25;
                    else if(finalidade.equals("D"))
                    	conta_estrutura=35;	
                 }                 
                 else if(selected.equals("Madeira")){
                    if(finalidade.equals("R"))
                    	conta_estrutura=5;
                    else if(finalidade.equals("D"))
                    	conta_estrutura=19;	
                 }                 	
                  else if(selected.equals("Alvenaria")){
                    if(finalidade.equals("R"))
                    	conta_estrutura=15;
                    else if(finalidade.equals("D"))
                    	conta_estrutura=35;	
                 }                	  
...}

Óbvio que dessa forma que eu postei só seria executado uma única vez(é só para ilustrar), e qualquer mudança na combo “usoCombo”, não alteraria o resultado das demais 7 que dependem dela.

fabim

Seu método é um pouco problemático…

Perceba que vc esta usando STRING como chave pra busca… olha a volta que vc ta dando: vc ta adicionando a String na combo, depois recuperando essa String e:

1 - Fazendo busca por String ( ruim ) ou
2 - Pegando o Id no banco com essa String e depois buscando pelo ID ( ruim tb )

em vez disso, vc poderia usar diretamente o id… como? seu objeto tem um ID certo? em vez de atribuir na combo a descricao, “Residencial”, adicione o OBJETO em si… o objeto possui id, entao vc usaria esse id como chave pra busca…

Finalidade finalidade = (Finalidade) combo.getSelectedItem();

finalidade.getId();

// se bem que qdo vc busca algo, nao deve usar so o Id, passe o objeto todo pra quem vai procurar

pra que vc veja somente a descricao na combo, va na sua classe e sobrescreva o metodo toString();

Ironlynx
<blockquote>Finalidade finalidade = (Finalidade) combo.getSelectedItem();

finalidade.getId();

// se bem que qdo vc busca algo, nao deve usar so o Id, passe o objeto todo pra quem vai procurar </blockquote>

Eu saquei o que vc disse, tanto que  mudei para usar um Model e um Renderer, mas o meu problema, na verdade, está na bidirecionalidade da coisa, ou seja, atualiza um, todos tem que ver(verificar) e atualizar a variável(se necessário na mudança ocorrida em usoCombo).
Ironlynx

2 - Pegando o Id no banco com essa String e depois buscando pelo ID ( ruim tb )

Ah, esqueci de falar o óbvio: Não há banco algum!!! :lol:
Logo nao há impacto de performance no BD!!!
É uma planilha de cálculo cuja única função é fazer cálculos de acordo com as funções imputadas/selecionadas.Não há persistência em BD, e a única coisa que ocorre é salvar os dados calculados em um PDF no final(opcional ao usuário).

ViniGodoy

Não seria o caso de usar um mediator?

Ironlynx

Vini, não pesquei…vc vai criar uma interface notificadora para as demais combos??? consegue dar um exemplo usando 2 combos como exemplo(pode ser as duas q eu postei antes)?
Detalhes que eu não tinha posto:
Quando a tela com as combos for executada, a interação entre elas já foi calculada ao menos uma vez, pois todas as combos começam já selecionadas na primeira posição (só ver o setSelectedIndex(0);
). Mudou uma, muda tudo(irá mudar o valor da variávelcorrespondente, e o valor da fórmula final será imediatamente alterado).

RafaelRio

Eu tenho fugido de observers porque ele prejudica muito a depuração, já que faz com que o fluxo do software fique difícil (impossível?) de acompanhar.

Então, para resolver esse tipo de problema que você está tendo, eu estou utilizando Presentation Model e Data Binding.

No seu caso, se você está tendo problemas de performance e não tem um método lento em particular, pode ser que seu programa esteja dando voltas e voltas: alguém notifica alguém, que notifica alguém, que notifica alguém…

Então, primeiro eu verificaria se tem um método que está lento (acho que você já fez isso). Se o problema for esse, então turbine o método.

Depois, tenta ver se não há várias notificações ocorrendo (agora sim você irá lidar com as desvantagens do observer).

E você pode tentar usar Presentation Model e binding como eu.

Ironlynx
Opa!!!Bom, eu fiz uma solução meia boca que funciona, e não precisa de grande interação: Como os combos já começam na primeira posição, inicializei as variáveis de cada combo(que fazem parte de uma fórmula), e deixei a notificação dessa fórmula como a última coisa a ser feita antes de atualizar o textfield com o produto dessa fórmula, que por sinal é beem simples:
public String retornaCategoria(int estrutura,int revest,int piso,int cobertura,int forro,
                                  int eletrica,int sanitaria){

      int categoria=estrutura+revest+piso+cobertura+forro+eletrica+sanitaria;

          if(categoria&lt=75)
                  return &quot;D&quot;;
          else if(categoria&gt=76&&categoria&lt=84)
                  return &quot;C&quot;;
          else if(categoria&gt=85&&categoria&lt=100)
                  return &quot;B&quot;;
          else
                 return &quot;A&quot;;    

   }//fim do método retornaCategoria()
E sim, eu tinha um método antes dando muitas voltas, fazendo várias notificações, aí já viu né... E meus problamas acabaram!!!O negócio, foi NÂO deixar nas combos, a mudança.Valeu a todos que ajudaram.
Criado 5 de julho de 2007
Ultima resposta 10 de jul. de 2007
Respostas 8
Participantes 4