2013-12-09 5 views
0

У меня есть этот небольшой фрагмент кода, который отображает простую панель со списком флажков. Поведение должно быть следующим:JList нужно дважды щелкнуть, чтобы обновить CheckableItem

  • если флажок «[] все» выбран любой другой CheckBox должен быть снят, в противном случае (когда «[] все» флажок не установлен) пользователь может выбрать любое количество флажков.

  • если флажок отличается от «[] все» проверяется то «[] все» флажок должен быть снят

Далеко теперь ничего странного кроме того, что если флажок «[] все» , то пользователь должен нажать два раза друг друга, чтобы отметить его как выбранный. Первый щелчок снимет флажок «[] все», но не проверяет выбранный флажок. Я хотел бы получить оба поведения вместе. Я думаю, что-то пропустил (синхронизации событие, может быть ...)

Вот код (содержится самостоятельно, так что если вы хотите, вы можете запустить его как есть):

import java.awt.*; 
import java.awt.event.*; 
import javax.swing.*; 
import javax.swing.border.EmptyBorder; 

public class CheckListPlot extends JFrame { 

public CheckListPlot() { 
    super("CheckList"); 
    String[] strs = { "a", "b", "c", "d", "e", "f", "g", "h", "i" }; 

    JLabel label = new JLabel("Please, before to start the simulation, choose what species you desire to plot"); 
    Font font = new Font("Tahoma", label.getFont().getStyle(), label.getFont().getSize() - 2); 
    label.setFont(font); 

    JPanel allCheckpanel = new JPanel(new BorderLayout()); 
    allCheckpanel.setBorder(new EmptyBorder(6, 6, 6, 6)); 
    final JCheckBox allCheck = new JCheckBox("all", false); 
    allCheckpanel.add(allCheck, BorderLayout.WEST); 

    JPanel labelPanel = new JPanel(new GridLayout(1, 1)); 
    labelPanel.setBorder(new EmptyBorder(10, 10, 10, 10)); 
    labelPanel.add(label); 

    final JList list = new JList(createData(strs)); 

    list.setCellRenderer(new CheckListRenderer()); 
    list.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); 
    list.setBorder(new EmptyBorder(0, 4, 0, 0)); 

    list.addMouseListener(new MouseAdapter() { 
     public void mouseClicked(MouseEvent e) { 
      int index = list.locationToIndex(e.getPoint()); 
      CheckableItem item = (CheckableItem) list.getModel().getElementAt(index); 
      System.out.println("item " + item.toString() + " is selected before? " + item.isSelected()); 
      item.setSelected(!item.isSelected()); 
      System.out.println("item " + item.toString() + " is selected after ? " + item.isSelected()); 
      Rectangle rect = list.getCellBounds(index, index); 
      list.repaint(rect); 
      if(allCheck.isSelected()){ 
       allCheck.setSelected(false); 

      } 


     } 
    }); 


    JScrollPane sp = new JScrollPane(list); 

    JButton simulateButton = new JButton("simulate"); 
    simulateButton.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent e) { 
      ListModel model = list.getModel(); 
      int n = model.getSize(); 
      for (int i = 0; i < n; i++) { 
       CheckableItem item = (CheckableItem) model.getElementAt(i); 
       if (item.isSelected()) { 
        System.out.println(item.toString()); 


       } 
      } 
     } 
    }); 

    JPanel panel = new JPanel(new GridLayout(1, 1)); 
    panel.add(simulateButton); 

    allCheck.addItemListener(new ItemListener() { 
     public void itemStateChanged(ItemEvent e) { 
      for(int i =0 ; i< list.getModel().getSize(); i++){ 
       ((CheckableItem)list.getModel().getElementAt(i)).setSelected(false); 
       Rectangle rect = list.getCellBounds(i, i); 
       list.repaint(rect); 
      }    


     } 
    }); 

    getContentPane().add(labelPanel, BorderLayout.NORTH); 

    getContentPane().add(allCheckpanel, BorderLayout.NORTH); 
    getContentPane().add(sp, BorderLayout.CENTER); 
    getContentPane().add(panel, BorderLayout.SOUTH); 
} 

private CheckableItem[] createData(String[] strs) { 
    int n = strs.length; 
    CheckableItem[] items = new CheckableItem[n]; 
    for (int i = 0; i < n; i++) { 
     items[i] = new CheckableItem(strs[i]); 
    } 
    return items; 
} 

class CheckableItem { 
    private String str; 

    private boolean isSelected; 

    public CheckableItem(String str) { 
     this.str = str; 
     isSelected = false; 
    } 

    public void setSelected(boolean value) { 
     isSelected = value; 
    } 

    public boolean isSelected() { 
     return isSelected; 
    } 

    public String toString() { 
     return str; 
    } 
} 

class CheckListRenderer extends JCheckBox implements ListCellRenderer { 

    public CheckListRenderer() { 
     setBackground(UIManager.getColor("List.textBackground")); 
     setForeground(UIManager.getColor("List.textForeground")); 
    } 

    public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean hasFocus) { 
     setEnabled(list.isEnabled()); 
     setSelected(((CheckableItem) value).isSelected()); 
     setFont(list.getFont()); 
     setText(value.toString()); 
     return this; 
    } 
} 

public static void main(String args[]) { 
    try { 
     UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel"); 
    } catch (Exception evt) {} 

    CheckListPlot frame = new CheckListPlot(); 
    frame.addWindowListener(new WindowAdapter() { 
     public void windowClosing(WindowEvent e) { 
      System.exit(0); 
     } 
    }); 
    frame.setSize(300, 200); 
    frame.setVisible(true); 
} 
} 
+0

Прочитайте [это] (http://stackoverflow.com/a/17952140/2894369) ответ, у вас есть рекомендации по вашей проблеме. – alex2410

+0

Благодарим вас за ответ; является хорошей альтернативой. – microvo

ответ

0

обновления свой метод добавления ItemListener по всей флажок следующего

allCheck.addItemListener(new ItemListener() { 
    public void itemStateChanged(ItemEvent e) { 
     for(int i =0 ; i< list.getModel().getSize(); i++){ 
      if(e.getStateChange() == ItemEvent.SELECTED) 
      { 
      System.out.println("value"+e.getStateChange()); 
      ((CheckableItem)list.getModel().getElementAt(i)).setSelected(true); 
      } else 
      { 
       ((CheckableItem)list.getModel().getElementAt(i)).setSelected(false); 
      } 
      Rectangle rect = list.getCellBounds(i, i); 
      list.repaint(rect); 
     } 
    } 
}); 
+0

Благодарим вас за ответ, но ваш код, когда я нажимаю «[] все», отмечает каждый другой флажок. Это не ожидаемое поведение, как вы можете прочитать выше – microvo

0

Ok я решил, но я не знаю, почему ... Я пишу здесь решение в надежде, что кто-то может объяснить мне это странное поведение. Я был бы очень рад понять, почему это маленькое изменение решает все.

в основном это изменить достаточное полномочия этого небольшого фрагмент кода:

list.addMouseListener(new MouseAdapter() { 
     public void mouseClicked(MouseEvent e) { 
        // I have made the operation on the JCheckBox first of all 
      if(allCheck.isSelected()){ 
       allCheck.setSelected(false); 
      } 


      int index = list.locationToIndex(e.getPoint()); 
      CheckableItem item = (CheckableItem)  list.getModel().getElementAt(index); 
      System.out.println("item " + item.toString() + " is selected before? " + item.isSelected()); 
      item.setSelected(!item.isSelected()); 
      System.out.println("item " + item.toString() + " is selected after ? " + item.isSelected()); 
      Rectangle rect = list.getCellBounds(index, index); 
      list.repaint(rect); 




     } 
    }); 

Я думаю, что из-за какой-то вопрос синхронизации между классом JCheckBox и классом JList, не так ли? Кажется, что операция JCheckBox (в предыдущем коде) в некотором роде приводит к тому, что JList потерял фокус, поэтому второй щелчок сбрасывает фокус JList.

Смежные вопросы