简体   繁体   中英

Edit /Update JTable after editing Cells

I've been searching for answers for days now.

I have a JTable, that's populated with data from a local SQLite-DB.

Now the target here is, that the user selects cells(1 -max. available), edits the cell and sees his Input in the Jtable. Further, I want to save this Input for a SQL-Statement.

Now I am stuck at the Point when the user makes his Input and leaves the cell. I don't get the JTable to Display the Change.

I tried repaint, I tried TableModelListener, but without success. JTable remains the very same. That's probably not a big matter. But I could use a little help here. How do I reach the goal of displaying the updated JTable including the user's Input ?

package views;

import java.awt.EventQueue;
import java.awt.HeadlessException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTable;
import javax.swing.WindowConstants;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import main.DatenHolen;



public class GUI extends JFrame {


private static final long serialVersionUID = 1L;

public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
        @Override
        public void run() {
            new GUI().setVisible(true);
        }
    });
}

private JButton btLoad;
public JTable table;
final static String DB_PATH = "C:\\DB.db"; //
private JButton btnDBNeuSpeichern;
private JButton btnDatenbankVergleich;
private JButton btnAusgewhlteDateienLoeschen;
private JButton btnZuLoeschendeDateien;

public GUI() throws HeadlessException {

    createComponents();  //Formular und Bestandteile aufbauen
    createEvents(); //Events und Logiken erstellen

}

private void createComponents() {
    setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    getContentPane().setLayout(null);

    btLoad = new JButton("Datenbank laden");
    btLoad.addMouseListener(new MouseAdapter() {
        @Override
        public void mouseClicked(MouseEvent arg0) {

         loadData();            

        }
    });
    btLoad.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent arg0) {
        }
    });
    btLoad.setBounds(537, 25, 183, 28);

    getContentPane().add(btLoad);

    btnDBNeuSpeichern = new JButton("Laufwerke neu in DB laden");

    btnDBNeuSpeichern.setBounds(537, 65, 183, 28);
    getContentPane().add(btnDBNeuSpeichern);

    btnDatenbankVergleich = new JButton("Datenbank mit bisheriger vergleichen");
    btnDatenbankVergleich.setBounds(537, 105, 273, 28);
    getContentPane().add(btnDatenbankVergleich);

    btnAusgewhlteDateienLoeschen = new JButton("Ausgewählte Dateien löschen");
    btnAusgewhlteDateienLoeschen.setBounds(537, 145, 205, 28);
    getContentPane().add(btnAusgewhlteDateienLoeschen);

    btnZuLoeschendeDateien = new JButton("Zu löschende Dateien selektieren");
    btnZuLoeschendeDateien.setBounds(537, 183, 205, 28);
    getContentPane().add(btnZuLoeschendeDateien);

    setSize(918, 850);

}

private void createEvents() {

    btnDBNeuSpeichern.addMouseListener(new MouseAdapter() {
        @Override
        public void mouseClicked(MouseEvent arg0) {

        }
    });

}


private void loadData() {


    DatenHolen DBLaden = new DatenHolen(); // DBQuers-Object


    table = new JTable(DBLaden.run(DB_PATH)); //DB_PATH is the SQLite-DB including path ; Method is returning TableModel and therefore populating the Jtable
    table.getModel().addTableModelListener(new TableModelListener(){

        @Override
        public void tableChanged(TableModelEvent arg0) {

        }

       }); 

} 
}

Here goes my JTableModel-Class

package main;


import javax.swing.table.DefaultTableModel;

public class TableModelSpezial extends DefaultTableModel{

private static final long serialVersionUID = 1L;



public boolean isCellEditable( int rowIndex, int columnIndex )
{
  return true; //falls Änderung auf eine Zeile beschränkt wird, zb 1. dann columnIndex==0;
}


public void setValueAt(Object aValue, int rowIndex, int columnIndex) {

    System.out.println(aValue);
    System.out.println(rowIndex);
    System.out.println(columnIndex);

  // fireTableCellUpdated(rowIndex, columnIndex);  

}



}

// TableModel & SQL_Build

package main;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.Statement;
import java.util.Vector;
import javax.swing.table.TableModel;

public class DatenHolen extends Thread{


public TableModelSpezial tableModel= new TableModelSpezial();


public TableModel run(String DB_PATH) {

    try (Connection conn = DriverManager.getConnection("jdbc:sqlite:" + DB_PATH);  //put up conn to db
            Statement stmt = conn.createStatement()) {

        ResultSet rs = stmt.executeQuery(" select* from dateien");
        ResultSetMetaData metaData = rs.getMetaData();

        // Names of columns
        Vector<String> columnNames = new Vector<String>();
        int columnCount = metaData.getColumnCount();
        for (int i = 1; i <= columnCount; i++) { //Test 1=2, damit i=1 die Spaltennummerierung darstellt

            columnNames.add(metaData.getColumnName(i));
        }

        // Data of the table
        Vector<Vector<Object>> data = new Vector<Vector<Object>>();
        while (rs.next()) {

            Vector<Object> vector = new Vector<Object>();
            for (int i = 1; i <= columnCount; i++) {

                vector.add(rs.getObject(i));

            }

            data.add(vector);
            System.out.println(vector);

        }

        tableModel.setDataVector(data, columnNames);

    } catch (Exception e) {
        e.printStackTrace();
    }   

    return tableModel;

}


}

The secret is in the table model, which you have not posted completely.

Nevertheless, the model performs the translation from your backing storage to the user interface and vice versa. So, you somehow need to implement getValueAt() to retrieve the correct value to display at a given cell. In setValueAt(), you have to update your backing store, so that the next call to getValueAt() will return the new value. In addition, you reactivate your commented fireTableCellUpdated, so that the table itself knows that a new value has to be fetched.

You need to stop editing on the cell before you process the data.

Two approaches:

  1. use a property of the JTable to stop editing when the table loses focus
  2. add code to your ActionListener to stop editing of the cell before doing your processing.

Check out Table Stop Editing for examples of both of these approaches.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM