2011-09-06 248 views
0

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

为什么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); 
     } 
     }); 
    } 
} 
+0

请尝试发布[SSCCE](http://sscce.org/) – oliholz

+0

哪个运行时错误发生? – oliholz

+0

异常在线程 “AWT-EventQueue的-0” java.lang.ArrayIndexOutOfBoundsException:-1 \t在java.util.ArrayList.get(ArrayList.java:324) \t在GuiDriver $ ChannelListListener.valueChanged(GuiDriver.java:130 ) \t在javax.swing.DefaultListSelectionModel.fireValueChanged(DefaultListSelectionModel.java:167) \t在javax.swing.DefaultListSelectionModel.fireValueChanged(DefaultListSelectionModel.java:147) \t在javax.swing.DefaultListSelectionModel.fireValueChanged(DefaultListSelectionModel.java: (defaultListSelectionModel.java:660) – blitzeus

回答

1

RemoveAction获得所选择的指数上valueChanged()并从模型中删除的项目。
actionPerformed()上再次删除选定的值,并再次删除所选的索引。为什么这么频繁?
Btw:On actionPerformed()不会调用channelTitleJList.getSelectedIndex()它删除相同的索引,该索引已被valueChanged()删除,但此索引不再存在,也许另一个元素被删除。之后,JList中没有选择。

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

+0

因此,如果if我注释掉了我的ChannelListListener类,然后我的RemoveAction类在没有运行时异常的情况下工作。为什么? – blitzeus

+0

因为youu只通过'ChannelListListener'中的'feedList.get(i)'获得Exception,''''''''''''''''。在没有ListSelectionListener的情况下删除后是否看到一个选择? – oliholz