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

Кусок из мануала:
Код: 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
Вопрос по JTable
    #38422389
oneHalf
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Чтобы изменения таблицы отображались в модель, надо переопределить 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
Вопрос по JTable
    #38422477
accept4ever
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
В модель данные загружаются из 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
Вопрос по JTable
    #38422482
accept4ever
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ошибся:
fireTableCellUpdated(rowIndex, colIndex);
...
Рейтинг: 0 / 0
Вопрос по JTable
    #38422487
accept4ever
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ещё добавлю, что приложение не имеет непосредственного коннекта к БД. rowSet получается из сервлета
...
Рейтинг: 0 / 0
Вопрос по JTable
    #38422975
oneHalf
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Блин, ну вы как маленький. Программист должен учиться сам искать в чем проблема, с помощью гуглов, мозгов - имеет значение только что сам. Замените CachedRowSet на обычный список объектов - тестовый, посмотрите так работает или не. Отсюда уже можно дальше копать и делать соответствующие выводы. В интернетах есть уже готовые реализации для модели таблицы - наберите CachedRowSetTableModel, не поленитесь - можно посмотреть как вообще народ делает и видоизменить под себя.

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

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

одын

два

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

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

Какой конкретно тип у вашей TableModel и где вы ей создаёте, и присваиваете таблице.
...
Рейтинг: 0 / 0
Вопрос по JTable
    #38423124
accept4ever
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
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
Вопрос по JTable
    #38423136
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Значит
table.getModel().addTableModelListener(this);
вызывается до
jTable1.setModel(ocrstm);
Так?
...
Рейтинг: 0 / 0
Вопрос по JTable
    #38423150
accept4ever
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
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
Вопрос по JTable
    #38423165
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
accept4everвызывается после применения модели
Из кода этого не очевидно. А так как нужна строгая последовательность, то есть смысл писать
ocrstm.addTableModelListener()
А не
table.getModel().addTableModelListener()
Потому что даже если эта последовательность сейчас соблюдается, то никто не мешает её нарушить в будущем.
Так как две операции находятно в явной зависимости, то не писать их последовательно в одном методе это раскладывать себе грабли.

И если вы нас не обманули и последовательность правильная, то остаётся просто продебажить fireTableCellUpdated().
...
Рейтинг: 0 / 0
Вопрос по JTable
    #38423166
oneHalf
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не обижайтесь - я вам предложил конкретный путь - заменить ваш дасурс на тестовый из нескольких строчек в виде списка, чтобы исключить возможные проблемы, недопонимания работы и т.д. с CachedRowSet. Вы это проигнорировали и по прежнему ждете готового ответа пуляя обрывками кода, который посчитали нужным выложить.
Ну пусть народ гадает, что у вас там за чем и где регистрируется и объявляется...
...
Рейтинг: 0 / 0
Вопрос по JTable
    #38423198
accept4ever
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
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
Вопрос по JTable
    #38423226
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
accept4everОбманывать Вас мне смысла нет, я же сюда за советом пришёл.
Понял свою ошибку. Я думал, что реализация setValueAt - это другой путь, чтобы не реализовывать TableModelListener.

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

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

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

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

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
Вопрос по JTable
    #38423302
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
accept4everВот:

На счет вашего "Вот:", oneHalf уже ответил выше. Откуда вы знаете что updateObject изменило состояние закешированых данных?
...
Рейтинг: 0 / 0
Вопрос по JTable
    #38425795
Фотография Penkov Vladimir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Возьмите DefaultTableModel вместо абстрактной. Куча проблем решится сразу
...
Рейтинг: 0 / 0
Вопрос по JTable
    #38426223
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Penkov VladimirВозьмите DefaultTableModel вместо абстрактной. Куча проблем решится сразу
Угу. И как её к другому источнику данных привязывать?
...
Рейтинг: 0 / 0
Вопрос по JTable
    #38426270
accept4ever
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Решил проблему путём добавления дополнительного вектора для хранения введенных данных.
Вот код, может кому пригодится:
Код: 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
Вопрос по JTable
    #38426293
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
accept4everНо вопрос на тему: почему rowSet.updateObject() не обновляет данные, остаётся открытым.

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

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
25 сообщений из 30, страница 1 из 2
Форумы / Java [игнор отключен] [закрыт для гостей] / Вопрос по JTable
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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