簡體   English   中英

使用復合JPanel單元格編輯器編輯后,JTable失去焦點

[英]JTable loses focus after editing with compound JPanel cell editor

我有一個單元格編輯器,由JPanel上的幾個組件組成。 當我的自定義單元格編輯器停止編輯時,表將失去焦點,而不是將焦點轉移到下一個單元格。

這是一個簡單的例子。 鍵入每個單元格並在表格中選項卡。 請注意,在訪問第3列后,表將失去焦點到面板上的另一個文本字段。

更新:此問題似乎在Java7中得到修復。 必須使用Java 6運行該示例才能查看焦點丟失行為。

import java.awt.AWTEvent;
import java.awt.Color;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.Toolkit;
import java.awt.event.AWTEventListener;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import javax.swing.AbstractCellEditor;
import javax.swing.DefaultCellEditor;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableModel;
import javax.swing.text.JTextComponent;


public class TableEditorFocusExample extends JFrame
{

   private JTable m_table;
   private TableModel tableModel;


   public TableEditorFocusExample()
   {
       setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );

       Toolkit.getDefaultToolkit().addAWTEventListener( new AWTEventListener()
       {

           @Override
           public void eventDispatched( AWTEvent event )
           {
               System.out.println( "FOCUS " + 
                                   event + 
                                   "\n   source=" + 
                                   event.getSource() );
           }
       }, AWTEvent.FOCUS_EVENT_MASK | AWTEvent.WINDOW_FOCUS_EVENT_MASK );

       tableModel = new DefaultTableModel( 4, 4 );
       m_table = new JTable( tableModel )
       {
           @Override
           public void changeSelection(
                   int row,
                   int column,
                   boolean toggle,
                   boolean extend )
           {
               super.changeSelection( row, column, toggle, extend );

               if ( editCellAt( row, column ) )
               {
                   Component editor = getEditorComponent();
                   editor.requestFocusInWindow();
                   if ( editor instanceof JTextComponent )
                   {
                       ( (JTextComponent)editor ).selectAll();
                   }
               }
           }

       };

       m_table.setModel( tableModel );
       m_table.setSurrendersFocusOnKeystroke( true );
       m_table.putClientProperty( "terminateEditOnFocusLost", Boolean.TRUE ); //$NON-NLS-1$    

       DefaultCellEditor textFieldCellEditor = new DefaultCellEditor( new JTextField() );
       textFieldCellEditor.setClickCountToStart( 1 );

       TableCellEditor panelBasedCellEditor = new PanelCellEditor();

       m_table.getColumnModel().getColumn( 0 ).setCellEditor( textFieldCellEditor );
       m_table.getColumnModel().getColumn( 1 ).setCellEditor( textFieldCellEditor );
       m_table.getColumnModel().getColumn( 2 ).setCellEditor( panelBasedCellEditor );
       m_table.getColumnModel().getColumn( 3 ).setCellEditor( textFieldCellEditor );
       m_table.setColumnSelectionAllowed( true );

       final JButton ok = new JButton( "reset" );

       JPanel panel = new JPanel();
       panel.add( m_table );

       // add a component to grab focus when the table editor loses focus 
       final JTextField textField = new JTextField( 8 );
       final Color origTextColor = textField.getBackground();
       textField.addFocusListener( new FocusAdapter()
       {
           @Override
           public void focusGained( FocusEvent e )
           {
               System.err.println( "focus gained from: " + e.getSource() );
               textField.setBackground( Color.red );
           }
       } );

       // reset the text field background color to the pre-focus color
       ok.addActionListener( new ActionListener()
       {
           @Override
           public void actionPerformed( ActionEvent e )
           {
               textField.setBackground( origTextColor );
           }
       } );

       panel.add( textField );
       panel.add( ok );

       getContentPane().add( panel );
   }


   public class PanelCellEditor extends AbstractCellEditor implements
           TableCellEditor
   {
       public PanelCellEditor()
       {
           m_textfield.setBackground( Color.green );

           m_panel = new JPanel( new GridLayout() )
           {
               @Override
               public boolean requestFocusInWindow()
               {
                   // when the table transfers focus to the editor,
                   // forward focus onto the text field.
                   return m_textfield.requestFocusInWindow();
               }
           };

           m_panel.add( m_textfield );
       }


       @Override
       public Object getCellEditorValue()
       {
           return m_textfield.getText();
       }


       @Override
       public Component getTableCellEditorComponent(
               JTable table,
               Object value,
               boolean isSelected,
               int row,
               int column )
       {
           m_textfield.setText( value == null ? "" : value.toString() );
           return m_panel;
       }


       private JPanel m_panel;
       private JTextField m_textfield = new JTextField( 5 );
   }


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

           @Override
           public void run()
           {
               TableEditorFocusExample test = new TableEditorFocusExample();
               test.setSize( 600, 300 );
               test.setVisible( true );
           }
       } );
   }
}

我在這里找到了一個類似的問題,但解決方案似乎不完整,因為自定義編輯器上的文本字段沒有焦點,它的光標不顯示,使用戶不清楚該字段是否可用於文本輸入。

誰有更好的解決方案?

很好的挖掘:-)

對於jdk6,您可以考慮使用SwingX及其JXTable修復該問題(剛檢查過,忘記了我們已經解決了一些焦點問題:-)。 或者,如果這不是一個選項,請查看其代碼並復制重寫的transferFocus(及相關)方法和改進的EditorRemover。

不要忘記讓編輯遵守合同:

       Action action = new AbstractAction() {

        @Override
        public void actionPerformed(ActionEvent e) {
            stopCellEditing();
        }

       };
       m_textfield.setAction(action);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM