JTable не обновится - PullRequest
       18

JTable не обновится

1 голос
/ 20 марта 2012

Почему ячейка 0,1 таблицы не изменится с aaa на XXXX?

import java.awt.*;

import javax.swing.*;
import javax.swing.table.DefaultTableModel;


class MainFrame {

    public static void main(String[] args) {


        JFrame f = new JFrame("Refreshing JTable");
        JPanel p = new JPanel(new GridBagLayout());
        DefaultTableModel productsModel;
        JTable productsTable;

        f.setSize(800, 600);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);


        String[] tableTitle = new String[] {"ID", "Name"};
        String[][] tableData = {{"1", "AAA"},{"2", "BBB"}};


        productsModel = new DefaultTableModel(tableData, tableTitle);
        productsTable = new JTable(productsModel) {
            public boolean isCellEditable(int r, int c) {
                return false;
            }
        };

        JScrollPane scrollpane = new JScrollPane(productsTable);


        tableData[0][1] = "XXXX";

        f.add(p);
        p.add(scrollpane);
        f.validate();
        f.setVisible(true);


    }


}

ПРИЧИНА: Очевидно, попытка обновить массив, в котором хранятся данные, приведет к тому, что JTable не изменится. Необходимо обновить DefaultTableModel или перерисовать всю таблицу.

РЕДАКТИРОВАТЬ (возможное решение) Одним из способов является с использованием таймера :

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;
import javax.swing.table.DefaultTableModel;

class MainFrame {

    static JFrame f = new JFrame("Refreshing JTable");
    static JPanel p = new JPanel(new GridBagLayout());
    static DefaultTableModel productsModel;
    static JTable productsTable;

    public static void main(String[] args) {
        runGui();
    }

    @SuppressWarnings("serial")
    public static void runGui() {

        f.setSize(800, 600);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);


        String[] tableTitle = new String[] {"ID", "Name"};
        String[][] tableData = {{"1", "AAA"},{"2", "BBB"}};


        productsModel = new DefaultTableModel(tableData, tableTitle);
        productsTable = new JTable(productsModel) {
            public boolean isCellEditable(int r, int c) {
                return false;
            }
        };

        JScrollPane scrollpane = new JScrollPane(productsTable);


        tableData[0][1] = "XXXX";

        Timer t = new Timer(2000, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                addColumns();
                remakeData();
                productsTable.setModel(productsModel);

            }
        });
        t.start();

        f.add(p);
        p.add(scrollpane);
        f.validate();
        f.setVisible(true);


    }

    private static void addColumns() {
        productsModel.setColumnCount(0);
        productsModel.addColumn("ID");
        productsModel.addColumn("Name");
    }

    private static void remakeData() {
        productsModel.setRowCount(0);
        productsModel.insertRow(productsModel.getRowCount(), new Object[] {"1", "Dummy item 1"});
        productsModel.insertRow(productsModel.getRowCount(), new Object[] {"2", "Dummy itme 2"});
        productsModel.insertRow(productsModel.getRowCount(), new Object[] {"3", "Dummy item 3"});
        productsModel.insertRow(productsModel.getRowCount(), new Object[] {"4", "Dummy item 4"});
        productsModel.insertRow(productsModel.getRowCount(), new Object[] {"5", "Dummy item 5"});
    }
}

РЕДАКТИРОВАТЬ (гораздо лучшее решение, как оно работает для меня безупречно) Использование статического метода . Так как я добавляю новые данные в массив через другой Frame, я создал статический метод в MainFrame, который я вызываю каждый раз, когда добавляю / обновляю / удаляю Object в массиве. Этот метод восстановит всю модель после обновления и, следовательно, обновит таблицу.

Ответы [ 2 ]

3 голосов
/ 21 марта 2012

Одна проблема с SSCCE, опубликованным в связанном вами потоке, состоит в том, что код изменяет массив, который первоначально сформировал модель таблицы, тогда как он должен изменять саму модель таблицы.

3 голосов
/ 21 марта 2012

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

  1. Вы обязательно прочитаете, как1004 * на самом деле работает.Хорошей отправной точкой является учебник по Swing и, возможно, даже класс javadoc самых важных классов JTable и TableModel.Еще одно хорошее прочтение о Swing и использовании MVC - этот документ .Он гораздо шире, чем JTable с, но даст вам более полное представление о том, как спроектированы все компоненты Swing и как вы должны их использовать.
  2. После прочтения этого руководства вы должны понимать, что если вы хотитечтобы обновить данные, которые показаны в таблице, вы обновляете модель своей таблицы.Модель сгенерирует события, полученные таблицей, и таблица сама обновится.В конце концов, таблица представляет собой только представление данных (= TableModel), поэтому обновления на дубле должны выполняться на стороне модели.Если это не ясно, вернитесь к шагу 1
  3. . Теперь посмотрите на ваш код и удалите прослушиватель.Вместо этого обновите модель таблицы и посмотрите, как таблица обновляется сама.
  4. Если это не работает, вы возвращаетесь на этот сайт с SSCCE , который вы публикуете.Таким образом, мы видим, что вы что-то пробовали, что вы пробовали и, скорее всего, что не так в вашем коде.Этот SSCCE должен включать ваш код TableModel, который вы используете, и код, который обновляет ваш TableModel, так как это наиболее вероятное место для вашей проблемы.
...