Пользовательский компонент свинга - превращение узла в текст - PullRequest
3 голосов
/ 18 октября 2008

Я пишу пользовательский компонент Swing (что-то совершенно новое, но подумайте JTree или JList). Я пытаюсь следовать общей структуре JTree, JTable, JList и т. Д. Для согласованности (я также видел, как различные плохие сторонние компоненты отказываются от разделяемой модели и / или подхода рендеринга).

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

  • Передайте сам узел (как объект) средству визуализации, и пусть средство визуализации решит, как его отобразить.
    • Вот как это делает JList.
    • Требуется настраиваемое средство визуализации только для изменения текста.
    • Обеспечивает большую гибкость при отображении узла (даже не обязательно должен быть текстом).
  • Передайте сам узел (как объект) в средство визуализации, но у вас есть метод convertValueToText () в классе компонента.
    • Вот как это делает JTree.
    • Рендереры могут быть такими же гибкими, как и раньше, - не имеют для использования этого метода.
    • Необходимо изменить компонент, чтобы изменить преобразование текста.
  • Как и выше, но делегировать функцию convertValueTotext () модели.
    • Вот как это делает JXTable.
    • Модель, вероятно, является лучшим местом для этого метода - и там легче переопределить.

Я не хочу настраивать рендерер только для изменения текста, но я бы хотел иметь возможность настраивать рендерер так, чтобы он делал больше, чем отображение отображаемой модели строки (иначе зачем возиться с рендерерами). Мне действительно не нравится тот факт, что JXTable использует отражение для поиска convertValueToText () в модели - это пахнет плохой магией для меня.

Может ли кто-нибудь пролить свет на эту заброшенную часть Swing?

РЕШЕНИЕ

Я закончил тем, что сделал:

  • Добавить метод к модели, который возвращает строку для данного узла. Важно отметить, что это может быть нулевым, чтобы указать, что средство визуализации должно знать, что делать, или что мы просто не можем предоставить ничего полезного.
  • Компонент имеет тот же метод и передает вызов модели. Это важно для разделения вида и модели. Средство визуализации вызывает этот метод, поэтому он не обращается к модели напрямую.
  • Средство визуализации по умолчанию вызывает вышеуказанный метод и, если оно не равно нулю, оно использует его, в противном случае оно может вызвать toString для значения или предоставить значение по умолчанию или что-то еще.

Это оставляет разработчикам выбор, когда они хотят переопределить отображаемое значение - Замените метод ненулевым возвращаемым значением, зная, что средство визуализации по умолчанию будет отображать этот текст. - Предоставьте пользовательский рендерер, которому передается реальный объект узла, чтобы он мог делать «умные» вещи, если это необходимо.

Я вполне доволен этим - он чувствует себя хорошо, работает и им легко пользоваться.

Спасибо за ваши перспективы!

Ответы [ 3 ]

1 голос
/ 18 октября 2008

Хороший вопрос. Это не специфично для Swing, а философский вопрос о разнице между моделью и представлением.

Как правило, преобразование объектов в текст - это работа модели или представления? Моя пуристская голова говорит, что на самом деле вам нужна иерархия представлений - одна для преобразования объектной модели в текст, а другая для отображения текста. Возможно, вам даже понадобится более двух - например, объект-текст, текст-документ-структура, документ-структура-HTML, а затем CSS для представления пользователю.

Однако, прагматизм говорит, что это может быть слишком трудно запомнить и поддерживать. Поэтому в ваших обстоятельствах я бы предложил: подумайте, насколько вероятно, что вы когда-нибудь захотите извлечь нетекстовые данные из модели. Если это маловероятно, поместите в модель эквивалент convertValueToText.

В противном случае разрешите компоненту использовать средство визуализации, если оно ему дано, или же взять значение объекта и преобразовать его в текст внутри.

Это обеспечивает максимальную гибкость и, вероятно, делает вещи более естественными для пользователей API. Я считаю, что это модель JTable, хотя я давно не пользовался Swing.

0 голосов
/ 19 октября 2008

Если вам пришлось написать свой собственный компонент, сделайте это как можно проще. Во многих случаях, если вам нужен пользовательский рендерер, вам не важна интерпретация по компоненту или модели. Модель хранит ваши данные. И в этом случае тоже на заказ написано. С моей точки зрения, хороший выбор основан на первом варианте. Предоставьте DefaultRenderer, который реализует AbstractRenderer, и добавьте туда все методы, такие как toText (Object o) и так далее. Затем позвольте мне решить, хочу ли я использовать функциональность по умолчанию или я предпочитаю писать свои собственные. Вам действительно нужен пользовательский компонент? Чтобы сделать это работает правильно, это очень много работы. Стоит ли этот компонент всего этого?

0 голосов
/ 19 октября 2008

AFAIK, ни JList, ни JTree не требуют, чтобы средство визуализации отображало текст. Средство визуализации получает объект данных и возвращает JComponent, который позиционируется как дочерний элемент в самом дереве / списке, а затем отображается.
Я бы пошел с этим. Рендерер для текста просто вернет JLabel. Если вы хотите иметь возможность изменить способ, текст создается, передайте форматтер TextRender, и все готово.

  • Stephan
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...