2012-05-28 29 views
2

我有一個JTable,它有2列。其中一列由JTextField表示,另一列由單選按鈕表示。Java Swing:JTextField不會像預期的那樣失去焦點

模型填充這樣:

model.addRow(new Object[]{radioButton, ""}); 

相關與JTextField中有這樣的細胞編輯:

class MyCellEditor extends DefaultCellEditor { 

    MyCellEditor(JTextField textField) { 
    super(textField); 
    textField.addFocusListener(new FocusListener() { 

     public void focusLost(FocusEvent e) { 
      // do something if focus is lost 
     } 

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

當我點擊JTextField的電池,我收到了「閃爍「遊標如預期,所以我可以輸入我的文本。無論如何,如果我點擊主窗口中的任何其他地方,我會期待」focusLost(...)「方法已被調用,但只有當我」玩「在窗口中(例如幾次點擊和拖出jtextfield)。

爲什麼在第一次點擊另一個外部組件後組件不會失去焦點?

回答

4

可以在TableCellEditor

覆蓋stopEditing()或直接寫

table.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE); 

更復雜(JFormattedTextField上)例如

import java.awt.Component; 
import java.awt.EventQueue; 
import java.text.DecimalFormat; 
import java.text.ParseException; 
import javax.swing.*; 
import javax.swing.table.TableCellEditor; 
import javax.swing.table.TableCellRenderer; 
import javax.swing.table.TableColumnModel; 

public class EditorAsRendererTableTest { 

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

      @Override 
      public void run() { 
       JTable table = new JTable(3, 2); 
       TableColumnModel colModel = table.getColumnModel(); 
       MyCellEditor both = new MyCellEditor(); 
       colModel.getColumn(0).setCellEditor(both); 
       colModel.getColumn(0).setCellRenderer(both); 
       JFrame frame = new JFrame("Test"); 
       frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
       frame.getContentPane().add(new JScrollPane(table)); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    private static class MyCellEditor extends AbstractCellEditor implements TableCellEditor, TableCellRenderer { 

     private static final long serialVersionUID = 1L; 
     private JFormattedTextField renderer = new JFormattedTextField(DecimalFormat.getInstance()); 
     private JFormattedTextField editor; 

     @Override 
     public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { 
      renderer.setValue(value); 
      return renderer; 
     } 

     @Override 
     public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { 
      editor = new JFormattedTextField(DecimalFormat.getInstance()); 
      editor.setValue(value); 
      return editor; 
     } 

     @Override 
     public boolean stopCellEditing() { 
      try { 
       editor.commitEdit(); 
      } catch (ParseException e) { 
       return false; 
      } 
      return super.stopCellEditing(); 
     } 

     @Override 
     public Object getCellEditorValue() { 
      return editor.getValue(); 
     } 
    } 

    private EditorAsRendererTableTest() { 
    } 
} 
+0

我已經在過去嘗試過,但他們沒有工作(無論如何,我認爲與stopEditing()你想要:public boolean stopCellEditing())。只有當按下「enter」鍵時纔會調用stopCellEditing()。 – Randomize

+0

@Randomize請參閱我的編輯在這裏,並且不要忘記也重寫cancelCellEditing() – mKorbel

+0

謝謝你的幫助。我運行你的演示代碼,看起來我在點擊文本字段後無法點擊其他任何地方。它是否意味着「最佳實踐」,所以文本字段不會失去焦點,直到輸入值爲止? – Randomize

0

我固定這樣的:

1)給予重點放在新的JTextField上:

if (editCellAt(getRowCount()-1, 1)) getEditorComponent().requestFocus(); 

2)表自動檢測失去焦點:

table.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE); 

3)在 「MyCellEditor類 - > @覆蓋公共布爾stopCellEditing()」 只是檢查組件是否具有焦點或不是:

getComponent().isFocusOwner()