2012-01-04 28 views
4

我有一個JComboBox顯示在下面的代碼。當程序啓動時,actionPerformed事件立即引發一些空指針異常,所以我想從沒有選中的元素開始。但是,由於某種原因,它不起作用(無論我做什麼,它始終始終顯示「USD/TRY」)。任何人有任何想法?固執JComboBox

JComboBox comboBox = new JComboBox(new String[]{"USD/TRY", "EUR/TRY", "GBP/TRY"}); 

comboBox.setSelectedIndex(-1); // doesnt change anything 
comboBox.setSelectedIndex(2); // doesnt change anything  
comboBox.setSelectedItem(null); // doesnt change anything 

UPDATE:構建組合框像下面並沒有改變任何東西要麼

JComboBox comboBox = new JComboBox(); 

comboBox.addItem("USD/TRY"); 
comboBox.addItem("EUR/TRY"); 
comboBox.addItem("GBP/TRY"); 

這裏是SSCCE:

public class MainFrame { 

    private final JTextArea textArea = new JTextArea(); 
    private IExchangeSource s; 

    public MainFrame(final IExchangeSource s) { 
     //build gui 
     final JComboBox comboBox = new JComboBox(); 

     comboBox.addItem("USD/TRY"); 
     comboBox.addItem("EUR/TRY"); 
     comboBox.addItem("GBP/TRY"); 

     comboBox.setSelectedIndex(-1); // doesnt change anything 
     //comboBox.setSelectedIndex(2); // doesnt change anything 


     JFrame f = new JFrame("Currency Converter"); 
     JPanel p = new JPanel(new BorderLayout()); 
     textArea.setName("textarea"); 
     textArea.setWrapStyleWord(true); 
     textArea.setLineWrap(true); 
     this.s = s; 

     comboBox.addActionListener(new ActionListener() { 

      public void actionPerformed(ActionEvent e) { 
       String exchange = (String) comboBox.getSelectedItem(); 

       s.getData(exchange); 
      } 
     }); 

     p.add(comboBox, BorderLayout.NORTH); 
     p.add(textArea, BorderLayout.CENTER); 
     f.setPreferredSize(new Dimension(300, 300)); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     f.pack(); 
     f.add(p); 
     comboBox.setSelectedIndex(0); 
     f.setVisible(true); 
    } 
} 
+0

嘗試在創建JComboBox之後加載String []? – 2012-01-04 16:21:26

+0

試過,它不工作= /我相應地更新了問題。謝謝 – Cemre 2012-01-04 16:26:37

+3

有異常的堆棧跟蹤會有所幫助。你怎麼能添加一個ActionListener到一個尚未創建的組合框? – 2012-01-04 16:30:32

回答

7

你(不完全)例如右變得可見,取消所有以前的設置之前調用

comboBox.setSelectedIndex(0); 

。在之前設置所需的初始索引,添加偵聽器,並且不要忽略在EDT上開始,如下面的sscce所示。

import java.awt.BorderLayout; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import javax.swing.JComboBox; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JTextArea; 

public class MainFrame { 

    private final JTextArea textArea = new JTextArea(); 


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

      @Override 
      public void run() { 
       new MainFrame(); 
      } 
     }); 
    } 
    public MainFrame() { 
     //build gui 
     final JComboBox comboBox = new JComboBox(); 

     comboBox.addItem("USD/TRY"); 
     comboBox.addItem("EUR/TRY"); 
     comboBox.addItem("GBP/TRY"); 

     JFrame f = new JFrame("Currency Converter"); 
     JPanel p = new JPanel(new BorderLayout()); 
     textArea.setName("textarea"); 
     textArea.setWrapStyleWord(true); 
     textArea.setLineWrap(true); 

     comboBox.setSelectedIndex(-1); 
     comboBox.addActionListener(new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       System.out.println(comboBox.getSelectedItem() + ": " + e); 
      } 
     }); 

     p.add(comboBox, BorderLayout.NORTH); 
     p.add(textArea, BorderLayout.CENTER); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     f.pack(); 
     f.setSize(new Dimension(300, 300)); 
     f.add(p); 
     f.setVisible(true); 
    } 
} 
+1

謝謝。其他答案在一定程度上解決了這些問題,但是仍然存在一些問題,但是這個問題完全解決了這個問題。我認爲缺乏構建框架的invokeLater函數(即:從EDT開始)是主要問題。 – Cemre 2012-01-04 19:26:05

+0

感謝您的跟進。我總是對揭示EDT問題的新方法感興趣。 – trashgod 2012-01-04 19:32:27

+0

@Cemre,你有沒有讀過API和教程?本教程中的示例正確使用了EDT,這就是爲什麼我在早些時候指出您要上課的時間。 – camickr 2012-01-04 21:55:40

2

1)添加ItemListener代替ActionListener,但這ItemListener始終發射兩次事件SELECTEDDESELECTED,

myComboBox.addItemListener(new ItemListener() { 

     @Override 
     public void itemStateChanged(ItemEvent e) { 
      if (e.getStateChange() == ItemEvent.SELECTED) { 
       //some stuff 
      } 
     } 
    }); 

2)你的GUI也許是或不是EventDispashThread創建的,但在這種情況下,不要緊,你必須通過包木窗變成了invokeLater()來延緩這種方法,例如

public class MainFrame { 
    . 
    . 
    . 

    f.setPreferredSize(new Dimension(300, 300)); 
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    f.pack(); 
    f.add(p); 
    comboBox.setSelectedIndex(0); 
    f.setVisible(true); 
    selectDesiredItem(); 
} 

private void selectDesiredItem() { 
    EventQueue.invokeLater(new Runnable() { 

     @Override 
     public void run() { 
      comboBox.setSelectedIndex(-1); 
     } 
    }); 
} 

3)更好地將工具AutoCompete JComboBox/JTextField貨幣對

4)也許並不重要,但CcyPairs已經默認了四邊

  • Buy BaseCcy

  • Sell BaseCcy

  • Buy VariableCcy

  • Sell VariableCcy

+0

非常感謝您的詳細解答。對此,我真的非常感激。雖然,你的第二個建議解決了組合框錯誤,但我仍然收到空指針異常。 – Cemre 2012-01-04 19:28:22

+0

+1主題專業知識! – trashgod 2012-01-04 19:29:31

+0

-1太多隨機子彈 - 新年快樂:-) – kleopatra 2012-01-05 10:45:38

0

的建議,到目前爲止都不錯。但有時,當事情真的令人費解上的組件是如何被構建,需要更直接的解決辦法:

  1. 子類JComboBox時(或任何Swing類在激發事件,JList中,等...)
  2. 添加一個字段private boolean fireEvents = false;考慮讓它volatile
  3. 覆蓋相關fireXXX()方法檢查fireEvents的狀態
  4. 只有全部建成後置fireEvents = true和初始化完成
  5. 如果「大修」隨後呼籲,如加載一個新的文件,新設置,您可以在重建所有內容時將fireEvents設置爲false。
+0

謝謝你的回答。 – Cemre 2012-01-04 19:26:44

+0

-1 _當事情真的很複雜時,主要是因爲應用程序代碼做錯了。因此,不要隨便使用不雅的子類,拙劣的標誌或混亂的覆蓋,第一步是挖掘並理解具體上下文中究竟出了什麼問題,並修復_that_ – kleopatra 2012-01-05 10:36:45