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());
}
}
I”我只使用所需的代码复制错误创建一个单独的程序然而,我注意到,有时当我在列表之间切换时,而不是选择项目时,选项周围会出现一个蓝色框。我试图在发生这种情况时调用getSelectionIndex(),并返回-1。每次点击某个项目时,我该如何选择它?
答
你的问题在于你的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());
}
}
发布您的[mcve],演示此问题。只需在列表中使用字符串,因为您的Staff对象与您的选择问题无关。 – camickr
对你的其他同学不感兴趣。 99%的代码与您描述的问题无关。 [mcve]的要点是让你简化问题。通常,当你这样做时,你会发现你的问题,但如果没有,那么你在论坛上发布一些简单的东西。 – camickr
我们无法编译,运行或测试此代码。请阅读上面提供给您的链接,这些链接可以帮助您改进此代码和问题,以便更易于回答。 –