2012-04-10 65 views
4

我想我的手在使用Swing,并决定专注于使用JList与对象的数组列表一起使用。JList复制选择

我想创建一个显示空白JList的程序,当按下按钮时将显示数组列表的内容,并允许单个选择打印出曾经被选中的内容。

我目前的代码完成了上述所有操作,但是当我点击JList上的一个条目时,它会打印出两次。我觉得这是一个简单的错误,可以很容易地纠正,但我一直在阅读,我的大脑已停止合作。

任何帮助将不胜感激。在此先感谢:)

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


public class textarea { 

    ArrayList <Pet> petList = new ArrayList <Pet>(); 
    DefaultListModel model = new DefaultListModel(); 
    JList list = new JList(); 

    public static void main (String [] args){ 

     textarea gui = new textarea(); 
     gui.go(); 
    } 

    public void go(){ 

     petList.add(new Pet("Lucy","Dog",5)); 
     petList.add(new Pet("Geoff","Cat",2)); 
     petList.add(new Pet("Hammond","Hamster",1)); 

     model = new DefaultListModel(); 
     for(Pet p:petList){ 
      model.addElement(p.toString()); 
     } 

     JFrame frame = new JFrame(); 
     JPanel panel = new JPanel(); 
     JButton button = new JButton("view pets"); 
     button.addActionListener(new ButtonListener()); 


     JScrollPane scroller = new JScrollPane(list); 
     scroller.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); 
     scroller.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); 

     panel.add(scroller); 

     list.setVisibleRowCount(4); 
     list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 
     list.addListSelectionListener(new ListSelectionListener(){ 
      public void valueChanged(ListSelectionEvent event){ 
       String selection = (String) list.getSelectedValue(); 
       System.out.println(selection); 
      } 
     }); 

     frame.getContentPane().add(BorderLayout.CENTER,panel); 
     frame.getContentPane().add(BorderLayout.SOUTH,button); 

     frame.setSize(350,300); 
     frame.setVisible(true); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

    }//end go() 

     class ButtonListener implements ActionListener{ 
     public void actionPerformed(ActionEvent event){ 
       list.setModel(model); 
      } 
     }//end ButtonListener 

} 
+0

一般性意见SwingUtilities.invokeLater()'。 – assylias 2012-04-10 22:57:55

+0

谢谢,我会牢记它,并相应地更改代码。 – skon 2012-04-11 10:57:05

回答

4

简短的回答:添加if (!event.getValueIsAdjusting())周围您的打印像这样:

list.addListSelectionListener(new ListSelectionListener() 
{ 
    public void valueChanged(ListSelectionEvent event) 
    { 
    if (!event.getValueIsAdjusting()) 
    { 
     String selection = (String) list.getSelectedValue(); 
     System.out.println(selection); 
    } 
    } 
}); 

长一点的回答:两起事件正在被解雇。点击鼠标时触发一次,释放鼠标时触发另一个。我们通常认为点击是单一动作,但实际上它是由鼠标抑郁,任何动作和鼠标释放构成的。在这些阶段中,选择内容可能会改变。运行你的代码,并尝试点击一行,拖动到其他行,然后释放。每当行更改时,您都会看到事件被触发。只有当值不再调整时才采取行动,你可以在'最终'状态下开火。使用你应该运行在[EDT] GUI代码(http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html)`:

来源:ListSelectionEvent JavadocsListSelectionModel Javadocs

+0

谢谢埃里克。在完成你所提到的事情之后,事件处理现在更有意义。 – skon 2012-04-11 10:58:17

+0

我很高兴听到它有帮助。欢迎来到堆栈溢出! – 2012-04-11 17:37:59

2

刚刚测试了您的代码。在项目选择2事件发送。唯一的区别是我可以看到isAdjusting布尔值。这是设置为true的第一次,假第二

无论如何,似乎这是标准行为