1 Востаннє редагувалося Lujok (10.08.2015 14:44:58)

Тема: Оновити jTable після додавання колонки, рядка в базу даних SQLite ?

Допоможіть з реалізацією моделі таблиці jTable  щоб вона оновлювалась відразу після додавання рядків та колонок в БД SQLite  .  Моя модель таблиці успадковується від  AbstractTableModel.  Я створював кнопки і для них Listenerи . В базу даних добавляються і колонки , і рядки,  але в таблиці  jTable  зміни зявляються тільки після перезапуску програми.
Весь код давати не буду , бо він величенький:
це модель таблиці :
public class t2estDBTableModel extends AbstractTableModel{
    private static Connection conn;// зєднання з базою даних
    private Object[][] contents;// зберігає дані
    private String[] columnNames; // зберігає імена колонок
    private Class[] columnClasses; // зберігає типи колонок
    private ResultSet rs =null;
    private DatabaseMetaData meta;
    JTable jtable;
    String tableName ;
    int count ;
   
     public t2estDBTableModel(Connection conn,JTable jtable,
String tableName)
            throws SQLException {
        super();
       this.jtable=jtable;
       this.tableName=tableName;
        t2estDBTableModel.conn = conn;
        getTableContents(tableName);
    }
      public void getTableContents(String tableName)  //багато кода, тому я пишу лише назву метода.  виводить в    //    jTable  дані з БД.
   
 
          //  this.fireTableStructureChanged();
    @Override
    public int getRowCount() {
         return contents.length;
    }
    @Override
    public int getColumnCount() {
       if (contents.length == 0) {
            return 0;
        } else {
            return contents[0].length;
        }
    }
    @Override
    public Object getValueAt(int row, int column) {
       return contents[row][column];
    } 
    @Override
    public Class<?> getColumnClass(int col) {
        return columnClasses[col];
    }
    @Override
    public String getColumnName(int col) {
         return columnNames[col];
    }
    public boolean isCellEditable(int i, int i1) {
        return true;
    }
    @Override
    public void setValueAt(Object o, int row, int column) // Реалізує оновлення даних в ячейках таблиці.
         
 
    }

Listener для кнопки . Клацнувши по ній добавляється нова строка в БД . ТРЕБА ЩЕ ЩОБ  ВІДРАЗУ ОНОВЛЮВАЛИСЬ     ДАНІ І  В jTable !!!  :
public class AddRowButtonListener   implements ActionListener {
    Connection con;
  String tableName;
  private JTable jtable;
  // TableModel mod ;
    PreparedStatement pstmtAddRow = null;
    JTable table ;
   
    AddRowButtonListener(Connection con, String tableName,TableModel mod,   JTable table) {
      this.con = con;
      this.tableName = tableName; 
     this.table = table;     
    }
    @Override
    public void actionPerformed(ActionEvent ae) {
        try {
            String sql = "INSERT INTO '"+tableName+"'(UA,EN,RU) VALUES (? , ?,?)" ;
            pstmtAddRow = con.prepareStatement(sql);
              pstmtAddRow.setObject(2, (String)"1hhhh");
              pstmtAddRow.setObject(3, (String)"2hhhh");
               pstmtAddRow.setObject(1, (String)"3hhhh");
                 pstmtAddRow.executeUpdate();

        } catch (SQLException ex) {
            Logger.getLogger(AddRowButtonListener.class.getName()).log(Level.SEVERE, null, ex);
        }   
    }   
}


Я читав що треба використовувати :fireTableStructureChanged(); , fireTableRowsInserted(row, row); та інші...
а ось як  , де  не знаю . Розраховую на допомогу.

2

Re: Оновити jTable після додавання колонки, рядка в базу даних SQLite ?

Прихований текст

Будь ласка!
(правила з форуму)

3.2. Не забувайте про наявність тегів code.
3.9. Якщо ви використовуєте дуже великі фрагменти коду або великі цитати, доцільним є використання спойлера.

Просто реально очі болять вчитуватися в ту кучу тексту, що ви розмістили.

3 Востаннє редагувалося Lujok (10.08.2015 14:51:38)

Re: Оновити jTable після додавання колонки, рядка в базу даних SQLite ?

BarsicPlus написав:
Прихований текст

Будь ласка!
(правила з форуму)

3.2. Не забувайте про наявність тегів code.
3.9. Якщо ви використовуєте дуже великі фрагменти коду або великі цитати, доцільним є використання спойлера.

Просто реально очі болять вчитуватися в ту кучу тексту, що ви розмістили.

А ЩО ЦЕ ТАКЕ І ЯК НИМ КОРИСТУВАТИСЯ.?  я то бачив в правилах про них написано ...

4 Востаннє редагувалося fed_lviv (10.08.2015 15:48:41)

Re: Оновити jTable після додавання колонки, рядка в базу даних SQLite ?

На рахунок коду Вам BarsicPlus написав. А в загальному, після того, як у Вас змінилася структура таблиці (нові колонки або видалені старі колонки) викликаєте метод fireTableStructureChanged(), який сповіщає що треба оновити вигляд таблиці оскільки відбулися зміни.

5

Re: Оновити jTable після додавання колонки, рядка в базу даних SQLite ?

fed_lviv написав:

На рахунок коду Вам BarsicPlus написав.

На рахунок якого коду, де ... щось я не бачу.

fed_lviv написав:

А в загальному, після того, як у Вас змінилася структура таблиці (нові колонки або видалені старі колонки) викликаєте метод fireTableStructureChanged(), який сповіщає що треба оновити вигляд таблиці оскільки відбулися зміни.

Що треба викликати fireTableStructureChanged  я і так знаю. А ось де ? Крім того, наскільки мені відомо , цього метода буде недостатньо ...

6 Востаннє редагувалося fed_lviv (10.08.2015 18:18:00)

Re: Оновити jTable після додавання колонки, рядка в базу даних SQLite ?

Lujok написав:

На рахунок якого коду, де ... щось я не бачу.

Йокалемене, щоб код "світився"!!!

Lujok написав:

Що треба викликати fireTableStructureChanged  я і так знаю. А ось де ? Крім того, наскільки мені відомо , цього метода буде недостатньо ...

Так, як код у вас "дуже гарний", тому, ще раз говорю в загальному. Ось методи на любий смак, вибирайте, який Вам підходить:
- fireTableCellUpdated(int row, int column)
- fireTableChanged(TableModelEvent e)
- fireTableDataChanged()
- fireTableRowsDeleted(int firstRow, int lastRow)
- fireTableRowsInserted(int firstRow, int lastRow)
- fireTableRowsUpdated(int firstRow, int lastRow)
- fireTableStructureChanged()

З Вашого коду: "Listener для кнопки . Клацнувши по ній добавляється нова строка в БД . ТРЕБА ЩЕ ЩОБ  ВІДРАЗУ ОНОВЛЮВАЛИСЬ     ДАНІ І  В jTable !!!  :" Тобто нові колонки в БД не добавляються, а додаються записи (рядки), тому Вам достатньо метода, наприклад fireTableDataChanged()
public void fireTableDataChanged()
Notifies all listeners that all cell values in the table's rows may have changed. The number of rows may also have changed and the JTable should redraw the table from scratch. The structure of the table (as in the order of the columns) is assumed to be the same.

У Вашому коді, я не бачу (можливо погано дивився), що модель таблиці отримала нові дані. Нові дані Ви вставили в БД. А ні модель, ні тимпаче таблиця про нові дані нічого не знають, тому один з варіантів:1. Вставляєте нові записи в БД.
2. Робити запит до БД і оновлюєте дані в моделі таблиці 3. Після цього викликайте метод fireTableXXX, щоб оповістити таблицю про зміну даних в її моделі.
P.S. Я розумію, що Ваш код тестовий, але все ж таки, не називайте так класи t2estDBTableModel!!!

7 Востаннє редагувалося Lujok (11.08.2015 11:08:48)

Re: Оновити jTable після додавання колонки, рядка в базу даних SQLite ?

fed_lviv написав :
З Вашого коду: "Listener для кнопки . Клацнувши по ній добавляється нова строка в БД . ТРЕБА ЩЕ ЩОБ  ВІДРАЗУ ОНОВЛЮВАЛИСЬ     ДАНІ І  В jTable !!!  :" Тобто нові колонки в БД не добавляються,

Добавляються в БД і строки і колонки нормально.

fed_lviv написав : 2. Робити запит до БД і оновлюєте дані в моделі таблиці 3. Після цього викликайте метод fireTableXXX, щоб оповістити таблицю про зміну даних в її моделі.

Я вірно розумію:
     треба створити метод в моделі   (  наприклад AddRow(),  AddColumn() )  таблиці в якому буде запит до БД  "SELECT..." і результат запиту заноситиметься в (в моєму випадку) двомірний масив private Object[][] contents в якому зберігаються дані для таблиці jTable ;  потім в цьому ж методі викликаєм  fireTableXXX.  Потім вже в  Listenerі (для кнопки )  викликаємо метод  AddRow(), або  AddColumn() . ?

8 Востаннє редагувалося fed_lviv (11.08.2015 13:25:03)

Re: Оновити jTable після додавання колонки, рядка в базу даних SQLite ?

Lujok написав:

Добавляються в БД і строки і колонки нормально.

А, хто Вам казав, що не нормально. Я ж писав, що з Вашого коду я бачу тільки додавання рядків, тобто структура таблиці не змінюється, тобто достатньо метода, fireTableDataChanged(), хоч за бажанням можете взяти інший.
На рахунок, Вашої моделі таблиці, я взагалі не розумію чому ви використовуєте, масиви, а не списки. А саме краще, почитайте Портянкіна, у нього досить файно описано модель таблиці для роботи з БД.А ось, простенький приклад:

public class MyTableModel extends AbstractTableModel {
    private ArrayList<ArrayList<Object>> data = new ArrayList<ArrayList<Object>>();
    private ArrayList<String> columnNames = new ArrayList<String>();
    private ArrayList<Class<?>> columnTypes = new ArrayList<Class<?>>();

    // метод завантаження даних (результат запиту до БД задається)
    public void setData(ResultSet result) throws SQLException {
        data.clear();
        columnNames.clear();
        columnTypes.clear();
        getColumnProperties(result);
        getData(result);
        fireTableDataChanged();
    }

    private void getColumnProperties(ResultSet result) throws SQLException {
        for (int i = 0; i < result.getMetaData().getColumnCount(); i++) {
            columnNames.add(result.getMetaData().getColumnName(i + 1));
            try {
                Class<?> type = Class.forName(result.getMetaData()
                        .getColumnClassName(i + 1));
                columnTypes.add(type);
            } catch (ClassNotFoundException e) {
               e.printStackTrace();
            }
        }
    }

    private void getData(ResultSet result) throws SQLException {
        while (result.next()) {
            ArrayList<Object> row = new ArrayList<Object>();
            for (int i = 0; i < result.getMetaData().getColumnCount(); i++) {
                row.add(result.getObject(i + 1));
            }
            data.add(row);
        }
    }
...
...
...