o meu sistema nao utiliza mouse so teclado e as teclas sao predefinidas… quando eu adiciono o JList na minha tela ele ganha o focu de tudo e os eventos do teclados para de responder… se eu utilizo o setFocusable(false) o sistema roda belezinha porem o meu problema e o seguinte… eu queria utilizar duas teclas para mover entre os itens… tipo Q = sobe, W = desse… eu setei pra que ele ele marcasse os itens pelo jList1.setSelectedIndex(i); isso tmb funciona mais a barra de rolagem nao vai junto tipo se tiver espaço para mostra apenas 5 e tiver 10 itens vc consegue mover entre ele mais vc sempre vai ficar vendo os 5 pq a barra de rolagem nao acompanha os itens… eu queria saber se tem algum tipo de setFocus… ou next()… alguma coisa do tipo pra mover a barra de rolagem junto e sempre mnostrar o item selecionado.
packageguj;importjava.awt.BorderLayout;importjava.awt.FlowLayout;importjava.awt.event.KeyEvent;importjavax.swing.Action;importjavax.swing.DefaultListModel;importjavax.swing.JButton;importjavax.swing.JFrame;importjavax.swing.JList;importjavax.swing.JPanel;importjavax.swing.JScrollPane;importjavax.swing.KeyStroke;importjavax.swing.ListSelectionModel;importjavax.swing.SwingUtilities;publicclassExemploJListextendsJFrame{privatestaticfinallongserialVersionUID=1L;publicstaticvoidmain(String[]args){// TODO Auto-generated method stubSwingUtilities.invokeLater(newRunnable(){publicvoidrun(){ExemploJListthisClass=newExemploJList();thisClass.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);thisClass.setVisible(true);}});}privateJButtonbtnOK=null;privateJPaneljContentPane=null;privateDefaultListModellistModel;privateJListlstList=null;privateJPanelpnlBotoes=null;privateJScrollPanescpList=null;publicExemploJList(){super();initialize();}privateJButtongetBtnOK(){if(btnOK==null){btnOK=newJButton();btnOK.setText("OK");}returnbtnOK;}privateJPanelgetJContentPane(){if(jContentPane==null){jContentPane=newJPanel();jContentPane.setLayout(newBorderLayout());jContentPane.add(getScpList(),BorderLayout.CENTER);jContentPane.add(getPnlBotoes(),BorderLayout.SOUTH);}returnjContentPane;}privateDefaultListModelgetListModel(){if(listModel==null){listModel=newDefaultListModel();for(inti=0;i<100;++i){listModel.addElement(String.format("Elemento %02d",i));}}returnlistModel;}privateJListgetLstList(){if(lstList==null){lstList=newJList();lstList.setModel(getListModel());lstList.setFocusCycleRoot(true);lstList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);lstList.setSelectedIndex(0);// Como exemplo, fiz com que as teclas q e w funcionem como Up e// Down, respectivamente.lstList.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_Q,0),"up");lstList.getActionMap().put("up",(Action)lstList.getActionForKeyStroke(KeyStroke.getKeyStroke(KeyEvent.VK_KP_UP,0)));lstList.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_W,0),"down");lstList.getActionMap().put("down",(Action)lstList.getActionForKeyStroke(KeyStroke.getKeyStroke(KeyEvent.VK_KP_DOWN,0)));}returnlstList;}privateJPanelgetPnlBotoes(){if(pnlBotoes==null){pnlBotoes=newJPanel();pnlBotoes.setLayout(newFlowLayout());pnlBotoes.add(getBtnOK(),null);}returnpnlBotoes;}privateJScrollPanegetScpList(){if(scpList==null){scpList=newJScrollPane();scpList.setViewportView(getLstList());}returnscpList;}privatevoidinitialize(){this.setSize(320,234);this.setContentPane(getJContentPane());this.setTitle("Exemplo de JList");}}
E
entanglement
Note que “setSelectedItem”, conforme você deve ter percebido, não é a mesma coisa que mover com as setas.
Eu simplesmente copiei a mesma ação executada quando se usa a tecla de seta para cima para a tecla “q”.
Exercício - Veja que se você teclar Q com a tecla Shift apertada não vai funcionar (não vai mover a seta). Por que isso ocorre?
E
entanglement
Outra dica: em muitos componentes do Swing, adicionar um KeyListener simplesmente não funciona do jeito que você quer. Muitas vezes você precisa mexer no ActionMap/InputMap (como fiz agora), ou então, em campos de entrada de dados, mexer no Document. No caso de um JComboBox, a situação é mais complicada ainda, e é por isso que é um pouco difícil fazer um AutoComplete que funcione.
E
entanglement
Eu usei uma coisa que normalmente não recomendo, que é um DefaultListModel. Só fiz isso para simplificar o exemplo; normalmente eu usaria um ListModel baseado em um dos Models do GlazedLists ( http://publicobject.com/glazedlists )
L
laurovitor
sim testei o codigo acima ele ate funciona porem eu nao posse deichar o JList com foco e ai q entra o problema…
o codigo tem q funcionar com o …
em estado false.
E
entanglement
OK, não tinha visto que a JList não tinha foco. Então:
packageguj;importjava.awt.BorderLayout;importjava.awt.FlowLayout;importjava.awt.event.ActionEvent;importjava.awt.event.KeyEvent;importjavax.swing.AbstractAction;importjavax.swing.Action;importjavax.swing.DefaultListModel;importjavax.swing.JButton;importjavax.swing.JComponent;importjavax.swing.JFrame;importjavax.swing.JList;importjavax.swing.JPanel;importjavax.swing.JScrollPane;importjavax.swing.KeyStroke;importjavax.swing.ListSelectionModel;importjavax.swing.SwingUtilities;publicclassExemploJListextendsJFrame{privatestaticfinallongserialVersionUID=1L;publicstaticvoidmain(String[]args){// TODO Auto-generated method stubSwingUtilities.invokeLater(newRunnable(){publicvoidrun(){ExemploJListthisClass=newExemploJList();thisClass.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);thisClass.setVisible(true);}});}privateJButtonbtnOK=null;privateJPaneljContentPane=null;privateDefaultListModellistModel;privateJListlstList=null;privateJPanelpnlBotoes=null;privateJScrollPanescpList=null;publicExemploJList(){super();initialize();}privateJButtongetBtnOK(){if(btnOK==null){btnOK=newJButton();btnOK.setText("OK");}returnbtnOK;}privateJPanelgetJContentPane(){if(jContentPane==null){jContentPane=newJPanel();jContentPane.setLayout(newBorderLayout());jContentPane.add(getScpList(),BorderLayout.CENTER);jContentPane.add(getPnlBotoes(),BorderLayout.SOUTH);}returnjContentPane;}privateDefaultListModelgetListModel(){if(listModel==null){listModel=newDefaultListModel();for(inti=0;i<100;++i){listModel.addElement(String.format("Elemento %02d",i));}}returnlistModel;}privateJListgetLstList(){if(lstList==null){lstList=newJList();lstList.setModel(getListModel());lstList.setFocusCycleRoot(true);lstList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);lstList.setSelectedIndex(0);lstList.setFocusable(false);// Como exemplo, fiz com que as teclas q e w funcionem como Up e// Down, respectivamente.lstList.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_Q,0),"up");lstList.getActionMap().put("up",newAbstractAction(){@OverridepublicvoidactionPerformed(ActionEvente){intselIndex=lstList.getSelectedIndex();if(selIndex>0)selIndex--;elseselIndex=0;lstList.setSelectedIndex(selIndex);lstList.ensureIndexIsVisible(selIndex);// aqui o pulo do gato}});lstList.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_W,0),"down");lstList.getActionMap().put("down",newAbstractAction(){@OverridepublicvoidactionPerformed(ActionEvente){intselIndex=lstList.getSelectedIndex();if(selIndex<lstList.getModel().getSize())selIndex++;elseselIndex=lstList.getModel().getSize()-1;lstList.setSelectedIndex(selIndex);lstList.ensureIndexIsVisible(selIndex);// aqui o pulo do gato}});}returnlstList;}privateJPanelgetPnlBotoes(){if(pnlBotoes==null){pnlBotoes=newJPanel();pnlBotoes.setLayout(newFlowLayout());pnlBotoes.add(getBtnOK(),null);}returnpnlBotoes;}privateJScrollPanegetScpList(){if(scpList==null){scpList=newJScrollPane();scpList.setViewportView(getLstList());}returnscpList;}privatevoidinitialize(){this.setSize(320,234);this.setContentPane(getJContentPane());this.setTitle("Exemplo de JList");}}// @jve:decl-index=0:visual-constraint="10,10"
E
entanglement
A janela em si tem de ter o foco (isso é porque janelas sem foco não recebem eventos de teclado). Mas o JList não precisa ter o foco.
E
entanglement
Repare, ao rodar o exemplo, que o foco continua sempre no botão OK, mesmo que se tecle q ou w. Obviamente, se você teclar um espaço, vai ativar o botão OK, como esperado.
L
laurovitor
ok vou implementar este exemplo no meu codigo pra ver se funciona pq eu testei esse exemplo q vc me passo e funciono certinho agora quero ver se vai funcionar no meu codigo…
L
laurovitor
Ok testei aqui deu certinho… muito obrigado pela ajuda… e meio chato ser iniciante e ter q ficar perguntando… mais em breve espera poder estar ajudando os outros aki no forum tmb…
=]
so mais uma duvida tem alguma maneira de centralizar o texto da JList?
T
thingol
No meu “technical debt” está, por exemplo, escrever no meu blog sobre todas as formas de não usar um KeyListener.
Até agora não escrevi, por exemplo, como é que se usa um “try with resources” com um java.sql.Connection.
Como vocês devem ter aprendido na marra, o comportamento de teclas com os componentes do Swing raramente pode ser customizado usando-se um mero KeyListener.