2017-07-14 83 views
0

我有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

我們無法編譯,運行或測試此代碼。請閱讀上面提供給您的鏈接,這些鏈接可以幫助您改進此代碼和問題,以便更易於回答。 –

回答

2

你的問題在於你的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()); 
    } 
}