Ячейка JTable, возвращающая ноль - PullRequest
1 голос
/ 26 марта 2012

Я использую JTextField внутри JTable клеток;Я использую 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)

, я получаю null.Теперь я изменяю значение на 5,0 и снова нажимаю кнопку, но теперь снова получаю null.Теперь, что удивительно, я редактирую другую ячейку, снова нажимаю кнопку;теперь я получаю правильные данные в ячейке 5,0!Почему это?Это ошибка?Я испробовал несколько возможностей!

Ответы [ 3 ]

5 голосов
/ 26 марта 2012

Я думаю, что каждый тип массивов начинается с 0 (ноль), затем вывод на JoptionPane корректен (возвращает пустую строку), немного изменил ваш исходный код, добавил наиболее важные правила Swing

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();
            }
        });
    }
}
5 голосов
/ 26 марта 2012

В вашем примере необходимо учесть несколько моментов:

Сначала вы должны заглянуть в Java - Tutorials , чтобы узнать о концепции рендерера и редактора в JTables, потому что вы как бы здесь все перемешиваете. В вашем Renderer вы используете JTextField, который не имеет смысла, потому что этот объект просто используется для представления данных в вашем tableModel. Обычно для представления используется JLabel, так как вы никогда не будете редактировать значение в Renderer.

Более того, ваш пример (хотя я еще не пробовал) должен работать, поскольку JTable уже имеет DefaultEditor. Может быть, вы просто забыли зафиксировать значение, нажав клавишу ввода, прежде чем нажимать кнопку, чтобы проверить, какое значение находится в?

Я действительно могу просто порекомендовать прочитать этот урок и найти несколько примеров того, как это обычно обрабатывается. Вы должны найти много рабочих примеров.

4 голосов
/ 28 марта 2012

Включая предложение @ kleopatra и полезные @ mKorble редакции , вот несколько дополнительных идей, основанных на вашем примере. В частности, обратите внимание на использование 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 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);
            }
        });
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...