Java, как обновить JTable - PullRequest
       20

Java, как обновить JTable

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

Я довольно новичок в GUI, поэтому, пожалуйста, держитесь со мной.Во всяком случае, у меня есть два JTables.Один для списка счетов, а другой для списка продуктов в счетах.Я создал прослушиватель, так что я могу получить значение идентификатора счета-фактуры из первой JTable одним щелчком мыши, а затем с помощью другого метода я генерирую новое содержимое таблицы для другой таблицы (метод работает нормально).Однако после обновления таблицы я попытался найти способы обновить ее, но безуспешно ... Я просто ищу способ обновить вторую таблицу в тот момент, когда я запускаю событие мыши

Вот частикод:

Панель с двумя JTables

public JPanel tabInvoices() {

    final JPanel panel = new JPanel(new MigLayout("", "20 [grow, fill] 10 [grow, fill] 20", "20 [] 10 [] 20"));

    final DefaultTableModel model1;
    final JTable table1, table2;

    String data[][] = {};
    String col1[] = {"ID", "Date"};
    String col2[] = {"ID", "Name", "Type", "Price", "Quantity"};
    Object[][] selrowData = {};   

    /** Labels and buttons **/
    JLabel labelInv = new JLabel("List of all invoices");
    JLabel labelPro = new JLabel("List of all products in this invoice");

    /** TABLE: Invoices **/
    model1 = new DefaultTableModel(data, col1);
    invoiceInfo = new DefaultTableModel(selrowData,col2);

    /** Load the invoices from DB **/
    List<Invoice> listInv = is.getAllInvoices();
    for (int i = 0; i < listInv.size(); i++) {
        model1.insertRow(i, new Object[] {
                listInv.get(i).getID(),
                listInv.get(i).getDate()
        });
    }

    /** TABLE: Invoices **/
    table1 = new JTable(model1){
        public boolean isCellEditable(int r, int c) {
            return false;
        }
    };

    /** TABLE: Invoice Info **/
    table2 = new JTable(invoiceInfo){
        public boolean isCellEditable(int r, int c) {
            return false;
        }
    };


    /** Cell and Row selection listener **/
    ListSelectionModel cellSelectionModel = table1.getSelectionModel();
    cellSelectionModel.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    cellSelectionModel.addListSelectionListener(new ListSelectionListener() {
        @Override
        public void valueChanged(ListSelectionEvent arg0) {
            int id = (int)table1.getValueAt(row, 0);            // Get ID from first table
            invoiceInfo.getDataVector().removeAllElements();    // Remove everything from second table
            invoiceInfo = getInvoiceInfo(id, invoiceInfo);      // replace with new values

            /**
             * HERE'S WHERE I NEED TO REFRESH THE TABLE2. HOW?
             */
        }
    });


    /** Load the products from DB belonging to this invoice **/
    List<Product> listPro = is.getInvoiceInfo(row); // TODO Listener!
    for (int i = 0; i < listPro.size(); i++) {
        invoiceInfo.insertRow(i, new Object[] {
                listPro.get(i).getID(),
                listPro.get(i).getName(),
                listPro.get(i).getType(),
                listPro.get(i).getPrice(),
                listPro.get(i).getQuantity()
        });
    }
    /** Scroll Panes **/
    JScrollPane scrollInv = new JScrollPane(table1);
    JScrollPane scrollPro = new JScrollPane(table2);

    /** Add everything to the panel **/
    panel.add(labelInv);
    panel.add(labelPro, "wrap");
    panel.add(scrollInv);
    panel.add(scrollPro);

    return panel;
}

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

public DefaultTableModel getInvoiceInfo(int id, DefaultTableModel model) {

    String data1[][] = {};
    String col1[] = {"ID", "Name", "Type", "Price", "Quantity"};
    DefaultTableModel info = new DefaultTableModel(data1,col1);

    /** Load products from DB **/
    List<Product> products = is.getInvoiceInfo(id);
    for (int i = 0; i < products.size(); i++) {
        info.insertRow(i, new Object[] {
                products.get(i).getID(),
                products.get(i).getName(),
                products.get(i).getType(),
                products.get(i).getPrice(),
                products.get(i).getQuantity()
        });
    }
    return info;
}

Ответы [ 3 ]

2 голосов
/ 20 марта 2012

Для обновления таблицы не требуется явного кода.insertRow () запускает для вас событие изменения, которое таблица слушает, и при необходимости перерисовывает себя.

Однако вы создаете новый экземпляр DefaultTableModel в методе getInvoiceInfo.Эта новая модель не прослушивается вашим JTable.Поэтому обновления с помощью insertRow () преобразуются в «пустышку», и ваш JTable в любом случае не имеет на него ссылку.

Быстрое исправление: изменить код на следующее:

public void getInvoiceInfo(int id, DefaultTableModel model) {

    /** Load products from DB **/
    List<Product> products = is.getInvoiceInfo(id);
    for (int i = 0; i < products.size(); i++) {
        model.insertRow(i, new Object[] {
                products.get(i).getID(),
                products.get(i).getName(),
                products.get(i).getType(),
                products.get(i).getPrice(),
                products.get(i).getQuantity()
        });
    }
}
1 голос
/ 20 марта 2012

1) создать JTable доступным для всех классов, пустот или методов,

  • везде можно получить DefaultTableModel от текущего JTable,

  • удаление строк обратным методом

код

if (myTableModel.getRowCount() > 0) {
    for (int i = myTableModel.getRowCount() - 1; i > 0; i--) {
         myTableModel.removeRow(i);
    }
}

2) неверный путь, как показано в коде, который вы разместили здесь путем повторного создания DefaulTableModel во время выполнения, тогда вам нужно добавить TableModel к текущему JTable

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

Вам нужно запустить событие, если вы изменяете напрямую, например, с помощью уведомления, методы:

void fireTableCellUpdated(int row, int column) 
void fireTableChanged(TableModelEvent e) 
void fireTableDataChanged() 
void fireTableRowsDeleted(int firstRow, int lastRow) 
void fireTableRowsInserted(int firstRow, int lastRow)
void fireTableRowsUpdated(int firstRow, int lastRow) 
void fireTableStructureChanged() 

документы здесь

Если вы использовали что-то вроде insertRow () или addColumn () on DefaultTreeModel эти события вызываются для вас, это зависит от того, как вы изменяете данные, если вы позже будете реализовывать свою собственную модель, эти методы станут важными, и важно, чтобы вы понимали, как они работают.

Следует отметить, что вызов вышеупомянутых методов из клиентского кода вне пользовательской модели - это дурной тон, и немного нет-нет, они предназначены для вызова самой моделью.

...