JTable单元格返回null

Ash*_*Raj 1 java swing jtable

JTextFieldJTable细胞内使用; 我使用的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;
    }
}
Run Code Online (Sandbox Code Playgroud)

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

table.getModel().getValueAt(5, 0)
Run Code Online (Sandbox Code Playgroud)

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

cru*_*sam 5

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

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

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

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


mKo*_*bel 5

我认为每种类型的数组都以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();
            }
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

  • @AshokRaj:[这个](http://stackoverflow.com/a/7267729/230513)可能有所帮助. (2认同)
  • @Ashok Raj ahaaaaaaaaa :-),你是对的,你必须叫`stopCellEditing`,更好的是可以通过阅读答案([@kleopatra](http://stackoverflow.com/search?q=user%3A203657+stopCellEditing) )或者相同的([@camickr](http://stackoverflow.com/search?q=user%3A131872+stopCellEditing)),也许还有其他问题和答案,但我在这个论坛上链接了"TOP two answerers" (2认同)

tra*_*god 5

结合 @kleopatra 的建议和 @mKorble 的有用修订,这里有一些基于您的示例的附加想法。特别注意Key Bindings 的使用setDefaultButton()Action结合。

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 /sf/ask/691226511/ */
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);
            }
        });
    }
}
Run Code Online (Sandbox Code Playgroud)