2016-08-24 13 views
0

私は数日間の回答を探しています。セルを編集した後にJTableを編集/更新する

私はJTableを持っています。これには、ローカルのSQLite-DBからのデータが入力されています。

ここでの目標は、ユーザーがセル(1 -max。available)を選択し、セルを編集し、入力をJtableで見ることです。さらに、この入力をSQL文に保存したいとします。

ユーザーが入力を行ってセルを離れるとき、私はポイントで立ち往生しています。 変更を表示するJTableが表示されません。

私は再描画を試みましたが、私はTableModelListenerを試しましたが、成功しませんでした。 JTableはまったく同じです。 それはおそらく大きな問題ではありません。しかし、私はここで少し助けを使うことができます。 ユーザーの入力を含む更新されたJTableを表示するという目標にはどのように到達すればよいですか?

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) { 

     } 

     }); 

} 
} 

ここに私のJTableModelクラスが行く

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; 

} 


} 
+0

https://docs.oracle.com/javase/tutorial/uiswing/components/table.html#modelchange – Fildor

答えて

1

秘密あなたが完全に投稿していないテーブルモデル、です。

それにもかかわらず、モデルはバッキングストレージからユーザーインターフェイスへの変換を実行します。逆もまた同様です。だから、あなたは何らかの理由で、指定されたセルに表示する正しい値を取得するためにgetValueAt()を実装する必要があります。 setValueAt()では、バッキングストアを更新して、getValueAt()の次回の呼び出しで新しい値が返されるようにする必要があります。また、コメントしたfireTableCellUpdatedを再度アクティブにすると、テーブル自体に新しい値をフェッチする必要があることがわかります。

+0

も参照してください。私はそれを調べるつもりです。 – Whitee

+0

実際に私はそれをしました。 Fildorのヒントも正しく、tableModel自体は柔軟性がありません。あなたは自分で書く必要があります。私はmtjをスクリプト化していなければならなかった。 tableModel全体をテーブルの各行を含むベクトルにデリートし、目的のセルの値を変更してから再度パックしなければなりませんでした。トリッキーなことはここでは、新しい値と行/列をtableModelにプッシュすることでした。それに加えて、元のテーブルを変更するSQL更新を実装しました。あなたの助けを捧げてください。 – Whitee

+0

また、実際の変更をトリガーする前述のactionListenerも実装しました。 TableModelクラスの新しいメソッドで新しい値、行、列にアクセスしました。 – Whitee

0

データを処理する前に、セルの編集を停止する必要があります。

二つのアプローチ:

  1. はテーブルがあなたの処理を行う前に、セルの編集を停止するために、あなたのActionListenerにコードを追加
  2. のフォーカスを失ったときに編集を停止するためにJTableののプロパティを使用します。

これらのアプローチの両方の例については、Table Stop Editingを参照してください。

関連する問題