JList getSelectionValue在清除后返回NULL

问题描述:

我有2个JLists,其中我只想选择一个项目。 主类:JList getSelectionValue在清除后返回NULL

public class Main { 

    public static void main(String[] args) { 

     new Staff("John", "D", 123456); 
     new Staff("Bob", "X", 123455); 
     Staff.lookup("John","D").setActive(true); 
     Staff.lookup("Bob","X").setActive(true); 
     new Staff("Jerry","Smith",384938); 
     new Staff("Bob","Hope",834802); 

     new InstructorGUI(1); 



    } 

} 

职员类别:

import java.util.ArrayList; 
import java.util.List; 


public class Staff{ 

    private String fName; 
    private String lName; 
    private int emtID; 
    public static List<Staff> staffIndex = new ArrayList<>(); 
    public static ArrayList<Staff> activeStaffIndex = new ArrayList<>(); 

    Staff(String fName, String lName, int NJEMS) { 
     this.fName = fName; 
     this.lName = lName; 
     staffIndex.add(this); 
     emtID = NJEMS; 
    } 

    //Getters 
    public int getEmtID() { 
     return emtID; 
    } 
    public String getFirstName() {return fName; } 
    public String getLastName() {return lName; } 

    @Override 
    public String toString() { 
     return String.format("%s, %s", lName, fName); 
    } 

    //Lookups 

    public static Staff lookup(String fName, String lName) { 
     for (Staff s : staffIndex) { 
      if (s.getFirstName().equalsIgnoreCase(fName) && s.getLastName().equalsIgnoreCase(lName)) { 
       return s; 
      } 
     } 
     return null; 
    } 

    //Setters 
    public void setEmtID(int NJEMS) { 
     emtID = NJEMS; 
    } 
    public void setFirstName(String s) { 
     fName = s; 
    } 
    public void setLastName(String s) { 
     lName = s; 
    } 

    //Removers 
    public static void removeStaff(Staff s) { 
     staffIndex.remove(s); 
     activeStaffIndex.remove(s); 
    } 

    //Utilities 
    public boolean isActive() { 
     if(activeStaffIndex.contains(this)) { 
      return true; 
     } else { 
      return false; 
     } 
    } 
    public void setActive(Boolean b) { 
     if (b) { 
      if (!activeStaffIndex.contains(this)) { 
       activeStaffIndex.add(this); 
      } 
     } else { 
      if (activeStaffIndex.contains(this)) { 
       activeStaffIndex.remove(this); 
      } 
     } 
    } 

} 

InstructorGUI类别:

import javax.swing.*; 
import java.awt.*; 
import java.util.ArrayList; 
import java.util.HashSet; 

public class InstructorGUI extends JFrame { 

    private static HashSet<InstructorGUI> instructorGUIIndex = new HashSet<>(); 
    private int identifier; 

    private JList<Object> listSelected, selectedInstructors, unSelectedInstructors; 

    public InstructorGUI(int id) { 
     super("Instructor Editor"); 
     setSize(550, 250); 
     setDefaultCloseOperation(DISPOSE_ON_CLOSE); 

     identifier = id; 

     boolean b = false; 

     for (InstructorGUI i : instructorGUIIndex) { 
      if (i.getIdentifier() == 1) { 
       b = true; 
      } 
     } 

     if (b) { 
      InstructorGUI.lookup(1).dispose(); 
      instructorGUIIndex.remove(InstructorGUI.lookup(1)); 
     } 

     instructorGUIIndex.add(this); 

     JPanel container = new JPanel(); 
     JPanel middle = new JPanel(); 
     JPanel inputPanel = new JPanel(); 
     JPanel topButtons = new JPanel(); 
     JPanel left = new JPanel(); 
     JPanel centerButtons = new JPanel(); 
     JPanel right = new JPanel(); 
     JPanel footer = new JPanel(); 

     container.setLayout(new BoxLayout(container, BoxLayout.Y_AXIS)); 
     middle.setLayout(new BoxLayout(middle, BoxLayout.X_AXIS)); 
     inputPanel.setLayout(new FlowLayout()); 
     topButtons.setLayout(new FlowLayout()); 
     left.setLayout(new FlowLayout()); 
     centerButtons.setLayout(new BoxLayout(centerButtons, BoxLayout.Y_AXIS)); 
     right.setLayout(new FlowLayout()); 
     footer.setLayout(new FlowLayout()); 

     JLabel lNameLabel = new JLabel("Last"); 
     JLabel fNameLabel = new JLabel("First"); 
     JLabel emsIdLabel = new JLabel("EMS ID"); 

     JTextField lNameField = new JTextField(10); 
     JTextField fNameField = new JTextField(10); 
     JTextField emsIdField = new JTextField(10); 

     selectedInstructors = new JList<>(); 
     unSelectedInstructors = new JList<>(); 


     JButton addInstructor = new JButton("Add"); 
     JButton editInstructor = new JButton("Edit"); 
     JButton removeInstructor = new JButton("Remove"); 

     JButton selectInstructor = new JButton("<-"); 
     JButton unSelectInstructor = new JButton("->"); 
     JButton selectAllInstructors = new JButton("<<--"); 
     JButton unSelectAllInstructors = new JButton("-->>"); 

     inputPanel.add(lNameLabel); 
     inputPanel.add(lNameField); 
     inputPanel.add(fNameLabel); 
     inputPanel.add(fNameField); 
     inputPanel.add(emsIdLabel); 
     inputPanel.add(emsIdField); 

     topButtons.add(addInstructor); 
     topButtons.add(editInstructor); 
     topButtons.add(removeInstructor); 

     left.add(selectedInstructors); 

     centerButtons.add(selectAllInstructors); 
     centerButtons.add(selectInstructor); 
     centerButtons.add(unSelectInstructor); 
     centerButtons.add(unSelectAllInstructors); 

     right.add(unSelectedInstructors); 

     footer.add(new JLabel("")); 

     JScrollPane x = new JScrollPane(selectedInstructors); 
     JScrollPane y = new JScrollPane(unSelectedInstructors); 

     x.setPreferredSize(new Dimension(100, 200)); 
     y.setPreferredSize(new Dimension(100, 200)); 

     middle.add(new JLabel("")); 
     middle.add(x); 
     middle.add(centerButtons); 
     middle.add(y); 
     middle.add(new JLabel("")); 

     container.add(inputPanel); 
     container.add(topButtons); 
     container.add(middle); 
     container.add(footer); 

     update(); 

     selectedInstructors.addListSelectionListener(e -> { 
      unSelectedInstructors.clearSelection(); 
      if(selectedInstructors.getSelectedValue() != null) { 
       Staff s = Staff.lookup(selectedInstructors.getSelectedValue().toString().split(", ")[1], selectedInstructors.getSelectedValue().toString().split(", ")[0]); 
       lNameField.setText(s.getLastName()); 
       fNameField.setText(s.getFirstName()); 
       emsIdField.setText(String.format("%s", s.getEmtID())); 
       listSelected = selectedInstructors; 
      } 
     }); 
     unSelectedInstructors.addListSelectionListener(e -> { 
      selectedInstructors.clearSelection(); 
      if (unSelectedInstructors.getSelectedValue() != null) { 
       Staff s = Staff.lookup(unSelectedInstructors.getSelectedValue().toString().split(", ")[1], unSelectedInstructors.getSelectedValue().toString().split(", ")[0]); 
       lNameField.setText(s.getLastName()); 
       fNameField.setText(s.getFirstName()); 
       emsIdField.setText(String.format("%s", s.getEmtID())); 
       listSelected = unSelectedInstructors; 
      } 
     }); 

     setContentPane(container); 
     setVisible(true); 
     addInstructor.addActionListener(e -> { 
      if(lNameField.getText().equalsIgnoreCase("") || fNameField.getText().equalsIgnoreCase("") || emsIdField.getText().equalsIgnoreCase("")) { 
       return; 
      } 
      if(Integer.parseInt(emsIdField.getText()) < 300000 || Integer.parseInt(emsIdField.getText()) > 900000) { 
       JOptionPane.showMessageDialog(null,"Please choose an EMS ID between 300000 and 900000."); 
       return; 
      } 
      for(Staff s : Staff.staffIndex) { 
       if(Integer.parseInt(emsIdField.getText()) == s.getEmtID()) { 
        JOptionPane.showMessageDialog(null, "EMS ID already taken."); 
        return; 
       } 
      } 
      new Staff(fNameField.getText(),lNameField.getText(),Integer.parseInt(emsIdField.getText())); 
      update(); 
     }); 
     editInstructor.addActionListener(e -> { 
      if(lNameField.getText().equalsIgnoreCase("") || fNameField.getText().equalsIgnoreCase("") || emsIdField.getText().equalsIgnoreCase("")) { 
       return; 
      } 
      if(Integer.parseInt(emsIdField.getText()) < 300000 || Integer.parseInt(emsIdField.getText()) > 900000) { 
       JOptionPane.showMessageDialog(null,"Please choose an EMS ID between 300000 and 900000."); 
       return; 
      } 
      for(Staff s : Staff.staffIndex) { 
       if(Integer.parseInt(emsIdField.getText()) == s.getEmtID()) { 
        JOptionPane.showMessageDialog(null, "EMS ID already taken."); 
        return; 
       } 
      } 
      Staff s = Staff.lookup(listSelected.getSelectedValue().toString().split(", ")[1],listSelected.getSelectedValue().toString().split(", ")[0]); 
      if(!s.getFirstName().equalsIgnoreCase(fNameField.getText()) || !s.getLastName().equalsIgnoreCase(lNameField.getText()) || s.getEmtID() != Integer.parseInt(emsIdField.getText())) { 
       s.setFirstName(fNameField.getText()); 
       s.setLastName(lNameField.getText()); 
       s.setEmtID(Integer.parseInt(emsIdField.getText())); 
       update(); 
      } 
     }); 
     removeInstructor.addActionListener(e -> { 
      if(listSelected.getSelectedValue() != null) { 
       Staff s = Staff.lookup(listSelected.getSelectedValue().toString().split(", ")[1],listSelected.getSelectedValue().toString().split(", ")[0]); 
       Staff.removeStaff(s); 
       update(); 
      } 
     }); 
     selectInstructor.addActionListener(e -> { 
      if(unSelectedInstructors.getSelectedValue() != null) { 
       Staff s = Staff.lookup(unSelectedInstructors.getSelectedValue().toString().split(", ")[1], unSelectedInstructors.getSelectedValue().toString().split(", ")[0]); 
       s.setActive(true); 
       update(); 
      } 
     }); 
     unSelectInstructor.addActionListener(e -> { 
      if(selectedInstructors.getSelectedValue() != null) { 
       Staff s = Staff.lookup(selectedInstructors.getSelectedValue().toString().split(", ")[1], selectedInstructors.getSelectedValue().toString().split(", ")[0]); 
       s.setActive(false); 
       update(); 
      } 
     }); 
     selectAllInstructors.addActionListener(e -> { 
      for(Staff s : Staff.staffIndex) { 
       s.setActive(true); 
      } 
      update(); 
     }); 
     unSelectAllInstructors.addActionListener(e -> { 
      for(Staff s : Staff.staffIndex) { 
       s.setActive(false); 
      } 
      update(); 
     }); 
    } 

    public int getIdentifier() { 
     return identifier; 
    } 

    public static InstructorGUI lookup(int id) { 
     for (InstructorGUI i : instructorGUIIndex) { 
      if (i.getIdentifier() == id) { 
       return i; 
      } 
     } 
     return null; 
    } 

    public void update() { 
     ArrayList<Staff> selected = new ArrayList<>(); 
     ArrayList<Staff> notSelected = new ArrayList<>(); 

     for (Staff s : Staff.staffIndex) { 
      if (s.isActive()) { 
       selected.add(s); 
      } else { 
       notSelected.add(s); 
      } 
     } 

     selectedInstructors.removeAll(); 
     unSelectedInstructors.removeAll(); 
     selectedInstructors.setListData(selected.toArray()); 
     unSelectedInstructors.setListData(notSelected.toArray()); 


    } 

} 

enter image description here I”我只使用所需的代码复制错误创建一个单独的程序然而,我注意到,有时当我在列表之间切换时,而不是选择项目时,选项周围会出现一个蓝色框。我试图在发生这种情况时调用getSelectionIndex(),并返回-1。每次点击某个项目时,我该如何选择它?

+1

发布您的[mcve],演示此问题。只需在列表中使用字符串,因为您的Staff对象与您的选择问题无关。 – camickr

+2

对你的其他同学不感兴趣。 99%的代码与您描述的问题无关。 [mcve]的要点是让你简化问题。通常,当你这样做时,你会发现你的问题,但如果没有,那么你在论坛上发布一些简单的东西。 – camickr

+0

我们无法编译,运行或测试此代码。请阅读上面提供给您的链接,这些链接可以帮助您改进此代码和问题,以便更易于回答。 –

你的问题在于你的ListSelectionListener。首先,让我们创建一个更好的,更简单的MCVE,一个代码simplifie仅重现该问题所需的要领:

import java.awt.GridLayout; 
import javax.swing.*; 
import javax.swing.event.ListSelectionEvent; 
import javax.swing.event.ListSelectionListener; 

@SuppressWarnings("serial") 
public class Main2 extends JPanel { 
    private JList<String> list1 = new JList<>(new String[] { "one", "two", "three" }); 
    private JList<String> list2 = new JList<>(new String[] { "hello", "goodbye", "yes" }); 

    public Main2() { 
     list1.setName("list 1"); 
     list2.setName("list 2"); 
     list1.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 
     list2.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 

     list1.addListSelectionListener(new MySelectionListener(list2)); 
     list2.addListSelectionListener(new MySelectionListener(list1)); 

     setLayout(new GridLayout(1, 0)); 
     add(new JScrollPane(list1)); 
     add(new JScrollPane(list2)); 
    } 

    private class MySelectionListener implements ListSelectionListener { 
     private JList<String> otherList; 

     public MySelectionListener(JList<String> otherList) { 
      this.otherList = otherList; 
     } 

     @Override 
     public void valueChanged(ListSelectionEvent e) { 
      otherList.clearSelection(); 
     } 
    } 

    private static void createAndShowGui() { 
     Main2 mainPanel = new Main2(); 

     JFrame frame = new JFrame("Main2"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.getContentPane().add(mainPanel); 
     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(() -> createAndShowGui()); 
    } 
} 

运行它,你会看到该问题重现 - 新选择不适当地选择所选项目。另外,如果你注释掉这一行,otherList.clearSelection();,你会发现新选择的列表会显示新的选择,这很好,所以这条线是错误的,因为它会搞乱你想要的行为。

@Override 
public void valueChanged(ListSelectionEvent e) { 
    // otherList.clearSelection(); 
    if (e.getValueIsAdjusting()) { 
     otherList.clearSelection(); 
    } 
} 

为什么这项工作:

这可以通过在其他列表被清除,只有当所选择的值调整限制是固定的?我真的不能肯定地说,但我知道这将清除其他列表的选择之前新列表的项目被选中,所以它的工作原理。此外,只有当值未调整时才会提取选定的值,因此需要if/else块,如下所示:

import java.awt.BorderLayout; 
import java.awt.GridLayout; 
import javax.swing.*; 
import javax.swing.event.ListSelectionEvent; 
import javax.swing.event.ListSelectionListener; 

@SuppressWarnings("serial") 
public class Main2 extends JPanel { 
    private JList<String> list1 = new JList<>(new String[] { "one", "two", "three" }); 
    private JList<String> list2 = new JList<>(new String[] { "hello", "goodbye", "yes" }); 
    private JTextField selectedItemTxtFld = new JTextField(10); 

    public Main2() { 
     list1.setName("list 1"); 
     list2.setName("list 2"); 
     list1.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 
     list2.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 

     list1.addListSelectionListener(new MySelectionListener(list2)); 
     list2.addListSelectionListener(new MySelectionListener(list1)); 

     JPanel listPanel = new JPanel(new GridLayout(1, 0)); 
     listPanel.add(new JScrollPane(list1)); 
     listPanel.add(new JScrollPane(list2)); 

     JPanel topPanel = new JPanel(); 
     topPanel.add(new JLabel("Selection:")); 
     topPanel.add(selectedItemTxtFld); 

     setLayout(new BorderLayout()); 
     add(topPanel, BorderLayout.PAGE_START); 
     add(listPanel, BorderLayout.CENTER); 
    } 

    private class MySelectionListener implements ListSelectionListener { 
     private JList<String> otherList; 

     public MySelectionListener(JList<String> otherList) { 
      this.otherList = otherList; 
     } 

     @Override 
     public void valueChanged(ListSelectionEvent e) { 
      // otherList.clearSelection(); 
      if (e.getValueIsAdjusting()) { 
       otherList.clearSelection(); 
      } else { 
       JList<String> thisList = (JList<String>) e.getSource(); 
       if (!thisList.isSelectionEmpty()) { 
        String selectedText = thisList.getSelectedValue().toString(); 
        selectedItemTxtFld.setText(selectedText); 
       } 
      } 
     } 
    } 

    private static void createAndShowGui() { 
     Main2 mainPanel = new Main2(); 

     JFrame frame = new JFrame("Main2"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.getContentPane().add(mainPanel); 
     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(() -> createAndShowGui()); 
    } 
}