JList SINGLE_SELECTION

Olá,

Estou setando o modo de seleção para seleção única, mas não está tendo efeito, está correto como estou fazendo abaixo?

lista=new JList();     
        lista.setCellRenderer(new CheckBoxCellRenderer());   
        lista.setListData(opcoesResposta);         
        Font font1 = new Font ("SansSerif", Font.BOLD, 12);   
        lista.setFont(font1);   
        lista.setForeground(Color.darkGray);   
        lista.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);   
        lista.setBackground (Color.blue);   
        lista.setForeground (Color.green);  

Oi,

O SINGLE_SELECTION define que você não poderá selecionar mais de 1 item segurando as teclas CTRL ou SHIFT.

Você está se referindo a seleção por meio do mouse?

Tchauzin!

Na verdade o que eu quero é que permita selecionar apenas uma opção, independente de mouse ou tecla.

obrigado.

Oi,

Apenas mude a ordem:

lista=new JList();     
lista.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);   
        lista.setCellRenderer(new CheckBoxCellRenderer());   
        lista.setListData(opcoesResposta);         
        Font font1 = new Font ("SansSerif", Font.BOLD, 12);   
        lista.setFont(font1);   
        lista.setForeground(Color.darkGray);           
        lista.setBackground (Color.blue);   
        lista.setForeground (Color.green);  

Tchauzin!

Fiz conforme sua dica, mas ainda continua selecionando vários itens :frowning:

Oi,

:frowning:
Que estranho… provavelmente esse setCellRenderer não está deixando a propriedade SINGLE_SELECTION exercer a sua função.

Comente essa linha e veja o que acontece…

Tchauzin!

Exatamente, é este renderizador que está bloqueando o SINGLE_SELECTION, mas quando eu tiro dá erro no código, pq estou usando um JList com Checkbox, vc tem algum exemplo de JList com checkbox em que eu consiga definir o SINGLE_SELECTION ou MULTIPLE?

Oi,

Não lembro qual a fonte disso:

[code]import java.awt.;
import java.awt.event.
;
import javax.swing.;
import javax.swing.border.
;

public class Estudos extends JFrame{
JList lista;

public Estudos() {
super(“A classe JList”);

Container c = getContentPane();
c.setLayout(new FlowLayout(FlowLayout.LEFT));

// Cria a JList
lista = new JList();

// Define o renderizador de células
lista.setCellRenderer(new CheckBoxCellRenderer());

// Define os valores da lista
Object[] cbArray = new Object[4];
cbArray[0] = new JCheckBox("Goiânia");
cbArray[1] = new JCheckBox("Brasília");
cbArray[2] = new JCheckBox("Barra do Garças");
cbArray[3] = new JCheckBox("Curitiba");

// Atribue os itens à lista
lista.setListData(cbArray);

// Define a seleção única para a lista
lista.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

// Aqui nós permitimos que as checkboxes sejam marcadas
// ou desmarcadas com a barra de espaço
lista.addKeyListener(new KeyAdapter(){
  public void keyPressed(KeyEvent e){
    if(e.getKeyCode() == KeyEvent.VK_SPACE){
      int index = lista.getSelectedIndex();
      if(index != -1){
        JCheckBox checkbox = 
          (JCheckBox) lista.getModel().getElementAt(index);
        checkbox.setSelected(!checkbox.isSelected());
        repaint();
      }
    }
  }
});

// Aqui nós permitimos que as checkboxes sejam marcadas
// ou desmarcadas com o mouse
lista.addMouseListener(new MouseAdapter(){
  public void mousePressed(MouseEvent e){
    int index = lista.locationToIndex(e.getPoint());
    if(index != -1){
      JCheckBox checkbox = 
        (JCheckBox) lista.getModel().getElementAt(index);
      checkbox.setSelected(!checkbox.isSelected());
      repaint();
    }
  }
});

// Um botão que permite obter os itens marcados
JButton btn = new JButton("Obter itens marcados");
btn.addActionListener(
  new ActionListener(){
    public void actionPerformed(ActionEvent e){
      String itens = "";

      for(int i = 0; i < lista.getModel().getSize(); i++){
        JCheckBox checkbox = 
            (JCheckBox) lista.getModel().getElementAt(i);
          if(checkbox.isSelected())
            itens += "Item com índice " + i + 
              " está marcado\n";
          else
            itens += "Item com índice " + i + 
              " está desmarcado\n";
      }          

      JOptionPane.showMessageDialog(null, 
        itens);
    }
  }
);

// Adiciona a lista à janela
c.add(new JScrollPane(lista));

// Adiciona o botão à janela
c.add(btn);  

setSize(350, 250);
setVisible(true);

}

public static void main(String args[]){
Estudos app = new Estudos();
app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}

// Classe personalizada que permite que os itens
// da lista sejam exibidos como JCheckBoxes
class CheckBoxCellRenderer implements ListCellRenderer{
Border noFocusBorder = new EmptyBorder(1, 1, 1, 1);

public Component getListCellRendererComponent(
JList list, Object value, int index,
boolean isSelected, boolean cellHasFocus){
JCheckBox checkbox = (JCheckBox) value;
checkbox.setBackground(isSelected ?
list.getSelectionBackground() : list.getBackground());
checkbox.setForeground(isSelected ?
list.getSelectionForeground() : list.getForeground());

checkbox.setEnabled(list.isEnabled());
checkbox.setFont(list.getFont());
checkbox.setFocusPainted(false);

checkbox.setBorderPainted(true);
checkbox.setBorder(isSelected ? UIManager.getBorder(
   "List.focusCellHighlightBorder") : noFocusBorder);

return checkbox;

}
}
[/code]

Mande rodar…

Tchauzin!

Foi exatamente deste exemplo que estou utilizando, execute e verá que a linha que SETA a seleção para SINGLE_SELECTION não funciona, o programa seleciona todas as opções.

Oi,

A tá! Só agora que fui entender o que você queria. Então, o SINGLE_SELECTION não controla os checkbox marcados. E sim a quantidade de linha selecionada na lista.

Então você deverá fazer algo do tipo:

[code] // Aqui nós permitimos que as checkboxes sejam marcadas
// ou desmarcadas com o mouse
lista.addMouseListener(new MouseAdapter(){
public void mousePressed(MouseEvent e){
int index = lista.locationToIndex(e.getPoint());
if(index != -1){

    	boolean tem_marcado = false;
    	
    	for (int i = 0; i < lista.getModel().getSize() && !tem_marcado; i++) {
    		
    		JCheckBox checkbox = 
	        (JCheckBox) lista.getModel().getElementAt(i);
    		tem_marcado = checkbox.isSelected();
    	}
    	
    	if (!tem_marcado) {
    		JCheckBox checkbox = 
		         (JCheckBox) lista.getModel().getElementAt(index);
    		checkbox.setSelected(!checkbox.isSelected());
    	}
      
      repaint();
    }
  }
});[/code]

Alteração no exemplo completo:

[code]import java.awt.;
import java.awt.event.
;
import javax.swing.;
import javax.swing.border.
;

public class Estudos extends JFrame{
JList lista;

public Estudos() {
super(“A classe JList”);

Container c = getContentPane();
c.setLayout(new FlowLayout(FlowLayout.LEFT));

// Cria a JList
lista = new JList();

// Define o renderizador de células
lista.setCellRenderer(new CheckBoxCellRenderer());

// Define os valores da lista
Object[] cbArray = new Object[4];
cbArray[0] = new JCheckBox("Goiânia");
cbArray[1] = new JCheckBox("Brasília");
cbArray[2] = new JCheckBox("Barra do Garças");
cbArray[3] = new JCheckBox("Curitiba");

// Atribue os itens à lista
lista.setListData(cbArray);

// Define a seleção única para a lista
lista.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

// Aqui nós permitimos que as checkboxes sejam marcadas
// ou desmarcadas com a barra de espaço
lista.addKeyListener(new KeyAdapter(){
  public void keyPressed(KeyEvent e){
    if(e.getKeyCode() == KeyEvent.VK_SPACE){
      int index = lista.getSelectedIndex();
      if(index != -1){
        JCheckBox checkbox = 
          (JCheckBox) lista.getModel().getElementAt(index);
        checkbox.setSelected(!checkbox.isSelected());
        repaint();
      }
    }
  }
});

// Aqui nós permitimos que as checkboxes sejam marcadas
// ou desmarcadas com o mouse
lista.addMouseListener(new MouseAdapter(){
  public void mousePressed(MouseEvent e){
    int index = lista.locationToIndex(e.getPoint());
    if(index != -1){
    	
    	boolean tem_marcado = false;
    	
    	for (int i = 0; i < lista.getModel().getSize() && !tem_marcado; i++) {
    		
    		JCheckBox checkbox = 
	        (JCheckBox) lista.getModel().getElementAt(i);
    		tem_marcado = checkbox.isSelected();
    	}
    	
    	if (!tem_marcado) {
    		JCheckBox checkbox = 
		         (JCheckBox) lista.getModel().getElementAt(index);
    		checkbox.setSelected(!checkbox.isSelected());
    	}
      
      repaint();
    }
  }
});

// Um botão que permite obter os itens marcados
JButton btn = new JButton("Obter itens marcados");
btn.addActionListener(
  new ActionListener(){
    public void actionPerformed(ActionEvent e){
      String itens = "";

      for(int i = 0; i < lista.getModel().getSize(); i++){
        JCheckBox checkbox = 
            (JCheckBox) lista.getModel().getElementAt(i);
          if(checkbox.isSelected())
            itens += "Item com índice " + i + 
              " está marcado\n";
          else
            itens += "Item com índice " + i + 
              " está desmarcado\n";
      }          

      JOptionPane.showMessageDialog(null, 
        itens);
    }
  }
);

// Adiciona a lista à janela
c.add(new JScrollPane(lista));

// Adiciona o botão à janela
c.add(btn);  

setSize(350, 250);
setVisible(true);

}

public static void main(String args[]){
Estudos app = new Estudos();
app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}

// Classe personalizada que permite que os itens
// da lista sejam exibidos como JCheckBoxes
class CheckBoxCellRenderer implements ListCellRenderer{
Border noFocusBorder = new EmptyBorder(1, 1, 1, 1);

public Component getListCellRendererComponent(
JList list, Object value, int index,
boolean isSelected, boolean cellHasFocus){
JCheckBox checkbox = (JCheckBox) value;
checkbox.setBackground(isSelected ?
list.getSelectionBackground() : list.getBackground());
checkbox.setForeground(isSelected ?
list.getSelectionForeground() : list.getForeground());

checkbox.setEnabled(list.isEnabled());
checkbox.setFont(list.getFont());
checkbox.setFocusPainted(false);

checkbox.setBorderPainted(true);
checkbox.setBorder(isSelected ? UIManager.getBorder(
   "List.focusCellHighlightBorder") : noFocusBorder);

return checkbox;

}
}[/code]

Tchauzin!

Perfeito lina,

Isso mesmo, agora ele seleciona penas um item, apesar de não tirar a selecao se quiser, ele seleciona e fica, mas não quero ficar te azucrinando.

Se não se zangar peço humildemente como iniciante, agora que a multipla seleção foi resolvida, existe uma forma de eu poder informar:

Quando posso deixar multipla selecao e quando posso deixar unica selecao e no caso da multipla selecao eu poder definir serão no maximo 3 selecoes por exemplo?

Sei que o objetivo aqui não é dar o peixe e sim ensinar a pescar, eu programo em outras linguagens procedurais ultrapassadas e estou vendo quanto tempo perdi em não ter conhecido java antes e este exemplo se ficar resolvido da forma que estou pedindo vai me ajudar muito, pq em quase todos o programas que precisarei fazer terei que ter este controle de:
SIMPLES SELECAO, MULTIPLA SELECAO (ESCOLHER QUANTAS SELECOES).

Muito obrigado.

Oi,

[quote=lsmarco]Perfeito lina,

Isso mesmo, agora ele seleciona penas um item, apesar de não tirar a selecao se quiser, ele seleciona e fica, mas não quero ficar te azucrinando. [/quote]

Isso se resolveria assim:

[code]
lista.addMouseListener(new MouseAdapter(){
public void mousePressed(MouseEvent e){
int index = lista.locationToIndex(e.getPoint());
if(index != -1){

    	boolean tem_marcado = false;
    	int index_selecionado = 0;
    	
    	for (int i = 0; i < lista.getModel().getSize() && !tem_marcado; i++) {
    		
    		JCheckBox checkbox = 
	        (JCheckBox) lista.getModel().getElementAt(i);
    		tem_marcado = checkbox.isSelected();
    		index_selecionado = i;
    	}
    	
    	if (!tem_marcado || tem_marcado && index_selecionado == index) {
    		JCheckBox checkbox = 
		         (JCheckBox) lista.getModel().getElementAt(index);
    		checkbox.setSelected(!checkbox.isSelected());
    	}
      
      repaint();
    }
  }
});[/code]

O restante deve-se pensar em colocar uma legenda acima da lista,
indicando a quantidade maxima que o usuário poderá selecionar.

A partir dai, é um simples controle com variaveis inteiras…

Tchauzin!

Perfelito Lina,

Obrigado por compartilhar seu conhecimento, sei quanto isso é importante, e pretendo pode ajudar também quando adquirir experiência.

Só pra finalizar:
Neste nosso exemplo você teve que implementar uma forma de fazer a seleção simples funcionar ao invés de utilizar o set.SINGLE_SELECTION, então acredito que também não poderei RENOVAR os items simplesmente com um comando do tipo:

listaElementos.setModel(array novos elementos);

Pra esclarecer melhor, estou fazendo esta última pergunta deste caso pelo seguinte:
Pretendo desenvolver um software que mostre um questionario na tela, sendo que cada pergunta quando eu apertar por exemplo um botão “PROXIMA PERGUNTA” ele teria que renovar os elementos.

desde já agradeço.

[quote=lsmarco]Perfelito Lina,

Obrigado por compartilhar seu conhecimento, sei quanto isso é importante, e pretendo pode ajudar também quando adquirir experiência.

Só pra finalizar:
Neste nosso exemplo você teve que implementar uma forma de fazer a seleção simples funcionar ao invés de utilizar o set.SINGLE_SELECTION, então acredito que também não poderei RENOVAR os items simplesmente com um comando do tipo:

listaElementos.setModel(array novos elementos);

Pra esclarecer melhor, estou fazendo esta última pergunta deste caso pelo seguinte:
Pretendo desenvolver um software que mostre um questionario na tela, sendo que cada pergunta quando eu apertar por exemplo um botão “PROXIMA PERGUNTA” ele teria que renovar os elementos.

desde já agradeço.[/quote]

Oi,

Realmente… Se for dessa maneira teria que usar varias JList e para cada uma delas implementar o mouseListener.
No caso, teriamos que pensar em uma outra solução. Ou melhor, uma solução mais adequada para a sua situação (Analise de Projeto Orientado a Objeto).

Vou tentar pensar em algo, depois postarei…

Tchauzin!

Ok lina,

Ficarei no aguardo, e mais uma vez Obrigado!

Oi,

Tenho uma solução.

Você cria uma variavel “global” dessa forma:

MouseListener io_mouse_list_event = null;

Na ação do seu botão <Próximo>, você implementa o seu MouseListener para cada situação:

[code]
Action
io_ie_proximo = new AbstractAction()
{
public void actionPerformed(ActionEvent evt)
{
int index = lista.locationToIndex(e.getPoint());

      // Claro nesse ponto vc já sabe se a lista vai poder selecionar 1 ou mais itens.				
      if (selection == 1) {
			
           if(index != -1){
					        	
                boolean tem_marcado = false;
                int index_selecionado = 0;
					        	
                for (int i = 0; i < lista.getModel().getSize() && !tem_marcado; i++) {
					        		
                     JCheckBox checkbox = (JCheckBox) lista.getModel().getElementAt(i);
                     tem_marcado = checkbox.isSelected();
                     index_selecionado = i;
                }
			        	
                if (!tem_marcado || tem_marcado && index_selecionado == index) {
                
                     JCheckBox checkbox = 
                     (JCheckBox) lista.getModel().getElementAt(index);
                     checkbox.setSelected(!checkbox.isSelected());
                }
           }
      }
      else if (selection == 3) {
						
           // FAZ A OUTRA ACAO.
						
      }
 }

};[/code]

E depois adiciona esse vento na sua lista:

lista.addMouseListener(io_mouse_list_event);

Tchauzin!

Hum. Ok, vou seguir sua instrução. Obrigado mesmo.

Isso resolve a alternancia entre eu poder ter uma pergunta que selecione uma resposta e outra pergunta que selecione mais de uma resposta. blz, agora só tem a questão da mudança dos elementos, estou tentando fazer ele trocar os elementos neste codigo, já consegui num outro com um JList normal se checkboxes usando o SetModel, mas neste exemplo que estamos utilizando náo funciona.

1.Pergunta
opcao 1="amarelo"
opcao 2=“verde”

2.Pergunta
opcao1="Azul"
opcao2="branco"
opcao3=“cinza”

Resolvido, fiz umas modificações e já está acontecendo da forma que eu queria, apenas alguns detalhes agora que preciso implementar.

Valeu!!!

Olá Lina ou alguém on-line que possa ajudar,

Já consegui atualizar a lista conforme passar de uma pergunta pra outra, agora só está faltando uma última coisa que não consegui resolver pela minha inexperiência.
Você fez umas modificações no código abaixo que permite que eu marque/desmarque apenas uma opção, exatamente como eu queria, mas eu precisaria também optar em selecionar apenas uma opção ou mais sendo que estas “mais de uma” eu pudesse limitar, tipo apenas 6 podem ser escolhidas.
Sua instrução foi que eu criasse variáveis simples de controle, mas não consegui, se você ou alguém por gentiliza pudesse me mostrar como fazer isso, mais uma vez ficarei grato.

lista.addMouseListener(new MouseAdapter(){   
	        public void mousePressed(MouseEvent e){   
	          int index = lista.locationToIndex(e.getPoint());   
	          if(index != -1){   
	                 
	              boolean tem_marcado = false;   
	              int index_selecionado = 0;   
	                 
	              for (int i = 0; i < lista.getModel().getSize() && !tem_marcado; i++) {   
	                     
	                  JCheckBox checkbox =   
	                  (JCheckBox) lista.getModel().getElementAt(i);   
	                  tem_marcado = checkbox.isSelected();   
	                  index_selecionado = i;    
	              }   
	                 
	              if (!tem_marcado || tem_marcado && index_selecionado == index) {   
	                  JCheckBox checkbox =   
	                       (JCheckBox) lista.getModel().getElementAt(index);   
	                  checkbox.setSelected(!checkbox.isSelected());   
	              }   
	               
	            repaint();   
	          }   
	        }   
	      });