У меня есть приложение, которое использует отключенные JTextFields в нескольких местах, которые должны быть прозрачными, что позволяет фоновому изображению вместо обычного текстового поля.
При запуске нового Nimbus LAF эти поля непрозрачны (несмотря на установку setOpaque (false)), и мой интерфейс нарушен. Как будто ЛАФ игнорирует непрозрачное свойство. Установка цвета фона явно трудна в нескольких местах, и менее оптимальная из-за фоновых изображений на самом деле не работает - она по-прежнему рисует его фоном по умолчанию LAF сверху, оставляя пограничный вид (экран заставки ниже имеет фон, явно установленный для соответствия изображению).
Любые идеи о том, как я могу заставить Нимбус не рисовать фон для JTextField?
Примечание. Мне нужен JTextField, а не JLabel, потому что мне нужна потокобезопасная функция setText() и обертывания.
Примечание. Моим резервным положением является продолжение использования системы LAF, но Nimbus действительно выглядит значительно лучше.
См. примеры изображений ниже.
Выводы
Сюрприз в этом поведении вызван неправильной интерпретацией того, что должен делать setOpaque() - из отчета об ошибке Nimbus:
Это проблема оригинального дизайна Swing и того, как он запутывался годами. Проблема setOpaque (false) имела побочный эффект в выходе из LAF, который скрывает фон, который на самом деле не тот, для чего он предназначен. Можно сказать, что компонент my имеет прозрачные части и качели, должен покрасить за собой родительский компонент.
К сожалению, компоненты Nimbus также, похоже, не соблюдают setBackground (null), которые в противном случае были бы рекомендуемым способом остановить рисование фона. Установка полностью прозрачного фона кажется мне неинтуитивной.
По-моему, setOpaque()/isOpaque() является ошибочным публичным выбором API, который должен был быть только:
public boolean isFullyOpaque();
Я говорю это, потому что isOpaque() == true - это контракт с Swing, что компонентный подкласс возьмет на себя ответственность за покраску всего фона - это означает, что родитель может пропустить рисование этого региона, если он захочет (что является важным показателем повышение). Что-то внешнее не может напрямую изменить этот контракт (законно), чье выполнение может быть закодировано в компоненте.
Таким образом, непрозрачность компонента не должна быть установлена с помощью setOpaque(). Вместо этого что-то вроде setBackground (null) должно приводить к тому, что многие компоненты "не имеют фона" и, следовательно, становятся не полностью непрозрачными. Например, в идеальном мире большинство компонентов должны иметь isOpaque(), который выглядит следующим образом:
public boolean isOpaque() { return (background!=null); }