Як в JTable встановити свого рисувальника?
Дуже просто. Потрібно реалізувати інтерфейс TableSellRenderer, имеюших всього один метод:
public Component getTableCellRendererComponent (JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
Після реалізації інтерфейсу ми отримаємо клас, який і буде малювати елементи таблиці. Але не всієї таблиці, а тільки осередки того типу стовпця, для якого ми встановимо нашого художника.
Перейдемо до прикладу. Працюємо в Eclipse.
Содадім новий проект: File-> New-> Java Project або File-> New-> Project. і в отрившемся вікні вибираємо Java Project, тиснемо Next. В поле Project Name вкажемо MyRendEditTable, тиснемо Finish.
Правою кнопкою по src, в откившемся меню вибираємо New-> Package. Ім'я пакета в поле Name встановимо myRendEditTable.table.
Подивимося, що вийшло: правою кнопкою по класу TableEx -> Run As -> Java Application, Отримуємо:
Зараз елементи таблиці промальовані рисовальщиками, встановленими в клас JTable за замовчуванням. Нас це не зовсім влаштовує. Таблиця потребує прокачування. У першому стовпці номера рядків притиснуті до правого боку, встановимо їх в центрі і змінимо фон. У стовпці "Кількість" негативні числа намалюємо червоним кольором, так прийнято в бухгалтерському обліку. В останньому стовпці притиснемо рядки до правого краю. Навіщо? Мені так закортіло. Після прокачування ви не впізнаєте цю таблицю.
Будемо створювати клас рисувальника, розширюючи клас JLabel, який малює вміст комірок. Правою кнопкою по пакету myRendEditTable.table, вибираємо New-> Class, в поле Name вводимо IntegerRenderer, це наш художник для першого стовпця (взагалі-то стовпці нумерують з нуля, так що це нульовий стовпець). Код класу-рисувальника для першого стовпця:
Розберемо цей клас докладно. По-перше метод
public Component getTableCellRendererComponent (JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
Аргументи тут такі: table - це наша таблиця, value - значення в цій комірці, isSelected - виділена наш осередок чи ні, hasFocus - має осередок фокус чи ні, row - ряд осередки, яку ми малюємо, column- колонка цього осередку.
Методом setHorisontalAlignment встановимо номера рядків в центр. Методом setText вкажемо, що, якщо значення чарунки не заявлено, то ставимо пробіл.
Тепер розглянемо isSelected і hasFocus. IsSelected == true означає що комірка виділена, hasFocus == true означає, що осередок має фокус. Але хіба осередок, що має фокус не є одночасно виділеній? Так, є. Тоді навіщо розрізняти фокус і селектід? Справа тут ось в чому. Коли ми ставимо курсор на рядок таблиці, то все осередки цієї Сторк отримують в своєму властивості isSelected значення true, тобто isSelected = true. Всі інші елементи таблиці мають isSelected = false. Осередок виділеної рядки, саме на якій стоїть курсор має фокус, тобто її властивість hasFocus = true, для всіх інших осередків, включаючи осередки виділеної стоки, hasFocus = false. У нашому класі-малювальників ми вказуємо як малювати осередки виділеного ряду (isSelected = true) і того осередку виділеного ряду, на якій встановлений курсор (hasFocus = true). У класі JTable прийнято допомогу, що має фокус, обводити контуром. Дотримуючись цей стиль, встановимо контур методом setBorder. Стоп. Навіщо ми встановлюємо контур фокусної осередки, якщо клас JTable і так обводить такі осередки контуром? Все просто. Як тільки ми взяли на себе обов'язок встановити рисувальника для якихось осередків, так клас JTable зняв з себе будь-яку відповідальність за їх промальовування, ми самі повинні все прописувати: обводити контуром чи ні, потрібен кольоровий фон чи ні і т.п.
Перший стовпець оброблений, тепер зробимо рисувальника для стовпця "Кількість". Правою кнопкою по пакету myRendEditTable.table, вибираємо New-> Class, в поле Name вводимо DoubleRenderer, це наш художник для третього стовпця. Код класу-рисувальника для стовпця "Кількість":
В цьому класі перевіряємо значення, встановлене в клітинку, якщо воно менше нуля, то колір числа червоний. Метод setForeground якраз і задає колір значення, яке зазначено в осередку (а не фону, який задається методом setBackground).
Тепер останній рядок. Правою кнопкою по пакету myRendEditTable.table, вибираємо New-> Class, в поле Name вводимо StringRenderer, це наш художник для третього стовпця. Код класу-рисувальника для стовпця "Склад":
В цьому класі визначаємо, якщо номер колонки дорівнює трьом (column == 3), то притискаємо значення осередку до правої кордоні.
На цей момент ваш проект повинен виглядати так:
Малювальники готові, залишилося повідомити нашої таблиці про це. Малювальники встановлюють для стовпців. Кожен стовпець має тип. Як дізнатися цей тип? У моделі таблиці, а у нас це клас TableExModel, є вектор vColClass, в ньому і оголошені типи, відповідні кожному стовпчику. Встановити рисувальника в таблицю означає вказати рисувальника для типу. Тип першої колонки (а точніше нульовий) - Integer. Ставимо рисувальника для колонки типу Integer:
table.setDefaultRenderer (Integer.class, new IntegerRenderer ());
Тепер колонка "Номер" буде промальована нашим малювальником. Зверніть увагу на тонкість. У нас тільки одна колонка має тип Integer, а якщо були б інші? Тоді і вони малювалися б нашим малювальником. Це не завжди зручно. Але ми з вами вже вміємо обійти таку складність, правда? Так правда. У нас два стовпці типу String. Ми вирішили значення в останньому стовпці притиснути до правого боку, але в стовпці "Найменування", а його тип String, вони повинні бути притиснуті до лівого боку. Ось чому в класі StringRenderer ми вказали, що зрушення вправо дейсвующій тільки для стовпця номер три:
Звертаю вашу увагу, що не тільки останній рядок промальовується нашим малювальником StringRenderer, а й стовпець "Найменування", адже він теж має тип String. Ще раз. Малювальники встановлюють для типу, а якщо колонок цього типу декілька, то встановлений рисувальник діє у всіх колонках цього типу. Щоб змусити колонки одного типу малюватися по-різному ставимо умови, що, наприклад, if (column == 3), малювати так-то, а інші так-то.
Змініть код конструктора TableEx () так:
Цими рядками ми встановили своїх малювальників для колонок типу String, Double, Integer:
Отже, таблиця піддалася грандіозної прокачування. Ви готові побачити результат? Правою кнопкою по значку класу TableEx -> Run As -> Java Application:
Проведемо досвід. Два рази лівою кнопкою по 18.8 і поставте мінус перед ним. Натисніть Enter. Число -18.8 стало червоним. Клацніть один раз лівою кнопкою 120.0. Весь ряд виділений підсвіткою, все осередки цього ряду мають властивість isSelected = true, а осередок зі значенням 120.0, в якій зараз курсор, має hasFocus = true. Контур навколо осередку зі 120.0 побачили? Не дарма ми намагалися.