Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change JButton gradient color, but only for one button, not all

I want to change JButton gradient color, i found this, http://java2everyone.blogspot.com/2009/01/set-jbutton-gradient-color.html, but i want to change gradient for only one button, not all button

like image 420
help Avatar asked Aug 19 '11 00:08

help


People also ask

How do I change a button in Java?

By default, we can create a JButton with a text and also can change the text of a JButton by input some text in the text field and click on the button, it will call the actionPerformed() method of ActionListener interface and set an updated text in a button by calling setText(textField.

What is different between JButton and button?

A button generates an action event when it is pressed. The JButton class is used to create a labeled button that has platform independent implementation. The application result in some action when the button is pushed.

How will you assign the string and icon both to the JButton?

To add icon to a button, use the Icon class, which will allow you to add an image to the button. Icon icon = new ImageIcon("E:\editicon. PNG"); JButton button7 = new JButton(icon);


1 Answers

TL;DR: it's not possible directly, but can be done with a workaround like in Luca's answer, however his/her answer uses the incorrect gradient steps. The correct ones are listed below.

The way it works

In the Metal LAF there is a hardcoded exception. If the background property is a subclass of UIResource, it's ignored* and the button is instead painted with the (also hardcoded) gradient from the UI property Button.gradient. Otherwise, if background is not a UIResource, that background is painted as-is.

*unless the button is disabled, in which case there is no gradient and the color inside the UIResource is used for the background.


The gradient

Following the logic of MetalButtonUI, I found out the used gradient it uses comes from the UI property Button.gradient, which contains the ArrayList:

0 = {Float} 0.3
1 = {Float} 0.0
2 = {ColorUIResource} "[221,232,243]"
3 = {ColorUIResource} "[255,255,255]"
4 = {ColorUIResource} "[184,207,229]"

Following the logic even further, I ended up in MetalUtils.GradientPainter.drawVerticalGradient(). This implementation interprets the above data as*:

  • Gradient from 0% to 30%: color1 to color2
  • Gradient from 30% to 60%: color2 to color1
  • Gradient from 60% to 100%: color1 to color3

*assuming the second float is 0.0, otherwise more gradients are drawn.

Since this is a multi-stage gradient, it can't be done with a simple GradientPaint but can be done with a LinearGradientPaint. However the background property only accepts Color. It cannot even be spoofed/hacked because the actual value is eventually given to Graphics.setColor() and not Graphics2D.setPaint() (even though Metal is Swing-based and not AWT) Dead End. The only solution seems to subclass JButton altogether.

like image 188
Mark Jeronimus Avatar answered Sep 22 '22 06:09

Mark Jeronimus