Используйте JSpinner как редактор ячеек JTable

я использую JSpinner как редактор ячеек таблицы, у меня есть одна неприятная проблема:

Ячейка остается в НЕредактируемом режиме, пока я не нажму на нее, для НЕредактируемого я имею в виду, что я не могу писать в нее (у нее нет фокуса, поэтому она не принимает ввод с клавиатуры), но я могу изменить значение вверх -стрелки вниз (на клавиатуре).

Итак, что мне нужно сделать, чтобы сфокусировать ячейку таблицы, как только я нажму клавишу, когда она выбрана?

За исключением этой проблемы, мой класс SpinnerEditor работает достаточно хорошо.

Спасибо всем.


person blow    schedule 17.09.2010    source источник


Ответы (2)


Вот полный пример. Он делает больше, чем просто помещает JSpinner в таблицу, чтобы вы могли прочитать его и взять то, что вам нужно. Я нашел ответ Блоу неполным, и он не сработал для меня, поэтому вот что вы можете скомпилировать и запустить.

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

public class JSpinnerInTables {
    static String[] columnNames = {
        "Name","Value"
    };
    static Object[][] data = {
        {"one",1.0},
        {"two",2.0}
    };
    public static void main( String[] args ) {
        JFrame frame = new JFrame();
        JTable table = new JTable(data,columnNames);
        //table.setSurrendersFocusOnKeystroke(true);
        TableColumnModel tcm = table.getColumnModel();
        TableColumn tc = tcm.getColumn(1);
        tc.setCellEditor(new SpinnerEditor());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(table);
        frame.pack();
        frame.setVisible(true);
    }
    public static class SpinnerEditor extends DefaultCellEditor
    {
        JSpinner spinner;
        JSpinner.DefaultEditor editor;
        JTextField textField;
        boolean valueSet;

        // Initializes the spinner.
        public SpinnerEditor() {
            super(new JTextField());
            spinner = new JSpinner();
            editor = ((JSpinner.DefaultEditor)spinner.getEditor());
            textField = editor.getTextField();
            textField.addFocusListener( new FocusListener() {
                public void focusGained( FocusEvent fe ) {
                    System.err.println("Got focus");
                    //textField.setSelectionStart(0);
                    //textField.setSelectionEnd(1);
                    SwingUtilities.invokeLater( new Runnable() {
                        public void run() {
                            if ( valueSet ) {
                                textField.setCaretPosition(1);
                            }
                        }
                    });
                }
                public void focusLost( FocusEvent fe ) {
                }
            });
            textField.addActionListener( new ActionListener() {
                public void actionPerformed( ActionEvent ae ) {
                    stopCellEditing();
                }
            });
        }

        // Prepares the spinner component and returns it.
        public Component getTableCellEditorComponent(
            JTable table, Object value, boolean isSelected, int row, int column
        ) {
            if ( !valueSet ) {
                spinner.setValue(value);
            }
            SwingUtilities.invokeLater( new Runnable() {
                public void run() {
                    textField.requestFocus();
                }
            });
            return spinner;
        }

        public boolean isCellEditable( EventObject eo ) {
            System.err.println("isCellEditable");
            if ( eo instanceof KeyEvent ) {
                KeyEvent ke = (KeyEvent)eo;
                System.err.println("key event: "+ke.getKeyChar());
                textField.setText(String.valueOf(ke.getKeyChar()));
                //textField.select(1,1);
                //textField.setCaretPosition(1);
                //textField.moveCaretPosition(1);
                valueSet = true;
            } else {
                valueSet = false;
            }
            return true;
        }

        // Returns the spinners current value.
        public Object getCellEditorValue() {
            return spinner.getValue();
        }

        public boolean stopCellEditing() {
            System.err.println("Stopping edit");
            try {
                editor.commitEdit();
                spinner.commitEdit();
            } catch ( java.text.ParseException e ) {
                JOptionPane.showMessageDialog(null,
                    "Invalid value, discarding.");
            }
            return super.stopCellEditing();
        }
    }
}
person Jason    schedule 28.01.2012

Хорошо, теперь мое решение таково:

spinner.addFocusListener(new FocusListener() {

    public void focusGained(FocusEvent e) {

        // editor is ((JSpinner.DefaultEditor)spinner.getEditor()).getTextField();
        // necessary to set focus on the text component of jspinner
        editor.requestFocus();

        // this if you want to select the displayed text of jspinner
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                System.out.println("run");
                editor.selectAll();
            }
        });
    }

    public void focusLost(FocusEvent e) {}
});
person blow    schedule 17.09.2010
comment
У меня такая же проблема, но ваше решение мне не подходит. Метод focusGain никогда не вызывается. Я точно скопировал ваш код, создал поле с именем editor и присвоил ему значение, которое вы говорите использовать. Как выглядит остальная часть вашего кода для настройки JTable и CellEditor? - person Jason; 27.01.2012