简体   繁体   中英

Java - How do I select items in JList 2 based on selection in JList 1?

I have two JLists. When I select an item in list AI want one or more related items to be highlighted in list B. Simple case here has list 1 with AB, AC, BC, and ABC; list 2 has A, B, and C. If AC is selected in list 1 I want A and C to be highlighted in list 2, etc.

I'm completely mishandling the ListSelectionListener and ListCellRenderer. My idea was:

  1. In the ListSelectionListener for list 1 designate in an ArrayList or HashMap what items in list 2 should be highlighted based on what was just selected in list 1.

  2. Do a list2.repaint() from the list 1 ListSelectionListener with the logic in the ListCellRenderer for list 2 setting the background to blue or white accordingly based on what was designated in the ListSelectionListener for list 1.

This doesn't work, but I don't know if it's because I'm implementing it incorrectly or because it's the wrong approach altogether.

Any ideas? Thanks very much…

import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.swing.DefaultListModel;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.ListCellRenderer;
import javax.swing.SwingUtilities;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

public class Test extends JFrame {
  public static JList list1, list2;
  public static DefaultListModel model1, model2;
  public static List<Integer> highlightThese = new ArrayList<Integer>();


  public Test() {
    setPreferredSize(new Dimension(300, 100));
    Container cp = getContentPane();
    cp.setLayout(new FlowLayout());

    list1 = new JList();
    list1.setModel(new ListModel1());
    model1 = new DefaultListModel();
    list1.addListSelectionListener(new ListenerForList1());
    cp.add(list1);

    list2 = new JList(new String[] {"A", "B", "C"});
    model2 = new DefaultListModel();
    cp.add(list2);

    pack();
  }

  public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
      public void run() {
        new Test().setVisible(true);
      }
    });
  }
}

class ListModel1 extends DefaultListModel {
  String[] listItems = new String[] { "AB", "AC", "BC", "ABC" };

  public ListModel1 () {
    for (int i = 0; i < listItems.length; i++) {
      addElement(listItems[i]);
    }
  }
}

class ListModel2 extends DefaultListModel {
  String[] listItems = new String[] { "A", "B", "C" };

  public ListModel2 () {
    for (int i = 0; i < listItems.length; i++) {
      addElement(listItems[i]);
    }
  }
}

class ListenerForList1 implements ListSelectionListener {
  @Override
  public void valueChanged(ListSelectionEvent e) {
    JList list = (JList)(e.getSource());
    Object[] tmp = list.getSelectedValues();
    String[] selectedValues1 = Arrays.copyOf(tmp, tmp.length, String[].class);

    for (int i = 0; i < selectedValues1.length; i++) {
      String l1Val = selectedValues1[i];
      for (int j = 0; j < Test.model2.getSize(); j++) {
        String l2Val = (String)(Test.model2.get(j));
        if (l1Val.indexOf(l2Val) >= 0) {
          // Want to highlight item j in list2 here, or at least
          // designate somehow that it should be highlighted (in
          // TestRenderer2?). Must also handle turning off highlight
          // at some point but will deal with that later.
          Test.highlightThese.add(j);
        }
      }
    }
    list2.repaint();
  }
}

class TestRenderer2 extends JLabel implements ListCellRenderer {
  @Override
  public Component getListCellRendererComponent(JList list, Object stringval, int inx, boolean isSelected, boolean cellHasFocus) {
    if (Test.highlightThese.contains(inx)) {
      setBackground(Color.BLUE);
      setForeground(Color.WHITE);
    } else {
      setBackground(Color.WHITE);
      setForeground(Color.BLACK);
    }
    return this;
  }
}

Change ListSelectionMode from second list to ListSelectionModel.MULTIPLE_INTERVAL_SELECTION . Iterate over first model and use addSelectionInterval . Try this

import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.util.ArrayList;
import java.util.List;
import javax.swing.DefaultListModel;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
public class Test extends JFrame {
    public JList<String> list1, list2;
    public DefaultListModel<String> model1, model2;
    public List<Integer> highlightThese = new ArrayList<Integer>();
    public Test() {
        setPreferredSize(new Dimension(300, 100));
        Container cp = getContentPane();
        cp.setLayout(new FlowLayout());
        model1 = new DefaultListModel<String>();
        model1.addElement("AB");
        model1.addElement("AC");
        model1.addElement("BC");
        model1.addElement("ABC");
        list1 = new JList<String>(model1);
        list1.addListSelectionListener(new ListSelectionListener() {
            @Override
            public void valueChanged(ListSelectionEvent e) {
                list2.clearSelection();
                String str = list1.getSelectedValue();
                String[] parts = str.split("");
                for (int i = 0; i < model2.size(); i++) {
                    for (String p : parts) {
                        if (model2.getElementAt(i).equals(p))
                            list2.addSelectionInterval(i, i);
                    }
                }
            }
        });
        cp.add(list1);
        model2 = new DefaultListModel<String>();
        model2.addElement("A");
        model2.addElement("B");
        model2.addElement("C");
        list2 = new JList<String>(model2);
        list2.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
        cp.add(list2);
        pack();
    }
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new Test().setVisible(true);
            }
        });
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM