Могу ли я установить выбранный элемент для JList без события, брошенного слушателям? - PullRequest
4 голосов
/ 22 июня 2010

Я работаю над средством просмотра, которое использует JList для отображения эскизов страниц документа. Пользователь может открыть страницу, выбрав ее в JList или с помощью других механизмов, например, введя номер в текстовом поле.

При использовании последней альтернативы я хочу, чтобы JList также выбирал страницу. Я делаю это с помощью setSelectedIndex (), но это вызывает событие, которое вызывает загрузку страницы снова, как если бы пользователь щелкнул и выбрал страницу в JList, и это вызывает у меня некоторые проблемы.

На мой взгляд, индекс должен быть задан каким-то образом (возможно, в модели), чтобы обновлялся только пользовательский интерфейс JList, не вызывая событие изменения индекса.

Возможно ли это? Или есть лучший способ решить мою проблему?

Ответы [ 2 ]

6 голосов
/ 22 июня 2010
  1. Вы можете удалить все ListSelectionListener из списка, сделать выбор, а затем добавить их снова.

  2. Вы можете создать свой собственный ListSelectionModel с помощью метода, который не выбрасывает событие, и установить его в качестве модели выбора на JList, а затем использовать getSelectionModel().yourSelectIndexMethod(index).

  3. Вы также можете перенаправить все остальные методы выбора в список, просто найдите соответствующую запись, если выбираете страницу другими способами, и выберите элемент в списке.Таким образом, элемент выбирается и страница загружается один раз.

Код для варианта 2:

public class ListTest extends JPanel{

private static final String[] items = new String[]{"1", "2", "3"};
private JList mylist;
private JComboBox myCombo;
private JTextArea myTA;

public ListTest() {
    setLayout(new BorderLayout());
    myCombo = new JComboBox(items);
    myCombo.addActionListener(new ActionListener(){

        @Override
        public void actionPerformed(ActionEvent e){
            valueSelectedCombo(myCombo.getSelectedIndex());
        }
    });
    JPanel pn = new JPanel();
    pn.setLayout(new BoxLayout(pn, BoxLayout.X_AXIS));
    pn.add(myCombo);
    pn.add(Box.createHorizontalGlue());
    pn.add(new JButton(new AbstractAction("Clear"){

        @Override
        public void actionPerformed(ActionEvent e){
            myTA.setText("");
        }
    }));
    add(pn, BorderLayout.NORTH);
    add(new JScrollPane(getJList()), BorderLayout.WEST);
    add(new JScrollPane(myTA = new JTextArea()), BorderLayout.CENTER);
}

private void valueSelectedList(int index){
    myTA.setText(myTA.getText() + "\n" + items[index]);
}

private void valueSelectedCombo(int index){
    myTA.setText(myTA.getText() + "\n" + items[index]);
    ((CustomSelectionModel)mylist.getSelectionModel()).setSelectionSilent(index);
}

private JList getJList(){
    if (mylist == null){
        mylist = new JList(items);
        mylist.setSelectionModel(new CustomSelectionModel());
        mylist.addListSelectionListener(new ListSelectionListener(){

            @Override
            public void valueChanged(ListSelectionEvent e){
                if (!e.getValueIsAdjusting()){
                    valueSelectedList(mylist.getSelectedIndex());
                }
            }
        });

        mylist.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        mylist.setPreferredSize(new Dimension(100, 106));

    }
    return mylist;
}

private static class CustomSelectionModel extends DefaultListSelectionModel{

    private boolean isSilent = false;

    public void setSelectionSilent(int firstIndex){
        isSilent = true;
        setSelectionInterval(firstIndex, firstIndex);
        isSilent = false;
    }
    protected void fireValueChanged(int firstIndex, int lastIndex, boolean isAdjusting){
        if (isSilent){
            return;
        }
        super.fireValueChanged(firstIndex, lastIndex, isAdjusting);
    }
}

public static void main(String[] args){
    JFrame frame = new JFrame("test");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    // Add content to the window.
    frame.add(new ListTest());

    // Display the window.
    frame.pack();
    frame.setSize(300, 200);
    frame.setVisible(true);
}

}
1 голос
/ 22 июня 2010

Похоже, setSelectedIndex() - это просто удобный способ установки выбора в ListSelectionModel.Возможно, ваш ListModel может пометить или кэшировать результат, чтобы он не загружался во второй раз.

...