从JLIST中删除项目

时间:2011-09-06 02:26:42

标签: java swing jlist items

当按下删除按钮时,会发生运行时错误,并且直到channelTitleJList(再次按下JScrollPane的左侧)才会删除该项目。

为什么RemoveAction类不会立即删除该项?

itemTitleJList也没有按预期清除。

import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java.util.List;
import java.util.ArrayList;
import java.io.*;


public class GuiDriver extends JFrame{
   JList channelTitleJList, itemTitleJList;
   DefaultListModel cModel, iModel;
   List<RssReader> feedList = new ArrayList<RssReader>();   
   int nextFeed=0;
   ListSelectionModel lsm;


   public void addFeed(RssReader feed){
      feedList.add(feed);
   }


   public JToolBar createToolBar(){
      JToolBar bar = new JToolBar();
      Action newToolBarButton = new AddAction("New");
      Action deleteToolBarButton = new RemoveAction("Delete");
      Action clearToolBarButton = new ClearAction("Clear");

      bar.add(newToolBarButton);  
      bar.add(deleteToolBarButton);
      bar.add(clearToolBarButton);

      bar.setFloatable(false);      
      return bar;
   }


   public JSplitPane createJSplitPane(){
      JSplitPane hSplitPane  = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,createChannelJScrollPane(), createItemJScrollPane());
      hSplitPane.setDividerLocation(500);
      return hSplitPane;
   }


   public JScrollPane createChannelJScrollPane(){            
      cModel = new DefaultListModel(); 
      channelTitleJList = new JList(cModel);
      JScrollPane channelJScrollPane = new JScrollPane(channelTitleJList);
      channelTitleJList.setVisibleRowCount(20);
      lsm = channelTitleJList.getSelectionModel();
      lsm.addListSelectionListener(new ChannelListListener());      

      return channelJScrollPane;     
   }


   public JScrollPane createItemJScrollPane(){
      iModel = new DefaultListModel();
      itemTitleJList = new JList(iModel);
      JScrollPane itemJScrollPane = new JScrollPane(itemTitleJList);
      //itemTitleJList.addListSelectionListener(new ItemListListener());

      return itemJScrollPane;
   }   


   public class AddAction extends AbstractAction{
      public AddAction(String name){
         super(name);
      }

      public void actionPerformed(ActionEvent e){
         System.out.println(getValue(Action.NAME)+" selected.");
         JOptionPane message = new JOptionPane();
         String firstInput = message.showInputDialog(null, "Enter URL");
         try{
            DumpStockPage.readXml(firstInput);
                File f = new File("RSSFeed.xml");
            addFeed(new RssReader(f));

                cModel.addElement(feedList.get(nextFeed).rssChannel.getTitle());
                nextFeed++;
                iModel.clear();
         }
         catch (IOException ee){
            System.err.println(ee);
         }
      }
   }


   public class RemoveAction extends AbstractAction implements ListSelectionListener{
      int i;
      public RemoveAction(String name){
         super(name);
      }

      public void valueChanged (ListSelectionEvent e) {
         i = channelTitleJList.getSelectedIndex();
         cModel.remove(i);
      }

      public void actionPerformed(ActionEvent e){
         cModel.removeElement(channelTitleJList.getSelectedValue());
         cModel.remove(i);
      } 
   }

   public class ClearAction extends AbstractAction{
      public ClearAction(String name){
         super(name);
      }

      public void actionPerformed(ActionEvent e){
         iModel.clear();
      } 
   }


   private class ChannelListListener implements ListSelectionListener{
      public void valueChanged (ListSelectionEvent e) {        
         boolean adjust = e.getValueIsAdjusting();
         if (!adjust) {
            List<String> titles = new ArrayList<String>();
            int i = channelTitleJList.getSelectedIndex(); //the index of the selected item in the left list

            for(RssItem feed: feedList.get(i).rssChannel.items) {
                titles.add(feed.getTitle());  //build a list of titles, to be shown in the right list
            }

            itemTitleJList.setListData(titles.toArray()); //change the content of the right list
         } 
      }
   }

/*   
   private class ItemListListener implements ListSelectionListener {
     public void valueChanged (ListSelectionEvent e) {
        boolean adjust = e.getValueIsAdjusting();
        if (!adjust) {
           int i = e.getLastIndex();
           try{ 
              JFrame w = new JFrame();
              w.setTitle("Html Display"); 
              w.setSize(1000, 600); 
              w.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
              w.setVisible(true); 

              JEditorPane htmlPane = new JEditorPane();
              htmlPane.setPage(feedList.get(i).rssChannel.items.get(i).getLink());
              w.add(new JScrollPane(htmlPane));
           }
           catch(Exception ee){ 
              ee.printStackTrace();
           }
        }
     }
   }
*/  

   public static void main(String[] args) { 
      EventQueue.invokeLater(new Runnable() { 
         public void run() {  
            GuiDriver frame = new GuiDriver(); 

            frame.setTitle("RSS Reader");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
            frame.add(frame.createJSplitPane(), BorderLayout.NORTH);
            frame.add(frame.createToolBar(), BorderLayout.SOUTH);

            frame.setVisible(true);
            frame.setSize(800,400);
         }   
      });  
   }
}

1 个答案:

答案 0 :(得分:1)

RemoveActionvalueChanged()上获取所选索引并从模型中删除该项目。
actionPerformed()上,将再次删除所选值,并再次删除所选索引。为什么这么经常?
顺便说一句:在actionPerformed()不调用channelTitleJList.getSelectedIndex()时,它删除了由valueChanged()删除的相同索引,但此索引不再存在,可能删除了另一个元素。之后,JList中没有选择。

您的ArrayIndexOutOfBoundsExceptioni-1,因为如果没有选择,JList.getSelectedIndex()会返回-1see here