JTable单元格返回null

我在JTable单元格中使用JTextField ; 我使用TabelModel ,它具有JTable的动态数据。 现在,当我点击一个按钮时,我正在读取一个单元格值。 问题是具有当前焦点的单元格不返回更新的值。 例如,考虑这个程序:

 import java.awt.BorderLayout; import java.awt.Component; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JOptionPane; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.JTextField; import javax.swing.table.DefaultTableModel; import javax.swing.table.TableCellRenderer; public class MyTable extends JFrame { DefaultTableModel tmodel = new DefaultTableModel(new Object[][]{ {"some"}, {"any"}, {"even"}, {"text"}, {"and"}, {""}}, new Object[]{"Column 1"}); public MyTable() { setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); final JTable table = new JTable(tmodel); table.setDefaultRenderer(Object.class, new MyRenderer()); getContentPane().add(new JScrollPane(table), BorderLayout.CENTER); getContentPane().setLayout(new GridLayout(2, 2)); JButton jb = new JButton("click me"); //button to display last cell data jb.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) { JOptionPane.showMessageDialog( null, table.getModel().getValueAt(5, 0)); } }); getContentPane().add(jb); } public static void main(String arg[]) { new MyTable().setVisible(true); } } class MyRenderer implements TableCellRenderer { public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { JTextField editor = new JTextField(); if (value != null) { editor.setText(value.toString()); } return editor; } } 

在这里,我将最后一个字段留空。 当我读它

 table.getModel().getValueAt(5, 0) 

我得到了。 现在我将值更改为5,0,然后再次单击按钮,但现在我再次得到null 。 现在令人惊讶的是,我编辑了一些其他单元格,再次单击按钮; 现在我在单元格5,0获得了正确的数据! 为什么是这样? 这是一个错误吗? 我尝试了几种可能性!

结合@ kleopatra的建议和@ mKorble的有用修订 ,这里有一些基于你的例子的额外想法。 请特别注意setDefaultButton()ActionKey Bindings一起使用。

 import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.EventQueue; import java.awt.event.ActionEvent; import java.awt.event.KeyEvent; import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.KeyStroke; import javax.swing.table.DefaultTableModel; /** @see https://stackoverflow.com/q/9874664/230513 */ public class MyTable extends JFrame { private static final String show = "Show"; private DefaultTableModel tmodel = new DefaultTableModel( new Object[][]{ {"edit"}, {"any"}, {"cell"}, {"text"}, {"and"}, {"edit me"}}, new Object[]{ "Column 1"}); private JTable table = new JTable(tmodel); private Action showAction = new ShowAction(show); private JButton jb = new JButton(showAction); public MyTable() { setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setLocationByPlatform(true); table.putClientProperty("terminateEditOnFocusLost", true); KeyStroke enter = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0); table.getInputMap(JTable.WHEN_FOCUSED).put(enter, show); table.getActionMap().put(show, showAction); add(new JScrollPane(table), BorderLayout.CENTER); table.setPreferredScrollableViewportSize(new Dimension(400, 200)); JPanel panel = new JPanel(); panel.add(jb); getRootPane().setDefaultButton(jb); add(panel, BorderLayout.SOUTH); pack(); } private class ShowAction extends AbstractAction { private ShowAction(String name) { super(name); } @Override public void actionPerformed(ActionEvent e) { if (table.isEditing()) { table.getCellEditor().stopCellEditing(); } int row = table.getSelectedRow(); if (row > -1) { JOptionPane.showMessageDialog( MyTable.this, table.getModel().getValueAt(row, 0)); } } } public static void main(String arg[]) { EventQueue.invokeLater(new Runnable() { @Override public void run() { new MyTable().setVisible(true); } }); } } 

您的示例中有几点需要考虑:

首先,你应该看看Java – 教程 ,了解JTables中Renderer和Editor的概念,因为你在这里混合了一些东西。 在渲染器中,您使用的JTextField没有意义,因为此对象仅用于在tableModel中显示数据。 通常,JLabel用于呈现,因为您不会在呈现器中编辑值。

此外,你的例子(尽管我还没有尝试过)应该可以工作,因为JTable已经有了一个DefaultEditor。 也许您只是忘记在按下Enter之前提交值,然后单击按钮以检查哪个值在?

我真的可以推荐阅读本教程并搜索有关如何正常处理的一些示例。 你应该找到很多有用的例子。

我认为每种类型的数组都以0(零)开头,然后输出到JoptionPane是正确的(返回空字符串),稍微修改一下原始代码,添加最重要的Swing rulles

 import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.table.DefaultTableModel; public class MyTable extends JFrame { private static final long serialVersionUID = 1L; private DefaultTableModel tmodel = new DefaultTableModel(new Object[][]{ {"some"}, {"any"}, {"even"}, {"text"}, {"and"}, {"xxxxxxxxxxxxxxxxxxxxxxx"}}, new Object[]{"Column 1"}); public MyTable() { setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); final JTable table = new JTable(tmodel); table.setPreferredScrollableViewportSize(table.getPreferredSize()); add(new JScrollPane(table), BorderLayout.CENTER); JButton jb = new JButton("click me"); //button to display last cell data jb.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) { JOptionPane.showMessageDialog(null, table.getModel().getValueAt(5, 0)); } }); add(jb, BorderLayout.SOUTH); pack(); setVisible(true); } public static void main(String arg[]) { EventQueue.invokeLater(new Runnable() {//added initial thread @Override public void run() { MyTable myTable = new MyTable(); } }); } }