Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Java [игнор отключен] [закрыт для гостей] / Вопрос по JTable / 25 сообщений из 30, страница 1 из 2
09.10.2013, 17:55:05
    #38421954
accept4ever
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по JTable
Добрый день. Есть необходимость при изменении содержимого ячейки в таблице, получить это изменённое значение. На таблицу натянута модель, реализующая абстрактную.

Кусок из мануала:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
import javax.swing.event.*;
import javax.swing.table.TableModel;

public class SimpleTableDemo ... implements TableModelListener {
    ...
    public SimpleTableDemo() {
        ...
        table.getModel().addTableModelListener(this);
        ...
    }

    public void tableChanged(TableModelEvent e) {
        int row = e.getFirstRow();
        int column = e.getColumn();
        TableModel model = (TableModel)e.getSource();
        String columnName = model.getColumnName(column);
        Object data = model.getValueAt(row, column);

        ...// Do something with the data...
    }
    ...
}


Мой код:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
        
  rpf.jTable1.getModel().addTableModelListener(
        new TableModelListener() 
        {            
                @Override
                public void tableChanged(TableModelEvent e) 
                {
                    int row = e.getFirstRow();
                    int column = e.getColumn();
                    TableModel model = (TableModel)e.getSource();
                    String columnName = model.getColumnName(column);
                    Object data = model.getValueAt(row, column);                
                    System.out.println(data);                
                }
        }
    ); 


Мой код не работает. Не могу понять, в чём дело.
Заранее спасибо.
...
Рейтинг: 0 / 0
10.10.2013, 09:37:18
    #38422389
oneHalf
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по JTable
Чтобы изменения таблицы отображались в модель, надо переопределить setValueAt. Это подробно описано практически везде.
Что то типа такого
Код: java
1.
2.
3.
4.
5.
6.
7.
       @Override
        public void setValueAt(Object newVal, int row, int col) {
            Vector<Object> aRow = data.elementAt(row);
            aRow.remove(col);
            aRow.insertElementAt(newVal, col);
            fireTableCellUpdated(row, col);
        }
...
Рейтинг: 0 / 0
10.10.2013, 10:25:07
    #38422477
accept4ever
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по JTable
В модель данные загружаются из OracleCachedRowSet (rowSet в коде)
Переопределил setValueAt:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
@Override
    public void setValueAt(Object newVal, int rowIndex, int colIndex) 
    {       
        try
        {
            rowSet.absolute(rowIndex+1);            
            rowSet.updateObject(colIndex+1, newVal);            
            fireTableCellUpdated(rowIndex+1, colIndex+1);          
        }
        catch (SQLException e) 
        {				
            throw new NullPointerException(e.getMessage());
        }
                
    }


На таблице по прежнему не видно изменений
...
Рейтинг: 0 / 0
10.10.2013, 10:26:53
    #38422482
accept4ever
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по JTable
Ошибся:
fireTableCellUpdated(rowIndex, colIndex);
...
Рейтинг: 0 / 0
10.10.2013, 10:28:49
    #38422487
accept4ever
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по JTable
Ещё добавлю, что приложение не имеет непосредственного коннекта к БД. rowSet получается из сервлета
...
Рейтинг: 0 / 0
10.10.2013, 14:29:39
    #38422975
oneHalf
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по JTable
Блин, ну вы как маленький. Программист должен учиться сам искать в чем проблема, с помощью гуглов, мозгов - имеет значение только что сам. Замените CachedRowSet на обычный список объектов - тестовый, посмотрите так работает или не. Отсюда уже можно дальше копать и делать соответствующие выводы. В интернетах есть уже готовые реализации для модели таблицы - наберите CachedRowSetTableModel, не поленитесь - можно посмотреть как вообще народ делает и видоизменить под себя.

И вообще CachedRowSet - специфичная штука, которая на стороне сервера сжирает приличные размеры памяти, зависящие от размера подмножества в результирующем запросе. Т.е. если строк тысяча, другая еще норм - но десятки тысяч - будет кирдык.

Вот ссылки первые, что были, а то вдруг у вас гугл забанен

одын

два

Плюс, насколько я помню, все изменения в CachedRowSet фиксируются отдельным методом acceptChanges(). Такого не увидел.
...
Рейтинг: 0 / 0
10.10.2013, 15:12:47
    #38423066
accept4ever
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по JTable
Была описана конкретная проблема в конкретных условиях, Вы предложили альтернативный вариант решения данной проблемы не через событие, а прямо в модели. Предложенный Вами вариант не дал результата уже по какой-то другой причине. Если вы не знаете в чём причина, то не вопрос, вы мне ничего не должны. Но ваш последний совет равносилен фразе "Почитайте Хорстманна\Корнелла, Том 1, там где-то про Swing есть".

Спасибо, конечно, за ответ.
Но если Вы не удосужились вникнуть в суть вопроса и Вам нечего сказать по существу, можно было бы и не писать.
...
Рейтинг: 0 / 0
10.10.2013, 15:32:11
    #38423104
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по JTable
accept4ever,

Какой конкретно тип у вашей TableModel и где вы ей создаёте, и присваиваете таблице.
...
Рейтинг: 0 / 0
10.10.2013, 15:40:18
    #38423124
accept4ever
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по JTable
Blazkowicz,
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
public class OracleCachedRowSetTableModel extends AbstractTableModel implements TableModel
{	
    private static final long serialVersionUID = 1L;    	
    private OracleCachedRowSet rowSet;

    public OracleCachedRowSetTableModel(OracleCachedRowSet rs)
    {
        rowSet = rs;
    }
       
    @Override
    public boolean isCellEditable(int row, int column)
    {                
        return true;
    }
      
    @Override
    public Object getValueAt(int rowIndex, int columnIndex) 
    {
        try 
        {	
            try 
            {                
                rowSet.absolute(rowIndex+1);
                return (rowSet.getString(columnIndex+1));
            } 
            catch (SQLException e) 
            {				
                return null;
            }
        }
        catch (NullPointerException  e) 
        {
              return null;
        }  
    }  
    
    @Override
    public void setValueAt(Object newVal, int rowIndex, int colIndex) 
    {       
        try
        {
            rowSet.absolute(rowIndex+1);            
            rowSet.updateObject(colIndex+1, newVal);                        
            fireTableCellUpdated(rowIndex, colIndex);          
        }
        catch (SQLException e) 
        {				
            throw new NullPointerException(e.getMessage());
        }
                
    }   



Остальные методы тоже переопределены, но к данной теме не относятся.
Присвоение модели в таком виде:

Код: java
1.
2.
3.
OracleCachedRowSet ocrs = //получаем из сервлета;
OracleCachedRowSetTableModel ocrstm = new OracleCachedRowSetTableModel(ocrs);        
jTable1.setModel(ocrstm); 
...
Рейтинг: 0 / 0
10.10.2013, 15:43:59
    #38423136
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по JTable
Значит
table.getModel().addTableModelListener(this);
вызывается до
jTable1.setModel(ocrstm);
Так?
...
Рейтинг: 0 / 0
10.10.2013, 15:51:07
    #38423150
accept4ever
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по JTable
rpf.jTable1.getModel().addTableModelListener(
new TableModelListener()
{
@Override
public void tableChanged(TableModelEvent e)
{
int row = e.getFirstRow();
int column = e.getColumn();
TableModel model = (TableModel)e.getSource();
String columnName = model.getColumnName(column);
Object data = model.getValueAt(row, column);
System.out.println(data);
}
}
);

вызывается после применения модели
...
Рейтинг: 0 / 0
10.10.2013, 15:57:03
    #38423165
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по JTable
accept4everвызывается после применения модели
Из кода этого не очевидно. А так как нужна строгая последовательность, то есть смысл писать
ocrstm.addTableModelListener()
А не
table.getModel().addTableModelListener()
Потому что даже если эта последовательность сейчас соблюдается, то никто не мешает её нарушить в будущем.
Так как две операции находятно в явной зависимости, то не писать их последовательно в одном методе это раскладывать себе грабли.

И если вы нас не обманули и последовательность правильная, то остаётся просто продебажить fireTableCellUpdated().
...
Рейтинг: 0 / 0
10.10.2013, 15:57:50
    #38423166
oneHalf
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по JTable
Не обижайтесь - я вам предложил конкретный путь - заменить ваш дасурс на тестовый из нескольких строчек в виде списка, чтобы исключить возможные проблемы, недопонимания работы и т.д. с CachedRowSet. Вы это проигнорировали и по прежнему ждете готового ответа пуляя обрывками кода, который посчитали нужным выложить.
Ну пусть народ гадает, что у вас там за чем и где регистрируется и объявляется...
...
Рейтинг: 0 / 0
10.10.2013, 16:14:42
    #38423198
accept4ever
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по JTable
Blazkowicz,

Обманывать Вас мне смысла нет, я же сюда за советом пришёл.
Понял свою ошибку. Я думал, что реализация setValueAt - это другой путь, чтобы не реализовывать TableModelListener.
Сейчас tableChanged срабатывает, но возвращает значение из модели ocrstm, а не введённое в таблицу на форме.

Вот полный листинг кода (листинг модели чуть выше) в классе, который управляет формой:

public OracleCachedRowSet getReportParametersList(String reportName)
{
ParameterVector requestVector = new ParameterVector();
requestVector.add(new Parameter("action","GET_ACTION_PARAMETERS_LIST"));
requestVector.add(new Parameter("action_name",reportName.toUpperCase()));
responseObject = osr.readFromServlet(requestVector);
oracleCachedRowSet = (OracleCachedRowSet)responseObject;
if (oracleCachedRowSet.size() == 0)
{
javax.swing.JOptionPane.showMessageDialog(null,"Такого отчёта не существует...\n");
return null;
}
else
{
return oracleCachedRowSet;
}
}

public void showParametersListForm()
{
rpf = new ReportParametersFrame(this);
rpf.setModal(true);
rpf.setLocationRelativeTo(rf);
ocrstm = new OracleCachedRowSetTableModel(getReportParametersList(reportName));
rpf.jTable1.setModel(ocrstm);
rpf.jTable1.getModel().addTableModelListener(
new TableModelListener()
{
@Override
public void tableChanged(TableModelEvent e)
{
int row = e.getFirstRow();
int column = e.getColumn();
TableModel model = (TableModel)e.getSource();
String columnName = model.getColumnName(column);
Object data = model.getValueAt(row, column);
System.out.println(data);
}
}
);
rpf.setVisible(true);
}

oneHalf, я не обижаюсь. В OracleCachedRowSet есть данные, они видны на таблице при применении модели. Проблема ведь в другом совсем.
...
Рейтинг: 0 / 0
10.10.2013, 16:26:35
    #38423226
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по JTable
accept4everОбманывать Вас мне смысла нет, я же сюда за советом пришёл.
Понял свою ошибку. Я думал, что реализация setValueAt - это другой путь, чтобы не реализовывать TableModelListener.

В первом вопросе не было никаких setValueAt();

accept4everСейчас tableChanged срабатывает, но возвращает значение из модели ocrstm, а не введённое в таблицу на форме.

Значит никто не сохранил введенное значение в модели.
...
Рейтинг: 0 / 0
10.10.2013, 16:40:04
    #38423265
accept4ever
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по JTable
BlazkowiczВ первом вопросе не было никаких setValueAt();
Правильно. Когда я задавал первый вопрос setValueAt и не был реализован. Реализовать предложил комрад oneHalf. Я подумал, что это другой способ и, если реализовать setValueAt, то не нужно будет реализовывать TableModelListener.

BlazkowiczЗначит никто не сохранил введенное значение в модели.
Так в этом и заключается вопрос. Если setValueAt сейчас уже реализован, более того реализован TableModelListener, то почему не сохраняется введенное значение никуда вообще? Ни в модель ни в system.out не выводится.
...
Рейтинг: 0 / 0
10.10.2013, 16:42:32
    #38423275
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по JTable
Всё понял. Ларчик просто открывался:
Код: java
1.
2.
3.
4.
5.
public abstract class AbstractTableModel implements TableModel, Serializable
{
    public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
    }
}
...
Рейтинг: 0 / 0
10.10.2013, 16:45:55
    #38423282
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по JTable
Когда юзер что-то вводит, вызывается setValueAt() - который абстрактная модель не реализует, так как у неё нет хранилища. На кой хрен его оставили пустым, а не абстрактным - не понятно.
setValueAt() должен вызывать fire, который просто передаёт местонахождение изменений.
Если getValueAt() у вас возвращает старое значение, то собственно всё зависит от того как вы реализовали setValueAt().
...
Рейтинг: 0 / 0
10.10.2013, 16:49:29
    #38423291
accept4ever
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по JTable
Вот:

public void setValueAt(Object newVal, int rowIndex, int colIndex)
{
try
{
rowSet.absolute(rowIndex+1);
rowSet.updateObject(colIndex+1, newVal);
fireTableCellUpdated(rowIndex, colIndex);
}
catch (SQLException e)
{
throw new NullPointerException(e.getMessage());
}

}
...
Рейтинг: 0 / 0
10.10.2013, 16:56:31
    #38423302
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по JTable
accept4everВот:

На счет вашего "Вот:", oneHalf уже ответил выше. Откуда вы знаете что updateObject изменило состояние закешированых данных?
...
Рейтинг: 0 / 0
13.10.2013, 18:45:43
    #38425795
Penkov Vladimir
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по JTable
Возьмите DefaultTableModel вместо абстрактной. Куча проблем решится сразу
...
Рейтинг: 0 / 0
14.10.2013, 11:10:36
    #38426223
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по JTable
Penkov VladimirВозьмите DefaultTableModel вместо абстрактной. Куча проблем решится сразу
Угу. И как её к другому источнику данных привязывать?
...
Рейтинг: 0 / 0
14.10.2013, 11:38:05
    #38426270
accept4ever
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по JTable
Решил проблему путём добавления дополнительного вектора для хранения введенных данных.
Вот код, может кому пригодится:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
@Override
    public Object getValueAt(int rowIndex, int columnIndex) 
    {
        Object object = null;
        try 
        {
            if (columnIndex+1 <= rowSet.getMetaData().getColumnCount())
            {
                rowSet.absolute(rowIndex+1);
                object = rowSet.getString(columnIndex+1);                
            }
            else
            {
               object = vector.get(rowIndex);   
            }
        } 
        catch (SQLException e) 
        {				
            return null;
        }
        catch (NullPointerException  e) 
        {
            return null;
        }  
        return object;
    }  
    
    @Override
    public void setValueAt(Object newVal, int rowIndex, int colIndex) 
    {       
        try
        {
            if (colIndex+1 <= rowSet.getMetaData().getColumnCount())
            {
                rowSet.absolute(rowIndex+1);            
                rowSet.updateObject(colIndex+1, newVal);                        
                fireTableCellUpdated(rowIndex, colIndex);          
            }
            else
            {
                vector.set(rowIndex, newVal);
            }
        }
        catch (SQLException e) 
        {				
            throw new NullPointerException(e.getMessage());
        }
                
    }


Но вопрос на тему: почему rowSet.updateObject() не обновляет данные, остаётся открытым.
Предложенный выше rowSet.acceptChanges() нужен для того, чтобы постить изменения сразу в БД.
...
Рейтинг: 0 / 0
14.10.2013, 11:48:39
    #38426293
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по JTable
accept4everНо вопрос на тему: почему rowSet.updateObject() не обновляет данные, остаётся открытым.

А почему должен? Что говорит дока к методу?
...
Рейтинг: 0 / 0
14.10.2013, 12:14:41
    #38426342
accept4ever
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по JTable
Вроде как должен:

void updateObject(int columnIndex, Object x) throws SQLException

Updates the designated column with an Object value. The updater methods are used to update column values in the current row or the insert row. The updater methods do not update the underlying database; instead the updateRow or insertRow methods are called to update the database.
...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / Вопрос по JTable / 25 сообщений из 30, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]