简体   繁体   English

JList在选择项目0后重复更新defaultlistmodel

[英]JList repeatedly updating defaultlistmodel after selecting item 0

I am using the Swing designer in Eclipse to build a GUI to list my movies which are stored in an XML file. 我正在Eclipse中使用Swing设计器来构建GUI,以列出存储在XML文件中的电影。 After loading the frame and contents to the various JList s, I have the app set to update the lists when an item is selected. 将框架和内容加载到各种JList ,我将应用程序设置为在选择一个项目时更新列表。 So, if you pick a genre, all the movies for that genre will be shown, same applies for groups, episodes and seasons. 因此,如果您选择一种类型,则将显示该类型的所有电影,同样适用于团体,剧集和季节。 I also have a refresh lists button which reloads the lists. 我还有一个刷新列表按钮,可重新加载列表。

the problem I am encountering is: when I have selected the item at index 0 , an extra listener action is called compared to when I select index 1 or higher. 我遇到的问题是:当我选择索引0处的项目时,与选择索引1或更高索引时相比,将调用额外的侦听器动作。 Then (my main concern), if I select the refresh button, a listener is fired for every item added to the listmodel for the previously selected JList . 然后(主要关注),如果我选择了刷新按钮, listmodel先前选择的JList添加到listmodel每个项目触发一个侦听器。

For example, if I select 1 from the episodes list & then refresh, only 1 listener is called. 例如,如果我从情节列表中选择1 ,然后刷新,则仅会调用1个侦听器。 However, if I select 0 from the episode list & then refresh, I get 35 listeners called (which is the total amount of episodes in the list). 但是,如果我从情节列表中选择0 ,然后刷新,我将得到35个侦听器的调用(这是列表中情节的总数)。

For something small like the episodes this isn't a big issue, but when this happens on the movies column I get around 1500 listeners fired. 对于像情节这样的小事情来说,这不是什么大问题,但是当在电影专栏中发生这种情况时,我大约有1500名听众被解雇。

package local.testarea;

import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JScrollPane;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import net.miginfocom.swing.MigLayout;

@SuppressWarnings( { "rawtypes", "unchecked" } )
public class ListDemo {

    private JFrame frame;
    private JList list, list_1;
    private JButton btnNewButton;
    private DefaultListModel<String> list2;
    private DefaultListModel<Integer> list1;

    /**
     * Launch the application.
     */
    public static void main( String[] args )
    {
        EventQueue.invokeLater( new Runnable() {

            public void run()
            {
                try
                {
                    ListDemo window = new ListDemo();
                    window.frame.setVisible( true );
                }
                catch ( Exception e )
                {
                    e.printStackTrace();
                }
            }
        } );
    }

    /**
     * Create the application.
     */
    public ListDemo()
    {
        list1 = new DefaultListModel<Integer>();
        list2 = new DefaultListModel<String>();
        initialize();
        updateAll();
    }

    private void updateAll()
    {
        list1.clear();
        list2.clear();
        for ( int i = 0; i < 101; i++ )
        {
            list1.addElement( i );
        }
        list2.addElement( "Even" );
        list2.addElement( "Odd" );

    }

    private void updateLists( int selected )
    {
        list1.clear();
        list2.clear();
        switch( selected )
        {
            case 0:
                for ( int i = 0; i < 101; i++)
                {
                    if ( i % 2 == 0 ) 
                    {
                        list1.addElement( i );
                    }
                }
                list2.addElement( "Even" );
                break;

            case 1:
                for ( int i = 0; i < 101; i++)
                {
                    if ( i % 2 != 0 ) 
                    {
                        list1.addElement( i );
                    }
                }
                list2.addElement( "Odd" );
                break;

            default:
                int z = selected - 10;
                list1.addElement( z );
                list2.addElement( "Even" );
                list2.addElement( "Odd" );
                break;
        }
    }

    /**
     * Initialize the contents of the frame.
     */
    private void initialize()
    {
        frame = new JFrame();
        frame.setBounds( 100, 100, 450, 481 );
        frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
        frame.getContentPane().setLayout(new MigLayout("", "[grow][grow]", "[grow][]"));

        JScrollPane scrollPane = new JScrollPane();
        frame.getContentPane().add(scrollPane, "cell 0 0,grow");

        list = new JList( list1 );
        list.addListSelectionListener(new ListSelectionListener() {
            public void valueChanged(ListSelectionEvent e) {
                System.out.println( "List 1 trigger" );
                System.out.println( "selected item: " + list_1.getSelectedIndex() );
                if ( list.getSelectedIndex() >= 0 )
                {
                    int z = 10 + list.getSelectedIndex();
                    updateLists( z );
                }
            }
        });
        scrollPane.setViewportView(list);

        JScrollPane scrollPane_1 = new JScrollPane();
        frame.getContentPane().add(scrollPane_1, "cell 1 0,grow");

        list_1 = new JList( list2 );
        list_1.addListSelectionListener(new ListSelectionListener() {
            public void valueChanged(ListSelectionEvent e) {
                System.out.println( "List 2 trigger" );
                System.out.println( "selected item: " + list_1.getSelectedIndex() );
                if ( list_1.getSelectedIndex() >= 0 )
                {
                    updateLists( list_1.getSelectedIndex() );
                }
            }
        });
        scrollPane_1.setViewportView(list_1);

        btnNewButton = new JButton("New button");
        btnNewButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                System.out.println( "refresh" );
                updateAll();
            }
        });
        frame.getContentPane().add(btnNewButton, "cell 1 1");
    }
}

You are modifying the lists while selection is still in progress, which causes additional selection events to be fired (recursively). 您在选择仍在进行时正在修改列表,这将导致(递归)触发其他选择事件。 You are also modifying both lists for no reason. 您也无缘无故地修改了两个列表。

The String list should just act as a filter to the Integer List. String列表应仅用作Integer列表的过滤器。 Also, I don't understand why you're removing all the items from the Integer list when a single value is selected. 另外,我不明白为什么选择单个值时会从“ Integer列表中删除所有项目。 It makes it look like a JList is not what you want to use. 它看起来好像不是您要使用的JList

In any case, I modified your ListSelectionListener : 无论如何,我都修改了ListSelectionListener

public class ListDemo extends JFrame{

    private DefaultListModel<Integer> listModel1 = new DefaultListModel<>();
    private DefaultListModel<String> listModel2 = new DefaultListModel<>();
    private JList<Integer> list1 = new JList<>(listModel1);
    private JList<String> list2 = new JList<>(listModel2);
    int size = 101;

    public ListDemo() {

        list1.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        add(new JScrollPane(list1));

        list2.addListSelectionListener(new ListParityFilter());
        list2.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        listModel2.addElement("All");
        listModel2.addElement("Even");
        listModel2.addElement("Odd");
        list2.setSelectedIndex(0);
        add(new JScrollPane(list2), BorderLayout.EAST);

        setDefaultCloseOperation(EXIT_ON_CLOSE);
        pack();
        setLocationRelativeTo(null);
        setVisible(true);
    }

    private class ListParityFilter implements ListSelectionListener {

        public void valueChanged(ListSelectionEvent e) {

            if (e.getValueIsAdjusting())
                return;
            System.out.println("Selected List2 item: " + list2.getSelectedValue());
            listModel1.clear();
            switch (list2.getSelectedIndex()) {
                case 0:
                    for (int i = 0; i < size; i++)
                        listModel1.addElement(i);
                    break;
                case 1:
                    for (int i = 0; i < size; i += 2)
                        listModel1.addElement(i);
                    break;
                case 2:
                    for (int i = 1; i < size; i += 2)
                        listModel1.addElement(i);
                    break;
            }
        }
    }

    public static void main(String[] args) {

        new ListDemo();
    }
}

Notes: 笔记:

  • Instead of the refresh button, I added an "All" option for the filter list. 我为过滤器列表添加了“全部”选项,而不是刷新按钮。
  • The filter list should not be modified (there is no reason). 筛选器列表不应修改(没有理由)。
  • Check for e.getValueIsAdjusting() so you don't perform unnecessary operations. 检查e.getValueIsAdjusting()以免执行不必要的操作。
  • I set the selection model to SINGLE_SELECTION for both lists. 我将两个列表的选择模型都设置为SINGLE_SELECTION
  • I removed the Integer list selection listener because it serves no purpose. 我删除了“ Integer列表选择”侦听器,因为它没有用。 It will be called once in 2 situations: 在两种情况下将被调用一次
    1. When a value is selected (selected index >= 0). 选择一个值时(所选索引> = 0)。
    2. When a filter is applied, since the list is cleared (selected index = -1). 应用过滤器时,由于清除了列表(所选索引= -1)。
  • Use pack() on the JFrame instead of setting its size and location. JFrame上使用pack()而不是设置其大小和位置。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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