2

これは、ボタンを押すと、jList1 に a1 から a1000 までの項目が再入力される例です。

//variable
private List<String> list = new ArrayList<>();

...

//main method
jList1.setModel(new DefaultListModel());
for(int i = 0; i < 1000; i++) {
    list.add("a"+i);
}

...

//button action - jList1 refill
DefaultListModel dtm = (DefaultListModel)jList1.getModel();
dtm.removeAllElements();
for(String s : list) {
    dtm.addElement(s);
}

を入力するjList1と、(マウスで) 0 インデックス (jList の最初の要素) を選択し、リストの再入力中にプログラムがフリーズするボタンを押します。他の要素を選択するか、リスト内のアイテムをまったく選択しないと、問題なく入力されます。

PS この例は、swing または EWT スレッドを使用せずに実行されています。これは、主な理由がそれらを使用していることが判明したためです。

SSCCE:

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package lt;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JPanel;

/**
 *
 * @author Minutis
 */
public class Window {

    public static void main(String[] args) {
        final List<String> list = new ArrayList<>();


        JFrame frame = new JFrame("BorderLayout Frame");
        JPanel panel = new JPanel();
        final JList jList1 = new JList();
        JButton refill = new JButton("Refill");

        jList1.setModel(new DefaultListModel());
        for(int i = 0; i < 1000; i++) {
            list.add("a"+i);
        }

        refill.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                DefaultListModel dtm = (DefaultListModel)jList1.getModel();
                dtm.removeAllElements();
                for(String s : list) {
                    dtm.addElement(s);
                }
            }

        });

        frame.add(panel);
        panel.setLayout(new BorderLayout());
        panel.add(jList1, BorderLayout.CENTER);
        panel.add(refill, BorderLayout.SOUTH);
        frame.setSize(300, 300);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}
4

2 に答える 2

5

この問題は、最初の要素が選択されたときにモデル内のすべての要素を削除することによって発生します。実装方法では、インデックスが選択されて削除されると、何らかの理由で selectionChanged イベントが生成されます。別のインデックスが選択されているときに別のインデックスが選択されている場合 (要素のシフトを意味する場合でも)、selectionChanged イベントは生成されません。

削除は、最初の要素を定期的に削除する方法で実装されますが、選択インデックスは変更されません。したがって、インデックス 0 が選択されている場合、1000 個の selectionChanged イベントが生成されます。これは、EDT およびリスナーによって処理される必要があります。別のインデックスを選択すると、1 つのイベントのみが生成されます。これにより、オーバーヘッドが大幅に削減されます。

インデックス 0 が選択されている間に再設定する前に、手動で選択をインデックス 1 に設定してみてください。

if(jList1.getSelectedIndex() == 0){
     jList1.setSelectedIndex(1);
}

リストに要素が1つしかない場合は心配する必要はないと思います.要素数よりも大きなインデックスを設定することは何もすべきではありません。しかし、それは実装固有のものかもしれません。

何らかの理由でclearSelection()、空のリストを再設定するために selectionChanged イベントが生成されます。

于 2012-11-21T14:40:07.343 に答える
2
  • 論理的でより良いのは(タイプミスによる間違いを避けるためだけに)add//直接でremovemodify ItemsXxxListModel

例えば

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class Testing extends JFrame {

    private static final long serialVersionUID = 1L;
    private DefaultListModel listModel = new DefaultListModel();
    private JList list = new JList(listModel);
    private int currentSelectedRow = 0;
    private int xX = 0;

    public Testing() {
        setLocation(400, 300);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        for (int x = 0; x < 51; x++) {
            listModel.addElement("" + x);
            xX++;
        }
        JScrollPane sp = new JScrollPane(list);
        final JViewport vp = sp.getViewport();
        add(sp, BorderLayout.CENTER);
        /*JButton btn = new JButton("Get Row:");
        add(btn, BorderLayout.SOUTH);
        btn.addActionListener(new ActionListener() {

        public void actionPerformed(ActionEvent ae) {
        try {
        int goToRow = Integer.parseInt(JOptionPane.showInputDialog(getContentPane(), "Go To Row:"));
        Rectangle r = list.getCellBounds(goToRow, goToRow);
        if (goToRow > currentSelectedRow) {
        r = list.getCellBounds(goToRow - 1, goToRow - 1);
        int vph = vp.getExtentSize().height;
        r.y += vph;
        }
        list.scrollRectToVisible(r);
        list.setSelectedIndex(goToRow);
        currentSelectedRow = goToRow;
        } catch (Exception e) {

        }
        }
        });*/
        JButton btn1 = new JButton("Reset Model CastingModel");
        add(btn1, BorderLayout.NORTH);
        btn1.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent ae) {
                DefaultListModel model = (DefaultListModel) list.getModel();
                model.removeAllElements();
                for (int x = 0; x < 51; x++) {
                    model.addElement("" + (x + xX));
                    xX++;
                }
                //list.setModel(model);
            }
        });

        JButton btn2 = new JButton("Reset Model directly from Model");
        add(btn2, BorderLayout.SOUTH);
        btn2.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent ae) {
                listModel.removeAllElements();
                for (int x = 0; x < 51; x++) {
                    listModel.addElement("" + (x + xX));
                    xX++;
                }
            }
        });

        pack();
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new Testing().setVisible(true);
            }
        });
    }
}

編集list.clearSelection(); 問題はありません。OPによって記述された問題によって引き起こされた1,000行を超えるすべてのもの

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class Testing extends JFrame {

    private static final long serialVersionUID = 1L;
    private DefaultListModel listModel = new DefaultListModel();
    private JList list = new JList(listModel);
    private int currentSelectedRow = 0;
    private int xX = 0;

    public Testing() {
        setLocation(400, 300);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        for (int x = 0; x < 999; x++) {
            listModel.addElement("" + x);
            xX++;
        }
        JScrollPane sp = new JScrollPane(list);
        final JViewport vp = sp.getViewport();
        add(sp, BorderLayout.CENTER);

        JButton btn1 = new JButton("Reset Model CastingModel");
        add(btn1, BorderLayout.NORTH);
        btn1.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent ae) {
                list.clearSelection();
                DefaultListModel model = (DefaultListModel) list.getModel();
                model.removeAllElements();
                for (int x = 0; x < 999; x++) {
                    model.addElement("" + (x + xX));
                    xX++;
                }
                //list.setModel(model);
            }
        });

        JButton btn2 = new JButton("Reset Model directly from Model");
        add(btn2, BorderLayout.SOUTH);
        btn2.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent ae) {
                list.clearSelection();
                listModel.removeAllElements();
                for (int x = 0; x < 999; x++) {
                    listModel.addElement("" + (x + xX));
                    xX++;
                }
            }
        });

        pack();
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new Testing().setVisible(true);
            }
        });
    }
}
于 2012-11-21T14:10:55.880 に答える