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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как скрыть/восстановить столбец в JTable?.. Думаю, можно добавить в FAQ.. 
:(
    Опции темы
Kurt
Дата 6.1.2005, 19:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Увлеченный
***


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

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



Не так давно на форуме промелькнул вопрос о том, как можно скрыть столбцы в JTable. В ответ предлагалось использовать removeColumn(). Однако, в таком случае довольно затруднительно обратно показать те столбцы, что были скрыты. Информация из сети и мудрые люди натолкули меня на довольно изящное, как мне кажется, решение - поработать с TableModel. Ведь именно там хранятся данные и там описываются методы доступа к ним.
В итоге, получилось так:
В класса TableModel будем хранить не только сами данные и заголовки, но и некий объект содержащий список видимых столбцов. У меня - это вектор, хотя можно использовать все, что душе угодно. Индекс эл-та вектора - номер ОТОБРАЖАЕМОГО столбца, а значение - индекс "постоянного" столбца таблицы. А потом переопределим методы получения данных из модели.
..Н-да.. Туманно объяснил.. Лучше на примере. Я взял стандартный сановский пример и чуток подкорректировал его.

Итак, создаем нашу TableModel:
Код

..
class MyTableModel extends AbstractTableModel {

//это наши заголоки:
       final String[] columnNames = {"First Name",
                                     "Last Name",
                                     "Sport",
                                     "# of Years",
                                     "Vegetarian"};

//данные таблицы:
       final Object[][] data = {
           {"Mary", "Campione",
            "Snowboarding", new Integer(5), new Boolean(false)},
           {"Alison", "Huml",
            "Rowing", new Integer(3), new Boolean(true)},
           {"Kathy", "Walrath",
            "Chasing toddlers", new Integer(2), new Boolean(false)},
           {"Sharon", "Zakhour",
            "Speed reading", new Integer(20), new Boolean(true)},
           {"Angela", "Lih",
            "Teaching high school", new Integer(4), new Boolean(false)}
       };

//вектор видимых столбцов:
       Vector visible_columns;

//конструктор:
       MyTableModel(){
 //здесь мы создаем наш вектор и заполняем его начальными значениями.
           visible_columns = new Vector();
           for (int i=0; i<columnNames.length; i++){
                  visible_columns.add(new Integer(i));
           }

       }
..


А теперь переопределим основные методы:
Код

..
     public int getColumnCount() { //получаем кол-во ВИДИМЫХ столбцов
           return visible_columns.size();
       }

..

       public String getColumnName(int col) { //получаем заголовок
           //для этого с помощь вектора видимых столбцов получаем номер столбца,
   // к-й надо отобразить
           int true_column = ((Integer)visible_columns.get(col)).intValue();
           return columnNames[true_column];
       }

       public Object getValueAt(int row, int col) {
    //аналогично getColumnName
           int true_column = ((Integer)visible_columns.get(col)).intValue();
           return data[row][true_column];
       }
..

Далее можно определить методы сокрытия/восстановления столбцов. Возможно, я зря использовал Vector, может, с другими классами было бы легче - ну, воля ваша. Я написал метод turnOffColumn(), к-й скрывает i-й столбец (где i - индекс столбца в "статичном" массиве столбцов. Он не зависит от кол-ва видимых колонок!) , и метод resetColumns() - он восстанавливает видимтость всех столбцов.
Можно было бы написать метод восстановления конкретного столбца, но при решении моей задачи это было не нужно. smile
Итак, вот код этих методов. Он не представляет особой сложности:
Код

..
public void turnOffColumn(int col) {
       Integer intCol = new Integer(col);
       int i=visible_columns.indexOf(intCol);
       if(i!=-1){
            visible_columns.remove(i);
       };
       fireTableStructureChanged();
   }

   public void resetColumns(){
       visible_columns.clear();
       for (int i=0; i<columnNames.length; i++){
                  visible_columns.add(new Integer(i));
       };
        fireTableStructureChanged();
   }
..


Вот, собственно, и все. Прелесть моего решения - нет зависимости от отображаемых столбцов и кроме того, можно легко восстановить скрытые колонки.
Повторюсь, мысль применить такой способ принадлежит не мне, я лишь реализовал. Кроме того, я практически не пишу на Java, поэтому не отрицаю, что мой код содержит множество неэффективных решений. Ну, по крайней мере, это работает. smile
Итак, я прикрепляю авхив с исходником работающего примера - можно брать и компилить. Правда, пример реализован крайне убого, но ведь это не главное. smile В коде я по кнопке удаляю/восстанавливаю 2-й и 4-й столбцы. Enjoy it.
..
Если мои усилия оказались полезными - можно кинуть в FAQ. ;)

Присоединённый файл ( Кол-во скачиваний: 53 )
Присоединённый файл  HideColumnTable.zip


--------------------
Для корабля, который не знает куда плыть, нет попутного ветра... ((С) Архимед)
...
Все знают, что это невозможно. Но случайно находится невежда, который этого не знает. Он-то и делает открытие.. ((С) А. Эйнштейн)
PM ICQ   Вверх
Domestic Cat
Дата 6.1.2005, 19:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5452
Регистрация: 3.5.2004
Где: Dallas, US

Репутация: 13
Всего: 172



Попытался добавить в ФАК - как в пустоту кануло, ни ответа ни привета. smile


--------------------

PM   Вверх
AntonSaburov
Дата 6.1.2005, 19:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Штурман
****


Профиль
Группа: Модератор
Сообщений: 5658
Регистрация: 2.7.2002
Где: Санкт-Петербург

Репутация: 10
Всего: 118



Сейчас попробую - подождите минутку.
Добавлено @ 19:45
Все нормально - можно наслаждаться smile

Kurt - большое спасибо.
PM MAIL WWW ICQ   Вверх
Domestic Cat
Дата 6.1.2005, 19:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5452
Регистрация: 3.5.2004
Где: Dallas, US

Репутация: 13
Всего: 172



А почему у меня не сработало?


--------------------

PM   Вверх
Kurt
Дата 6.1.2005, 19:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Увлеченный
***


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

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



Рад, что понравилось. smile


--------------------
Для корабля, который не знает куда плыть, нет попутного ветра... ((С) Архимед)
...
Все знают, что это невозможно. Но случайно находится невежда, который этого не знает. Он-то и делает открытие.. ((С) А. Эйнштейн)
PM ICQ   Вверх
AntonSaburov
Дата 6.1.2005, 20:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Штурман
****


Профиль
Группа: Модератор
Сообщений: 5658
Регистрация: 2.7.2002
Где: Санкт-Петербург

Репутация: 10
Всего: 118



Цитата(Domestic @ 6.1.2005, 19:48)
А почему у меня не сработало?

А ты еще маленький smile Хоть и "Котище" smile
Дозволения на такие штуки у тебя нет.
PM MAIL WWW ICQ   Вверх
Domestic Cat
Дата 6.1.2005, 20:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5452
Регистрация: 3.5.2004
Где: Dallas, US

Репутация: 13
Всего: 172



Вроде ж в новостях Админ говорил что модератор раздела вносит статьи в ФАК.


--------------------

PM   Вверх
igon
Дата 7.1.2005, 01:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата
Не так давно на форуме промелькнул вопрос о том, как можно скрыть столбцы в JTable. В ответ предлагалось использовать removeColumn(). Однако, в таком случае довольно затруднительно обратно показать те столбцы, что были скрыты. Информация из сети и мудрые люди натолкули меня на довольно изящное, как мне кажется, решение - поработать с TableModel.


Решение, предлагаемое Kurt'ом, безусловно заслуживает права на существование как один из вариантов реализации сокрытия/восстановления столбцов в JTable, однако хотелось бы остановиться на некоторых моментах:
1. "Промелькнул" - это не то слово, которым можно описать наличие на форуме нескольких топиков с огромными кусками исходных текстов, инициатором которых был sanic smile
2. Использование removeColumn() без использования TableModel никогда не предлагалось, т.к. в исходной постановке задачи указывалось на необходимость манипуляций со скрытыми столбцами.
3. Для реализации функциональности, предлагаемой Kurt'ом (скрыть некоторые/показать все), нет необходимости в создании отдельного класса с дополнительными структурами и переопределением методов. Использование removeColumn() для сокрытия некоторых столбцов тривиально и в комментариях не нуждается. Отмечу только, что удаление столбца из JTable не сопровождается удалением его и из TableModel. Что же касается восстановления показа всех столбцов, то вот эскизный вариант реализации:

Код

class Test...
  JTable table;
  DefaultTableModel model = DB.CallStoredProcedure();
...
метод showSome
   table = new JTable(model);
   table.removeColumn(7);
   table.removeColumn(3);    
   table.removeColumn(2);
...
метод showAll
   table = new JTable(model);
...





--------------------
Хотите поговорить об этом?
PM   Вверх
Domestic Cat
Дата 7.1.2005, 03:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5452
Регистрация: 3.5.2004
Где: Dallas, US

Репутация: 13
Всего: 172



Цитата(igon @ 6.1.2005, 16:51)
3. Для реализации функциональности, предлагаемой Kurt'ом (скрыть некоторые/показать все), нет необходимости в создании отдельного класса с дополнительными структурами и переопределением методов. Использование removeColumn() для сокрытия некоторых столбцов тривиально и в комментариях не нуждается. Отмечу только, что удаление столбца из JTable не сопровождается удалением его и из TableModel. Что же касается восстановления показа всех столбцов, то вот эскизный вариант реализации:



Kurt реализовал MVC, это самый лучший вариант реализации; если учесть что в твоем примере создается лишний объект JTable smile Хотя не единственный конечно.


--------------------

PM   Вверх
igon
Дата 7.1.2005, 05:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата
Kurt реализовал MVC, это самый лучший вариант реализации

И как именно Kurt реализовал часть V(View) MVC? ИМХО, мой лишний объект JTable и будет этим самым View smile Более того, любое совместное использование JTable и TableModel подпадает под определение MVC (при условии наличия Listener'ов, естественно)
В моем примере лишним является не объект JTable, а, возможно, его лишняя общая переинициализация из model с полным перечнем столбцов - Kurt это делает более локализованно. Но будут ли при этом накладные расходы очень ощутимы?
Еще раз подчеркну - я не против создания и использования custom TableModel, но нужно ли, в случаях, подобных данному, ИМХО, излишнее усложнение?

Domestic Cat,
Цитата
Хотя не единственный конечно

относится к
Цитата
лучший вариант
или
Цитата
создается лишний объект
? smile



--------------------
Хотите поговорить об этом?
PM   Вверх
Domestic Cat
Дата 7.1.2005, 07:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5452
Регистрация: 3.5.2004
Где: Dallas, US

Репутация: 13
Всего: 172



Вариант не единственный.

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


--------------------

PM   Вверх
JavaDell
Дата 19.7.2011, 09:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



С этим все понятно.
Но как быть, если данные в таблице динамически удаляются/появляются?
Делаю как описано здесь: http://www.codeguru.com/java/articles/660.shtml
только вместо статического массива данных обращаюсь к getDataVector() методу TableModel.
В итоге getColumnCount() обрезает таблицу с конца и получаю array out of bounds после того, как прячу столбы.
PM MAIL   Вверх
JavaDell
Дата 19.7.2011, 10:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Вопрос снят, если кто не хочет замарачиваться со всеми этими внутренностями, есть решение проще:
Спрятать:
Код

jTable1.getColumnModel().getColumn(index).setMaxWidth(0);
jTable1.getColumnModel().getColumn(index).setMinWidth(0);
jTable1.getColumnModel().getColumn(index).setPreferredWidth(0);

Показать:
Код

final int WIDTH_TO_SET = getWidth()/(columns.size()-hidden.size()); // для примера
jTable1.getColumnModel().getColumn(index).setMaxWidth(WIDTH_TO_SET);
jTable1.getColumnModel().getColumn(index).setMinWidth(WIDTH_TO_SET);
jTable1.getColumnModel().getColumn(index).setPreferredWidth(WIDTH_TO_SET);

PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   jk1
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

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

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


 




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


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

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