2013-03-21 86 views
1

首先: 對不起,我無法提供SSCCE。我試圖在一個小項目上重新創建這個問題,但沒有成功,或者我應該說成功,因爲它在那裏工作!FocusListener上可編輯JCombobox沒有射擊

所以這裏是我的問題: 我有一個可編輯的JCombobox,它應該通過單擊編輯器組件來監聽焦點事件。但它不是。

下面的代碼片段,我裝上監聽器:

cmbZoom.setToolTipText(locale.getString("GUI_ZoomFactor")); 
cmbZoom.setFont(new Font(Font.SANS_SERIF, Font.PLAIN, 16)); 
cmbZoom.setPreferredSize(new Dimension(88, 29)); 
cmbZoom.setEditable(true); 
((JTextField)cmbZoom.getEditor().getEditorComponent()).setHorizontalAlignment(JTextField.CENTER); 
cmbZoom.getEditor().getEditorComponent().addFocusListener(
    new FocusListener(){ 
    public void focusGained(FocusEvent arg0) { 
     System.out.println("GAINED"); 
    } 

    public void focusLost(FocusEvent arg0) { 
     System.out.println("LOST"); 
    } 
    }); 

我已經嘗試去除所有其他的監聽器組合框,去掉觀察者模式,使受保護的組合框,並貼在每個聽者孩子,...

我也試圖重新實現它像寫這篇文章: JCombobox focusLost is not firing-why is that?

是否有調試事件的好辦法?

整個項目可以在Github上查看: https://github.com/nexxx/Database-Analyzer

工具欄類可以在這裏找到(開始於第98行代碼): https://github.com/nexxx/Database-Analyzer/blob/master/src/dba/gui/auxClasses/toolBars/ToolBar.java

+1

事實上,相同的代碼在某些情況下導致問題而不是其他問題導致我懷疑您的代碼可能未在[AWT事件調度線程]上執行(http://docs.oracle.com/javase/tutorial/ uiswing /併發/ dispatch.html)。 – VGR 2013-03-21 08:45:21

+0

@VGR非常感謝!這是問題!你能寫一個答案,以便我可以將其標記爲已解決。 – 2013-03-21 09:48:54

+1

無關:[不要使用setXXSize,有史以來](http://stackoverflow.com/a/7229519/203657) – kleopatra 2013-03-21 11:13:19

回答

2

相同的代碼會導致他人在某些情況下的問題,但沒有使我懷疑你的代碼可能無法在AWT event dispatch thread被執行的事實。

1
  • 我倒是建議不要與Item & DocumentListenerFocusListener混合加入到JComboBox'es Editor,可以創建無限循環

˚F或者例如,

import java.awt.*; 
import java.awt.event.FocusEvent; 
import java.awt.event.FocusListener; 
import java.util.Vector; 
import javax.swing.*; 
import javax.swing.UIManager; 
import javax.swing.plaf.ColorUIResource; 
import javax.swing.plaf.metal.MetalComboBoxButton; 

public class MyComboBox { 

    private Vector<String> listSomeString = new Vector<String>(); 
    private JComboBox someComboBox = new JComboBox(listSomeString); 
    private JComboBox editableComboBox = new JComboBox(listSomeString); 
    private JComboBox non_EditableComboBox = new JComboBox(listSomeString); 
    private JFrame frame; 

    public MyComboBox() { 
     listSomeString.add("-"); 
     listSomeString.add("Snowboarding"); 
     listSomeString.add("Rowing"); 
     listSomeString.add("Knitting"); 
     listSomeString.add("Speed reading"); 
// 
     someComboBox.setPrototypeDisplayValue("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"); 
     someComboBox.setFont(new Font("Serif", Font.BOLD, 16)); 
     someComboBox.setEditable(true); 
     someComboBox.getEditor().getEditorComponent().setBackground(Color.YELLOW); 
     ((JTextField) someComboBox.getEditor().getEditorComponent()).setBackground(Color.YELLOW); 
     someComboBox.getEditor().getEditorComponent().addFocusListener(fcsListener); 
// 
     editableComboBox.setPrototypeDisplayValue("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"); 
     editableComboBox.setFont(new Font("Serif", Font.BOLD, 16)); 
     editableComboBox.setEditable(true); 
     JTextField text = ((JTextField) editableComboBox.getEditor().getEditorComponent()); 
     text.setBackground(Color.YELLOW); 
     JComboBox coloredArrowsCombo = editableComboBox; 
     Component[] comp = coloredArrowsCombo.getComponents(); 
     for (int i = 0; i < comp.length; i++) { 
      if (comp[i] instanceof MetalComboBoxButton) { 
       MetalComboBoxButton coloredArrowsButton = (MetalComboBoxButton) comp[i]; 
       coloredArrowsButton.setBackground(null); 
       break; 
      } 
     } 
     editableComboBox.getEditor().getEditorComponent().addFocusListener(fcsListener); 
// 
     non_EditableComboBox.setPrototypeDisplayValue("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"); 
     non_EditableComboBox.setFont(new Font("Serif", Font.BOLD, 16)); 
     non_EditableComboBox.addFocusListener(fcsListener); 
// 
     frame = new JFrame(); 
     frame.setLayout(new GridLayout(0, 1, 10, 10)); 
     frame.add(someComboBox); 
     frame.add(editableComboBox); 
     frame.add(non_EditableComboBox); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setLocation(100, 100); 
     frame.pack(); 
     frame.setVisible(true); 
    } 

    // 
    private FocusListener fcsListener = new FocusListener() { 

     @Override 
     public void focusGained(FocusEvent e) { 
      dumpInfo(e); 
     } 

     @Override 
     public void focusLost(FocusEvent e) { 
      dumpInfo(e); 
     } 

     private void dumpInfo(FocusEvent e) { 
      final Component c = e.getComponent(); 
      System.out.println("Source : " + name(e.getComponent())); 
      System.out.println("Opposite : " + name(e.getOppositeComponent())); 
      System.out.println("Temporary: " + e.isTemporary()); 
      if (c instanceof JFormattedTextField) {//works for editable JComboBox too 
       SwingUtilities.invokeLater(new Runnable() { 

        @Override 
        public void run() { 
         ((JFormattedTextField) c).selectAll(); 
        } 
       }); 
      } else if (c instanceof JTextField) { 
       SwingUtilities.invokeLater(new Runnable() { 

        @Override 
        public void run() { 
         ((JTextField) c).selectAll(); 
        } 
       }); 
      } else if (c instanceof JTextField) { 
       SwingUtilities.invokeLater(new Runnable() { 

        @Override 
        public void run() { 
         ((JComboBox) c).getEditor().selectAll(); 
        } 
       }); 
      } 
     } 

     private String name(Component c) { 
      return (c == null) ? null : c.getName(); 
     } 
    }; 

    public static void main(String[] args) { 
     UIManager.put("ComboBox.background", new ColorUIResource(Color.yellow)); 
     UIManager.put("JTextField.background", new ColorUIResource(Color.yellow)); 
     UIManager.put("ComboBox.selectionBackground", new ColorUIResource(Color.magenta)); 
     UIManager.put("ComboBox.selectionForeground", new ColorUIResource(Color.blue)); 
     SwingUtilities.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       MyComboBox aCTF = new MyComboBox(); 
      } 
     }); 
    } 
}