LookAndFeel-независимая ссылка цветовых клавиш
В настоящее время я работаю над набором пользовательских элементов управления для продукта компании, в которой я работаю. Для этого я расширяю множество элементов управления Swing и также переопределяю много методов paint
.
Чтобы поддерживать согласованную цветовую схему, я получаю цвета для моих методов paint
, setBackground
и т.д., используя UIManager.getColor
.
Это было прекрасно, пока мы не заметили, что Nimbus LookAndFeel, поставляемый с текущими версиями JRE, использует совершенно разные цветовые клавиши, поэтому многие вещи выглядят совершенно неуместными.
Например, в то время как все остальные элементы LookAndFeels (Metal, Windows Classic, Windows, CDE/Motif, GTK) определили ключевой "текст" как яркий фон для текстов и "textText" в качестве соответствующего цвета переднего плана ", текст" в Nimbus на самом деле черный цвет переднего плана, и стандартный цвет фона текста, кажется, не существует.
"TextField.background" будет работать, но это, к примеру, не существует для Windows LookAndFeels.
Я предполагаю, что у вас проблема. Я не хочу поддерживать набор цветовых клавиш для каждого LAF, который знает, какие LAF будут добавлены в будущем и которые моя компания может решить использовать.
Простым решением было бы избавиться от Nimbus, конечно, но, по понятным причинам, моему боссу вообще не нравится эта идея, кроме того, Nimbus является частью JRE в эти дни и должен поддерживаться.
Итак, я задаюсь вопросом, существует ли какой-либо стандартизованный способ получения LAF-зависимых цветов, например, "текст фона/переднего плана", "выделенный текст bg/fg" и т.д.?
Ответы
Ответ 1
Нет никакого пути - вы должны создать свой собственный уровень абстракции для имен цветов (и, возможно, других имен свойств).
В основном у вас есть запас LookAndFeels (металл, Windows Classic, Windows, CDE/Motif, GTK), которые используют собственные имена цветов и Nimbus, которые используют разные имена.
Создать класс, например. LafProperties
, так что для каждого свойства/цвета у вас есть метод (например, "getTextColor" ). Этот класс возвращает свойства для классических стилей Laf. Затем распространите этот класс на Nimbus и измените только методы, которые отличаются в Nimbus.
Если у акций Lafs и Nimbus есть большинство свойств, которые по-разному называются, чем использование, вы можете использовать интерфейс и два реализующих класса.
Ответ 2
Я не уверен, что существует "стандартизованный" способ получения этих значений.
Как вы заметили, Nimbus использует свои собственные имена для цветов. В частности, свойства textForeground
и textBackground
.
Эта странность, вероятно, связана с тем, что Nimbus использует небольшой набор основных цветов (указанный в качестве Первичного в диаграмма), которые вычитают из них вторичные цвета, которые, в свою очередь, используются в качестве основы для всех остальных цветов.
Ответ 3
Да, поскольку подразумевается @josefx, к сожалению, это не то, как работают пользовательские интерфейсы. Они не являются пулом общих переносимых свойств, а представляют собой набор фактических компонентов и конкретных реализаций для каждого из этих компонентов. Это не очень расширяемая система, которая дружественна к пользовательским компонентам.
Уровень абстракции - это компонент, а не нечто более зернистое. Если вы попросите компонент ComponentUI для компонента, о котором L & F не знает, вам не повезло. И ComponentUI - это немного больше, чем обертка для метода рисования, поэтому он не обязан раскрывать какие-либо метаданные вообще.
Проще говоря, вы застряли в основном, используя метод JTextField (или какой-либо другой подходящий компонент), который предлагает josefx, или добавляя определенную поддержку в вашем коде для обработки эксцентриситетов имен свойств L & F что вы хотите хорошо поддерживать.
Еще одно предложение - "предварительно убрать" изменения L & F и подкласс L & Fs, который вы хотите поддержать, чтобы ваши компоненты были более гражданами первого класса в пределах этих L & Fs. Когда L & F изменится на L & F, который вы поддерживаете, отключите свое имя класса с именем класса подкласса, а затем реализуйте ComponentUI для своих пользовательских компонентов и расширьте родительский метод LookAndFeel.createUI, чтобы он "знал", о ваших новых компонентах.
Ни один из них не очень хорош, но система компонентов Swing не предназначена для расширения во время выполнения для обработки настраиваемых компонентов. Весь комплект компонентов выполняется сразу же, когда создается L & F.
Ответ 4
Не очень хороший способ, но он должен работать на основе:
- Создать JTextField
- вызов getForeground, getBackground, getSelectionColor для получения значений, зависящих от laf.
Обновление:
Класс ComponentUI и его подклассы, которые являются базовыми классами для всех взглядов и чувств, предоставляют только способ инициализации зависимого по умолчанию параметра значения, они не обеспечивают прямого доступа к этим значениям.
Ответ 5
Класс java.awt.SystemColor предоставляет переменные для множества общих атрибутов.
Для текстового фона/фона используйте поля-члены text
/textText
; для выделенного текста используйте textHighlight
/textHighlightText
.
Ответ 6
Немногие вещи, которые я пытаюсь понять, читают ваш вопрос, который немного приправлен фрустрациями нижнего живота, если я хорошо себя чувствую:
- зависимость от стандартов JRE/поддержка по сравнению с независимыми/свободными решениями.
- стандарты и соответствие по сравнению с творчеством и настройкой
И, таким образом, в конечном счете:
- практический подход вашего босса по сравнению с программистами далекие будущие идеи