TL; DR: это невозможно напрямую, но может быть сделано обходным путем, как в ответе Луки, однако в его / ее ответе используются неправильные шаги градиента.Правильные перечислены ниже.
Как это работает
В Metal LAF есть жестко закодированное исключение.Если свойство background
является подклассом UIResource
, оно игнорируется *, и вместо этого кнопка закрашивается (также жестко закодированным) градиентом из свойства пользовательского интерфейса Button.gradient
.В противном случае, если background
не является UIResource
, этот фон закрашивается как есть.
*, если кнопка не отключена, в этом случае градиент отсутствует, и цвет внутри UIResource
равениспользуется для фона.
Градиент
Следуя логике MetalButtonUI
, я обнаружил, что используемый градиент используется из свойства пользовательского интерфейса Button.gradient
, которое содержитArrayList
:
0 = {Float} 0.3
1 = {Float} 0.0
2 = {ColorUIResource} "[221,232,243]"
3 = {ColorUIResource} "[255,255,255]"
4 = {ColorUIResource} "[184,207,229]"
Следуя логике, я оказался в MetalUtils.GradientPainter.drawVerticalGradient()
.Эта реализация интерпретирует вышеприведенные данные как *:
- Градиент от 0% до 30%: цвет1 до цвета2
- Градиент от 30% до 60%: цвет2 до цвета1
- Градиент от 60% до 100%: от color1 до color3
* при условии, что второе значение с плавающей точкой равно 0.0, в противном случае рисуется больше градиентов.
Поскольку это многоступенчатый градиентэто нельзя сделать простым GradientPaint
, но можно сделать LinearGradientPaint
.Однако свойство background
принимает только Color
.Он даже не может быть подделан / взломан, потому что фактическое значение в конечном итоге присваивается Graphics.setColor()
, а не Graphics2D.setPaint()
(хотя Metal основан на Swing, а не AWT) Dead End. Единственное решение, похоже, подклассJButton в целом.