ScrollBar do JCombo

17 respostas
G

Oi Pessoal tudo bem?
Estou postando a mesma pergunta de algumas semanas atrás, peço desculpas, mas eh que infelismente ou felismente tenho que descobrir isto…
Algumas pessoas já sabem o meu problema, e para quem não sabe, eu desenvolvi uma classe combo que funciona de uma maneira dinâmica/inteligente fazendo cargas parciais de dados no combo, dados estes carregados do banco de dados. Ela está funcionando perfeitamente, só estaria faltando fazer a carga pelo scrollbar tambem… e por isso minha pergunta:

Como faço para adicionar um listener no jscrollbar imbutido no jComboBox?

se alguém puder me dar alguma idéia ou sugestão agradeço!!!

Gustavo Alvim.

17 Respostas

dukejeffrie

Pergunta pra Patrícia se funcionou adicionar um AdjustmentListener.

Pegar o scrollbar vc sabe, né?? Deve ter algum método no JComboBox.

Eu tenho uma dúvida… vc tentou mudar o BoundedRangeModel que está associado ao JScrollBar?? Quem sabe reimplementando o model vc não precise pegar cliques, e tal… tudo funciona automaticamente…

boa sorte!!1

G

DukeJeffrie, O que eu preciso saber eh justamente isto… pegar o scroolbar imbutido no combo… o combo não me oferece esta opcao…
e uma vez feito isto, eu conseguir trabalhar com as propriedades do scrool e até mesmo utilizar o adjustmentListener que vc mensionou…
complicado…

Gustavo.

dukejeffrie

Cara, que furada!!:shock:
Não tem nenhum jeito simples de pegar o JScrollbar do combo box!! Nem olhei de tanta certeza que eu tinha…

Eu tive uma idéia que pode não resolver, mas vai te dar um caminho pra pesquisar. Existe a classe DefaultComboBoxModel que vc pode usar pra mudar como o ComboBox acessa sua lista.

Ou seja, vc provavelmente tem uma classe que consegue dizer em qual “janela” do seu ResultSet vc está dada uma posição nessa janela. Vamos supor que a sua lista tem 10 mil itens, e cada janela contém 100 itens, então o item 456 está na janela “401-500”, certo?

Vc pode fazer uma subclasse do DefaultComboModel em que vc reimplementa o size() para devolver 10 mil, e o getElementAt() pra descobrir se vc tá na janela certa, mudar de janela se precisar, e pegar o item certo.

Desse jeito, vc só mexe no código que interessa: o do model. Eu briguei bastante com vc na outra thread pq eu cismava que vc estava gastando energia à toa. A Patrícia tb desistiu de postar. Mas eu sou mais teimoso que todos vcs juntos e vou sempre dizer que não precisa pegar esse evento do mouse no scroll bar pra fazer isso, pq vc tá num modelo MVC. :twisted:

Mas, do fundo do coração, torço pra vc conseguir fazer seu loading gradual. Boa sorte!!!

G

Duke, muito obrigado pela ajuda que vc tem me dado e também dado a Patricia, que por ventura trabalha comigo, acho que vc nao sabia… hehe… por isso estamos tentando realizar um loading parecido (idéia do chefe)… ela disse para falar para vc que esta um pouco ocupada mas não desistiu do problema, logo ira postar alguma coisa… mas é isso ai, vou tentar fazer o que vc falou, foi uma otima dica, se der certo show de bola …

Valeu… e se dentro do possivel vc puder me ajudar eu agradeço, pois ando ainda apanhando do java…

Gustavo Alvim.

dukejeffrie

Meu caro galvim, vc não está apanhando do Java. O problema é que vc tem na sua mão uma API gigantesca com alguns anos de reformulações.

Quem sabe eu escrevo algum artigo/tutorial/etc aqui sobre a relação entre AWT, Swing e JavaBeans. É bem interessante e vou ter uma desculpa pra aprender isso direito. :slight_smile:

Mas essa regra que eu venho usando há algum tempo serve sempre: “se parece muito difícil de fazer, tente outra abordagem”. No Swing não tem nada faltando, vc só precisa fazer algumas customizações. Entender o MVC também faz diferença: 80% das vezes vc vai usar os widgets de sempre pra mostrar seus dados de um jeito estranho, isto é, vai mexer no model. Outros 15% (essa estatística é inventada, tá??), vc vai mudar cores e layout, ou seja, o View. Precisar mexer no Controller é raríssimo.

abraço!

G

Fala ai Galera,

Ééé…, ainda não consegui fazer um combo com carga parcial de dados… tirei uma pequena férias, voltei a trabalhar ontem… gostaria que vcs continuassem a me ajudar pois estou quase conseguindo…

Dukejeffrie, vc deu uma dica boa…, eu fiz aquela subclasse da DefaultComboBoxModel e reimplementei os métodos getSize e o getElementAt, … para o getSize deu certo, eu mandei retornar o número de itens do meu banco de dados, mais com o getElementAt não obtive muito sucesso, quando clico na seta do scrool para descer ou subir ele entra neste método fazendo com que eu consiga pegar qual o index, mas tem um problema…
A idéia seria fazer uma verificação dentro deste método (getElementAt) para saber se ele esta no ultimo item carregado (ex.: se eu estou carregando de 100 em 100, verifico se ele chegou no index 99), tranquilo, mando carregar mais 100, mas o problema é que ele entra outras vezes neste método, por exemplo quando o componente jComboBox é carregado (quando rodo o programa) e também quando estou navegando com as setas Up e Down do teclado, e como isso ocorre vc já imaginou o que irá acontecer nao? … ele irá fazer cargas em momentos errados…

Agora não sei se gasto tempo com isso ou parto para uma outra solução.

Duke, se tiver outra dica ou se alguém também puder me ajudar eu agradeco…

Gustavo Alvim.

anjomal

A GALERA DAQUI, SABE SE TEM MEIO DE IMPLEMENTAR MAIS DE UMA COLUNA EM UM JComboBox ??? Fazer um ComboBox que Mostre por exemplo o Codigo e o Nome do Cliente ?^

Valew

dukejeffrie

Sempre tem. Precisa ver quanto vc quer gastar de energia nisso.

O mais lógico é usar a única coluna do JComboBox pra mostrar tudo o que vc quer mostrar. Se vc quer mostrar o código e o nome do cliente no JComboBox, vc pode implementar uma classe assim:

public class ComboClienteItem {
   private int codigo;
   private String nome;

   // ... acessores, construtor, quanto mais JavaBean melhor.

   public String toString() {
      return codigo + " - " + nome;
   }
}

Pronto, vc pode adicionar esses elementos diretamente ao JComboBox, que ele vai mostrá-los bonitinho. Quando vc precisar do código, vc pode fazer assim:

// vamos supor que seu combo box chama-se jComboCliente:
   ComboClienteItem item = (ComboClienteItem) jComboCliente.getSelectedItem();
   metodoQueFazTudo(item);

Sei lá… isso aí serve?

aquelão!!

anjomal

Bom galera deixa eu ser mais claro !!! eu desenvolvi uma classe em C++ que era um COMBO+GRID ele mostrava os dados em colunas tipo CODIGO|CLIENTE e o usuario selecionava a linha adicionar tipo assim uma string que concatena o codigo + nome não era bem oque eu queria … :lol: queria um COMBO que tivesse multiplas colunas e que me retornasse um objeto do tipo array contendo os elementos selecionados alguem ja fez isso em JAVA ? pois do modo que eu estou falando alem de ficar mais bonito eu posso ter varios elementos no Combo e retornalos sem precisar de ficar manipulando strings para desconcatenar.

galera falow !!!

PRA QUE JANELAS SE EU POSSO VIVER SEM PAREDES !!!
SEJA LIVRE USE LINUX !!!

G

Mas e ai …

alguém tem uma solução para o meu problema???

Gustavo Alvim

dukejeffrie

Fala, Galvim…

A Patrícia me escreveu:

Pra ser sincero não entendi muito bem não… :slight_smile:

A idéia que eu tinha dado pro Galvim antes foi essa mesma que ele falou: diz pro Scroll que tem 10 mil itens, mas só carrega do banco os primeiros 200.

O que eu ia sugerir agora que eu to entendendo melhor seu objetivo é fazer uma “janela de dados”, que é assim:

  1. Vc tem o índice do começo da janela, digamos, inicio.
  2. Vc tem o tamanho da janela, digamos, tamanho.
  3. O view acha que vc só tem tamanho elementos (no exemplo 200), pq quando ele chama getSize() vc só devolve o tamando da janela.
  4. Quando vc usa o getElementAt(), vc mapeia o valor pra aquilo que vc quer, que no caso é um código mais ou menos assim:
public Object getElementAt(int index) {
    return databaseModel.getElement(inicio + index);
  }

Isso pq quem chama o getElementAt é a parte de visualização do JComboBox. Mas e pra mover a janela? Na hora que disparar o seu gatilho (sei lá como vcs fizeram), vc desloca a janela de dados:

protected void moveFrente() {
      inicio = inicio + tamanho;
   }

   protected void moveTras() {
      inicio = inicio - tamanho;
   }

É lógico que vc vai ter que fazer uns ajustes no tamanho da janela quando o número de itens no banco não for suficiente pra preencher todos (por exemplo, se vc divide a lista de 1240 itens de 200 em 200, os últimos 40 itens vão aparecer isolados).

Acho que não resolvi o problema, mas vcs podem ter umas idéias boas a partir disso…

tudo de bom!!

G

Duke, como disse na minha penultima mensagem…, o combobox faz com que ele entre neste metodo (getElementAT) em momentos que não me interessa, entao nao vai ter como mandar carregar mais itens através deste método…

Só para lembrar, eu estou querendo fazer um esquema no qual simule um mouseListener do scroolbar do combo, que na verdade “nao existe”. blz né?

Eu fiz vários teste interseptando o getElementAt mas “ACHO” que não da Duke… cara não aguento mais mexer com isto, e o pior… eu tenho que fazer isto … da vontade de mandar um email para sun para fazer um listener deste.

por enquanto vou continuar tentando…
Duke, vc que tem mais experiencia e é claro se vc tiver um tempo, por favor faz um teste … insere um combo normal, muda o getsize para retornar 10 mil por exemplo, e tenta fazer ele funcionar da seguinte maneira… quando vc for clicando na seta do scrool para baixo, eu quero que de 200 em duzentos clicks, ou seja quando chegar no index “199”, “299” vai imprimindo um hello na tela… hehe…
se vc conseguir blz … é somente isso que eu quero…

Valeu! muito obrigado…

Gustavo ALvim

dukejeffrie

Putz, cara… tô muito curioso pra saber como faz isso… : )))

Mas eu tb não tenho a menor idéia de como chegar lá!!

Durante o dia, eu normalmente to no trabalho, e não to nem fazendo interface no momento… mas se eu tiver um tempinho, eu tento descobrir, ok??

Se vc aprender antes, posta aqui no fórum pra gente ver!!! 8)

Aquelão!!

G

Beleza, eu agradeço novamente pela ajuda, vc colaborou bastante.

Pena que eu tenho que dar uma posição para meu chefe até amanha… he

Até mais

Gustavo

G

O Duke, eu achei a classe que se encontra os listeners no qual o combo trabalha, a basicComboPopup, lá tem o método createmouseListener() dentre outros, mas neste caso como faço para sobreescrever estes métodos, naquele caso do DefaultComboModel foi simples … era só utilizar o método setModel(), mas e neste caso, vc sabe?
…eu crio uma subclasse da basicComboPopup, implemento o que quero e depois?

Gustavo.[/url]

dukejeffrie

Ae Gustavo, essa classe é do PLAF.

Quer dizer que a intenção dela é permitir trocar o Look And Feel de Popups genéricos, como JComboBoxes e JPopupMenus. Por isso vc não consegue acessar muita coisa de lá mesmo… : )

Tive lendo de novo o ComboBoxModel, confirma pra mim se vc tá com essas propriedades valendo:

  1. getSize() devolve o tamanho da sua janela (200);
  2. getElementAt(index) devolve o elemento relativo (top + index);

Vc precisa de 2 camadas: um model-swing e um model-model. Num deles, vc obedece às exigências do swing. no outro, vc faz a paginação. por isso o metodo acima seria assim:

public Object getElementAt(int index) {
  return innerModel.getElementAt(top + index);
}

No seu innerModel, vc faz o que vc fez antes e não deu certo, tomando cuidado pra mudar o “top” conforme necessário. Acho que funciona. Daí vc vai ter 200 caras visíveis, mais uns 100 carregados no inner e o resto no banco! Quando vc pedir um cara dentro da borda, o innerModel faz o seguinte:

public Object getElementAt(int index) {
  if (index < teto) {
    carregaAnteriores();
  }
  return elements.get(index - teto);
}

protected void carregaAnteriores() {
  elements.delete(MEIA_JANELA, elements.size());
  elements.addAll(0, carregaDoBanco(teto - MEIA_JANELA, MEIA_JANELA));
  teto -= MEIA_JANELA;
}

Na verdade, vc vai precisar não só te um teto, mas de 4 indices no seu innerModel:

  • zero: 0
  • top: zero + MEIA_JANELA;
  • bottom: top + MEIA_JANELA * 2;
  • end: <tamanho do resultset>

MEIA_JANELA é uma constante que define metade da sua janela.

Será que eu viajei demais??

Abração!!

G

O Duke valeu, mas eu acho que pelo getElementAt não tem como fazer, pois o combobox utiliza muito este método, ele não é só utilizado quando clico no scroll, em outros momentos ele tb é chamado…
…eu estou estudando uma forma de pegar o scroll do combo naquela classe que te falei, a basic combo popup, tentando adicionar um listener para ele, mais não esta fácil, hehe…

Até mais…

Criado 11 de dezembro de 2002
Ultima resposta 13 de jan. de 2003
Respostas 17
Participantes 3