Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> JTable - попытка убрать недовведенный ряд, интересное поведение. а как бороться? 
V
    Опции темы
_Y_
Дата 31.12.2010, 14:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1651
Регистрация: 27.11.2006

Репутация: 1
Всего: 34



Обнаружил вот такой "феномен". Имеем табцицу JTable и две кнопки. Одна кнопка добавляет ряд к таблице, другая убирает все пустые ряды. Теперь делаем так (вариант А):
  • Запускаем программу
  • Добавляем кнопкой в таблицу несколько рядов.
  • Кликаем на какой-нибудь ячейке не первого ряда и начинаем вводить текст.
  • Не закончив ввод текста (т.е. при активном cellEditor), кликаем кнопку убирающую пустые ряды. Ряд с незаконченным вводом не убирается, а "зависает в воздухе".
  • Кликаем куда-нибудь в освободившееся поле. Получаем ошибку "ArrayIndexOutOfBoundsException"
Теперь вариант В:
  • Запускаем программу и делаем все то же самое, но после удаления рядов нигде не кликаем - просто любуемся на странно зависшую величину.
  • Кликаем нексколько раз на кнопке, добавляющей ряды. "Висящее в воздухе" значение оказывается на своем законном месте в таблице.
Вариант С: таблица помещена не на форму а в JScrollPane
  • Запускаем программу и делаем все то же самое. Значение в воздухе не повисает. Таблица остается пустой (если, конечно, в ней других данных не было).
  • Кликаем где угодно - никаких ошибок.
  • Кликаем нексколько раз на кнопке, добавляющей ряды. "Спрятавшееся" значение оказывается на своем законном месте в таблице.
Вот такая интересная фигня. Побороть ее несложно. Вопрос в том как побороть ее наиболее грамотно?

Вот код программы:
Код

import java.awt.BorderLayout;

import javax.swing.*;
import javax.swing.table.DefaultTableModel;

public class TableRowsAddRemove extends JFrame {


    private JTable jTable = new JTable(1, 1);

    public TableRowsAddRemove(){

        //Create table

        //VARIANTS A and B
        
        this.add(jTable, BorderLayout.CENTER);
        
        //VARIANT C
        
        //this.add(new JScrollPane(jTable), BorderLayout.CENTER);
        
        //Create buttons

        JButton button = new JButton("Add row");
        button.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                addRowToTable();
            }
        });
        this.add(button, BorderLayout.WEST);

        button = new JButton("Remove empty rows");
        button.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                removeEmptyRowsFromTable();
            }
        });
        this.add(button, BorderLayout.EAST);

        //Finalise the window

        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setSize(800, 600);
        this.setVisible(true);

    }//end constructor

    public static void main(String[] args) {

        new TableRowsAddRemove();                
    }

    //PRIVATE METHODS

    private void addRowToTable(){
        ((DefaultTableModel)jTable.getModel()).addRow(new String[0]);
    }

    private void removeEmptyRowsFromTable(){
        DefaultTableModel model = (DefaultTableModel)jTable.getModel();
        
        int nCols = model.getColumnCount();
        boolean rowIsEmpty;
        Object oValue;
        
        for(int r = model.getRowCount() - 1; r >=0; r--){
            
            rowIsEmpty = true;
            
            for(int c = 0; c < nCols; c++){
                oValue = model.getValueAt(r, c);
                if(oValue != null && (! "".equals(oValue.toString().trim()))){
                    rowIsEmpty = false;
                    break;
                }
            }
            
            if(rowIsEmpty){
                model.removeRow(r);
            }        
        }
    }

}



Это сообщение отредактировал(а) _Y_ - 31.12.2010, 14:32


--------------------
Я вот в этом поучаствовал: http://sbor-nik.appspot.com/kick.jsp?id=sbor5737960678883328 (на правах саморекламы:)
PM MAIL WWW   Вверх
jk1
Дата 31.12.2010, 14:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник
Сообщений: 1168
Регистрация: 17.10.2008
Где: Санкт-Петербург

Репутация: 21
Всего: 75



Мне известно два способа решения проблемы.
Первый:
Код

table.getCellEditor(row, column).stopCellEditing();

его можно вызывать для каждой ячейки каждого удаляемого столбца. Решение, прямо скажем, далекое от оптимального.
Второй способ - конфигурирование самой таблицы. При создании нужно будет сделать следующее:
Код

jTable.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);

При попытке нажатия на кнопку таблица теряет фокус и, согласно установленному property, выходит из режима редактирования автоматически.


--------------------
Opinions are like assholes — everybody has one
PM MAIL   Вверх
_Y_
Дата 31.12.2010, 15:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1651
Регистрация: 27.11.2006

Репутация: 1
Всего: 34



jk1, спасибо, jTable.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE); рулит. Я до такого простого решения не додумался.

Кстати, а где бы посмотреть как и почему это ClientProperty функционирует?


--------------------
Я вот в этом поучаствовал: http://sbor-nik.appspot.com/kick.jsp?id=sbor5737960678883328 (на правах саморекламы:)
PM MAIL WWW   Вверх
jk1
Дата 31.12.2010, 16:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник
Сообщений: 1168
Регистрация: 17.10.2008
Где: Санкт-Петербург

Репутация: 21
Всего: 75



Цитата

Кстати, а где бы посмотреть как и почему это ClientProperty функционирует? 

Client Properties - это механизм, обеспечивающий унификацию механизма задания различных свойств. Если посмотреть внимательно, то оказывается что он реализован в JComponent и наследуется подавляющим большинством Swing-компонент. На уровне конкретного компонента определяется только то, какие property он способен понять и применить. Ничего экстраординарного в этой модели нет, можно было бы с тем же успехом наделать специфических методов для каждого компонента. А изнутри компонента совершенно все равно каким образом было установлено то или иное свойство поведения\состояния.

Внутри компонента Client Properties хранятся в отдельной хэш-таблице.

Таким образом, Client Properties - всего лишь еще один способ конфигурирования Swing-компонент, наряду с setXXX() методами. Для справки можно пользоваться вот этой таблицей .

Что меня всегда удивляло, так это отсутствие нормальной документации от производителя по этому вопросу. И, кстати, гарантий работы этого механизма в будущем тоже. 

Это сообщение отредактировал(а) jk1 - 31.12.2010, 16:46


--------------------
Opinions are like assholes — everybody has one
PM MAIL   Вверх
_Y_
Дата 31.12.2010, 19:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1651
Регистрация: 27.11.2006

Репутация: 1
Всего: 34



jk1, теперь вроде понятно. Про такой хэш я знал. Чего не знал - что добавляя в таблицу Property уже определенное в данном компоненте (ссылка, которую ты привел), устанавливаешь значение этого Property.

Спасибо! smile

Это сообщение отредактировал(а) _Y_ - 31.12.2010, 19:41


--------------------
Я вот в этом поучаствовал: http://sbor-nik.appspot.com/kick.jsp?id=sbor5737960678883328 (на правах саморекламы:)
PM MAIL WWW   Вверх
dorogoyIV
Дата 1.1.2011, 12:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1503
Регистрация: 26.3.2007

Репутация: 36
Всего: 46



+ для jk1 (_Y_ с тебя), реально заслужил  smile 

PM MAIL   Вверх
_Y_
Дата 1.1.2011, 12:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1651
Регистрация: 27.11.2006

Репутация: 1
Всего: 34



dorogoyIV, а я сразу должное отдал smile  Как только ответ прочитал.


--------------------
Я вот в этом поучаствовал: http://sbor-nik.appspot.com/kick.jsp?id=sbor5737960678883328 (на правах саморекламы:)
PM MAIL WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   jk1
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, jk1.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: GUI и Java FX приложения | Следующая тема »


 




[ Время генерации скрипта: 0.0469 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.