Я думаю, что работаю над этим 3 часа (без школы: D).И результат хороший!Вот скриншот этого в Ubuntu:
![Ubuntu](https://i.stack.imgur.com/JBrtT.png)
Я отказался от использования настройки цвета тела.Как вы можете видеть на изображении, вы можете выбирать цвета, и когда они отключены, все затухает.
А вот класс HTMLJRadio
, работающая версия Ubuntu:
package so_6648578;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import javax.swing.plaf.basic.BasicHTML;
import javax.swing.text.View;
import sun.swing.SwingUtilities2;
public class HTMLJRadio extends JRadioButton
{
private static final String HTML_PREFIX = "<html>";
private static Dimension size = new Dimension();
private static Rectangle viewRect = new Rectangle();
private static Rectangle iconRect = new Rectangle();
private static Rectangle textRect = new Rectangle();
private String myText;
public HTMLJRadio(String text)
{
super(HTML_PREFIX + text);
this.myText = text;
}
@Override
public void setEnabled(boolean enabled)
{
super.setEnabled(enabled);
setText(HTML_PREFIX + myText);
}
private View clearSuperText()
{
try {
Field textField = getClass().getSuperclass().getSuperclass().getSuperclass().getDeclaredField("text");
textField.setAccessible(true);
textField.set(this, null);
View v = (View) getClientProperty(BasicHTML.propertyKey);
Field clientPropertiesField = getClass().getSuperclass().getSuperclass().getSuperclass().getSuperclass().getDeclaredField("clientProperties");
clientPropertiesField.setAccessible(true);
Class arrayTableClass = clientPropertiesField.get(this).getClass();
Method remove = arrayTableClass.getMethod("remove", Object.class);
remove.setAccessible(true);
remove.invoke(clientPropertiesField.get(this), BasicHTML.propertyKey);
return v;
} catch (Exception e) {
e.printStackTrace(System.err);
System.exit(-1);
return null;
}
}
private void restoreSuperText(View v)
{
try {
Field textField = getClass().getSuperclass().getSuperclass().getSuperclass().getDeclaredField("text");
textField.setAccessible(true);
textField.set(this, HTML_PREFIX + myText);
Field clientPropertiesField = getClass().getSuperclass().getSuperclass().getSuperclass().getSuperclass().getDeclaredField("clientProperties");
clientPropertiesField.setAccessible(true);
Class arrayTableClass = clientPropertiesField.get(this).getClass();
Method put = arrayTableClass.getMethod("put", Object.class, Object.class);
put.setAccessible(true);
put.invoke(clientPropertiesField.get(this), BasicHTML.propertyKey, v);
} catch (Exception e) {
e.printStackTrace(System.err);
System.exit(-1);
}
}
@Override
protected void paintComponent(Graphics g)
{
// Paint the icon
View v = clearSuperText();
super.paintComponent(g);
restoreSuperText(v);
// Paint the HTML
paintHTML(g);
}
public Icon getDefaultIcon()
{
return UIManager.getIcon("RadioButton.icon");
}
/**
* paint the radio button
* StackOverflow.com: Copied and modified from Oracle Java API:
*
*/
public synchronized void paintHTML(Graphics g)
{
Font f = getFont();
g.setFont(f);
FontMetrics fm = SwingUtilities2.getFontMetrics(this, g, f);
Insets i = getInsets();
size = getSize(size);
viewRect.x = i.left;
viewRect.y = i.top;
viewRect.width = size.width - (i.right + viewRect.x);
viewRect.height = size.height - (i.bottom + viewRect.y);
iconRect.x = iconRect.y = iconRect.width = iconRect.height = 0;
textRect.x = textRect.y = textRect.width = textRect.height = 0;
Icon altIcon = getIcon();
String text = SwingUtilities.layoutCompoundLabel(
this, fm, getText(), altIcon != null ? altIcon : getDefaultIcon(),
getVerticalAlignment(), getHorizontalAlignment(),
getVerticalTextPosition(), getHorizontalTextPosition(),
viewRect, iconRect, textRect,
getText() == null ? 0 : getIconTextGap());
// fill background
if (isOpaque()) {
g.setColor(getBackground());
g.fillRect(0, 0, size.width, size.height);
}
// Draw the Text
if (text != null) {
View v = (View) getClientProperty(BasicHTML.propertyKey);
if (v != null) {
if (!isEnabled()) {
// Perpared the grayed out img
BufferedImage img = new BufferedImage(textRect.width + 1, textRect.height + 1, BufferedImage.TYPE_4BYTE_ABGR_PRE);
Graphics2D gg = (Graphics2D) img.createGraphics();
Rectangle imgRect = new Rectangle(0, 0, textRect.width, textRect.height);
gg.setClip(imgRect);
v.paint(gg, imgRect);
int brighter = getBackground().brighter().getRGB() & 0x00FFFFFF;
int darker = getBackground().darker().getRGB() & 0x00FFFFFF;
gg.dispose();
for (int y = 0; y < img.getHeight(); ++y) {
for (int x = 0; x < img.getWidth(); ++x) {
int argb = img.getRGB(x, y);
if (argb != 0) {
argb = (argb & 0xFF000000) | brighter;
img.setRGB(x, y, argb);
}
}
}
g.drawImage(img, textRect.x + 1, textRect.y + 1, this);
for (int y = 0; y < img.getHeight(); ++y) {
for (int x = 0; x < img.getWidth(); ++x) {
int argb = img.getRGB(x, y);
if (argb != 0) {
argb = (argb & 0xFF000000) | darker;
img.setRGB(x, y, argb);
}
}
}
g.drawImage(img, textRect.x, textRect.y, this);
} else {
v.paint(g, textRect);
}
} else {
throw new IllegalStateException("The given text isn't HTML!!");
}
}
}
public static void showButtons()
{
String htmlText = "<h1>Laf</h1><p>Ha Ha!<p style='color: green; text-decoration: underline;'>Green?";
JPanel p = new JPanel(new GridLayout(0, 1, 3, 3));
HTMLJRadio button1 = new HTMLJRadio(htmlText);
p.add(button1);
HTMLJRadio button2 = new HTMLJRadio(htmlText);
button2.setEnabled(false);
p.add(button2);
JRadioButton button3 = new JRadioButton("Non html disabled");
button3.setEnabled(false);
p.add(button3);
JOptionPane.showMessageDialog(null, p);
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e) {
}
showButtons();
}
});
}
}
Подход2
Вторая попытка заставить его работать в Windows.Это работает и в Ubuntu:
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import javax.swing.plaf.basic.BasicHTML;
import javax.swing.text.View;
import sun.swing.SwingUtilities2;
public class HTMLJRadio extends JRadioButton
{
private static final String HTML_PREFIX = "<html>";
private static Dimension size = new Dimension();
private static Rectangle viewRect = new Rectangle();
private static Rectangle iconRect = new Rectangle();
private static Rectangle textRect = new Rectangle();
private String myText;
public HTMLJRadio(String text)
{
super(HTML_PREFIX + text);
this.myText = text;
}
@Override
public void setEnabled(boolean enabled)
{
super.setEnabled(enabled);
setText(HTML_PREFIX + myText);
}
private View clearSuperText()
{
try {
Field textField = getClass().getSuperclass().getSuperclass().getSuperclass().getDeclaredField("text");
textField.setAccessible(true);
textField.set(this, null);
View v = (View) getClientProperty(BasicHTML.propertyKey);
Field clientPropertiesField = getClass().getSuperclass().getSuperclass().getSuperclass().getSuperclass().getDeclaredField("clientProperties");
clientPropertiesField.setAccessible(true);
Class arrayTableClass = clientPropertiesField.get(this).getClass();
Method remove = arrayTableClass.getMethod("remove", Object.class);
remove.setAccessible(true);
remove.invoke(clientPropertiesField.get(this), BasicHTML.propertyKey);
return v;
} catch (Exception e) {
e.printStackTrace(System.err);
System.exit(-1);
return null;
}
}
private void restoreSuperText(View v)
{
try {
Field textField = getClass().getSuperclass().getSuperclass().getSuperclass().getDeclaredField("text");
textField.setAccessible(true);
textField.set(this, HTML_PREFIX + myText);
Field clientPropertiesField = getClass().getSuperclass().getSuperclass().getSuperclass().getSuperclass().getDeclaredField("clientProperties");
clientPropertiesField.setAccessible(true);
Class arrayTableClass = clientPropertiesField.get(this).getClass();
Method put = arrayTableClass.getMethod("put", Object.class, Object.class);
put.setAccessible(true);
put.invoke(clientPropertiesField.get(this), BasicHTML.propertyKey, v);
} catch (Exception e) {
e.printStackTrace(System.err);
System.exit(-1);
}
}
@Override
protected void paintComponent(Graphics g)
{
// Paint the icon
View v = clearSuperText();
super.paintComponent(g);
restoreSuperText(v);
// Paint the HTML
paintHTML(g);
}
public Icon getDefaultIcon()
{
return UIManager.getIcon("RadioButton.icon");
}
private Color getDisableColor()
{
return UIManager.getColor("ComboBox.disabledForeground");
}
private Color getDisableColorBackground()
{
return getDisableColor().brighter().brighter();
}
/**
* paint the radio button
* StackOverflow.com: Copied and modified from Oracle Java API:
*
*/
public synchronized void paintHTML(Graphics g)
{
Font f = getFont();
g.setFont(f);
FontMetrics fm = SwingUtilities2.getFontMetrics(this, g, f);
Insets i = getInsets();
size = getSize(size);
viewRect.x = i.left;
viewRect.y = i.top;
viewRect.width = size.width - (i.right + viewRect.x);
viewRect.height = size.height - (i.bottom + viewRect.y);
iconRect.x = iconRect.y = iconRect.width = iconRect.height = 0;
textRect.x = textRect.y = textRect.width = textRect.height = 0;
Icon altIcon = getIcon();
String text = SwingUtilities.layoutCompoundLabel(
this, fm, getText(), altIcon != null ? altIcon : getDefaultIcon(),
getVerticalAlignment(), getHorizontalAlignment(),
getVerticalTextPosition(), getHorizontalTextPosition(),
viewRect, iconRect, textRect,
getText() == null ? 0 : getIconTextGap());
// fill background
if (isOpaque()) {
g.setColor(getBackground());
g.fillRect(0, 0, size.width, size.height);
}
// Draw the Text
if (text != null) {
View v = (View) getClientProperty(BasicHTML.propertyKey);
if (v != null) {
if (!isEnabled()) {
// Perpared the grayed out img
BufferedImage img = new BufferedImage(textRect.width + 1, textRect.height + 1, BufferedImage.TYPE_4BYTE_ABGR_PRE);
Graphics2D gg = (Graphics2D) img.createGraphics();
Rectangle imgRect = new Rectangle(0, 0, textRect.width, textRect.height);
gg.setClip(imgRect);
v.paint(gg, imgRect);
Color cBrither = getDisableColorBackground();
Color cDarker = getDisableColor();
int brighter = cBrither.getRGB() & 0x00FFFFFF;
int darker = cDarker.getRGB() & 0x00FFFFFF;
// int brighter = getBackground().brighter().getRGB() & 0x00FFFFFF;
// int darker = getBackground().darker().getRGB() & 0x00FFFFFF;
gg.dispose();
for (int y = 0; y < img.getHeight(); ++y) {
for (int x = 0; x < img.getWidth(); ++x) {
int argb = img.getRGB(x, y);
if (argb != 0) {
argb = (argb & 0xFF000000) | brighter;
img.setRGB(x, y, argb);
}
}
}
g.drawImage(img, textRect.x + 1, textRect.y + 1, this);
for (int y = 0; y < img.getHeight(); ++y) {
for (int x = 0; x < img.getWidth(); ++x) {
int argb = img.getRGB(x, y);
if (argb != 0) {
argb = (argb & 0xFF000000) | darker;
img.setRGB(x, y, argb);
}
}
}
g.drawImage(img, textRect.x, textRect.y, this);
} else {
v.paint(g, textRect);
}
} else {
throw new IllegalStateException("The given text isn't HTML!!");
}
}
}
public static void showButtons()
{
String htmlText = "<h1>Laf</h1><p>Ha Ha!<p style='color: green; text-decoration: underline;'>Green?";
JPanel p = new JPanel(new GridLayout(0, 1, 3, 3));
HTMLJRadio button1 = new HTMLJRadio(htmlText);
p.add(button1);
HTMLJRadio button2 = new HTMLJRadio(htmlText);
button2.setEnabled(false);
p.add(button2);
JRadioButton button3 = new JRadioButton("Non html disabled");
button3.setEnabled(false);
p.add(button3);
JOptionPane.showMessageDialog(null, p);
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e) {
}
showButtons();
}
});
}
}
Снимок экрана Windows со второй попытки
![Windows screenshot of 2nd attempt](https://i.stack.imgur.com/tytaH.png)
Подход 3: С determineDisabledColorByWitchCraft()
:
Это отлично работает и в Ubuntu:
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import javax.swing.plaf.basic.BasicHTML;
import javax.swing.text.View;
import sun.swing.SwingUtilities2;
public class HTMLJRadio extends JRadioButton
{
private static final String HTML_PREFIX = "<html>";
private static Dimension size = new Dimension();
private static Rectangle viewRect = new Rectangle();
private static Rectangle iconRect = new Rectangle();
private static Rectangle textRect = new Rectangle();
private String myText;
public HTMLJRadio(String text)
{
super(HTML_PREFIX + text);
this.myText = text;
}
@Override
public void setEnabled(boolean enabled)
{
super.setEnabled(enabled);
setText(HTML_PREFIX + myText);
}
private View clearSuperText()
{
try {
Field textField = getClass().getSuperclass().getSuperclass().getSuperclass().getDeclaredField("text");
textField.setAccessible(true);
textField.set(this, null);
View v = (View) getClientProperty(BasicHTML.propertyKey);
Field clientPropertiesField = getClass().getSuperclass().getSuperclass().getSuperclass().getSuperclass().getDeclaredField("clientProperties");
clientPropertiesField.setAccessible(true);
Class arrayTableClass = clientPropertiesField.get(this).getClass();
Method remove = arrayTableClass.getMethod("remove", Object.class);
remove.setAccessible(true);
remove.invoke(clientPropertiesField.get(this), BasicHTML.propertyKey);
return v;
} catch (Exception e) {
e.printStackTrace(System.err);
System.exit(-1);
return null;
}
}
private void restoreSuperText(View v)
{
try {
Field textField = getClass().getSuperclass().getSuperclass().getSuperclass().getDeclaredField("text");
textField.setAccessible(true);
textField.set(this, HTML_PREFIX + myText);
Field clientPropertiesField = getClass().getSuperclass().getSuperclass().getSuperclass().getSuperclass().getDeclaredField("clientProperties");
clientPropertiesField.setAccessible(true);
Class arrayTableClass = clientPropertiesField.get(this).getClass();
Method put = arrayTableClass.getMethod("put", Object.class, Object.class);
put.setAccessible(true);
put.invoke(clientPropertiesField.get(this), BasicHTML.propertyKey, v);
} catch (Exception e) {
e.printStackTrace(System.err);
System.exit(-1);
}
}
@Override
protected void paintComponent(Graphics g)
{
// Paint the icon
View v = clearSuperText();
super.paintComponent(g);
restoreSuperText(v);
// Paint the HTML
paintHTML(g);
}
public Icon getDefaultIcon()
{
return UIManager.getIcon("RadioButton.icon");
}
public static Color determineDisabledColorByWitchCraft() {
// this is little 'block' character..
JButton b = new JButton(String.valueOf('\u2586'));
b.setSize(b.getPreferredSize());
b.setEnabled(false);
BufferedImage biDisabled = new BufferedImage(
b.getWidth(),
b.getHeight(),
BufferedImage.TYPE_INT_RGB);
Graphics g2 = biDisabled.getGraphics();
b.paint(g2);
// get the middle pixel..
int x = b.getWidth()/2;
int y = b.getHeight()/2;
return new Color(biDisabled.getRGB(x,y));
}
private Color getDisableColor()
{
return determineDisabledColorByWitchCraft();
}
private Color getDisableColorBackground()
{
return getDisableColor().brighter().brighter();
}
/**
* paint the radio button
* StackOverflow.com: Copied and modified from Oracle Java API:
*
*/
public synchronized void paintHTML(Graphics g)
{
Font f = getFont();
g.setFont(f);
FontMetrics fm = SwingUtilities2.getFontMetrics(this, g, f);
Insets i = getInsets();
size = getSize(size);
viewRect.x = i.left;
viewRect.y = i.top;
viewRect.width = size.width - (i.right + viewRect.x);
viewRect.height = size.height - (i.bottom + viewRect.y);
iconRect.x = iconRect.y = iconRect.width = iconRect.height = 0;
textRect.x = textRect.y = textRect.width = textRect.height = 0;
Icon altIcon = getIcon();
String text = SwingUtilities.layoutCompoundLabel(
this, fm, getText(), altIcon != null ? altIcon : getDefaultIcon(),
getVerticalAlignment(), getHorizontalAlignment(),
getVerticalTextPosition(), getHorizontalTextPosition(),
viewRect, iconRect, textRect,
getText() == null ? 0 : getIconTextGap());
// fill background
if (isOpaque()) {
g.setColor(getBackground());
g.fillRect(0, 0, size.width, size.height);
}
// Draw the Text
if (text != null) {
View v = (View) getClientProperty(BasicHTML.propertyKey);
if (v != null) {
if (!isEnabled()) {
// Perpared the grayed out img
BufferedImage img = new BufferedImage(textRect.width + 1, textRect.height + 1, BufferedImage.TYPE_4BYTE_ABGR_PRE);
Graphics2D gg = (Graphics2D) img.createGraphics();
Rectangle imgRect = new Rectangle(0, 0, textRect.width, textRect.height);
gg.setClip(imgRect);
v.paint(gg, imgRect);
Color cBrither = getDisableColorBackground();
Color cDarker = getDisableColor();
int brighter = cBrither.getRGB() & 0x00FFFFFF;
int darker = cDarker.getRGB() & 0x00FFFFFF;
// int brighter = getBackground().brighter().getRGB() & 0x00FFFFFF;
// int darker = getBackground().darker().getRGB() & 0x00FFFFFF;
gg.dispose();
for (int y = 0; y < img.getHeight(); ++y) {
for (int x = 0; x < img.getWidth(); ++x) {
int argb = img.getRGB(x, y);
if (argb != 0) {
argb = (argb & 0xFF000000) | brighter;
img.setRGB(x, y, argb);
}
}
}
g.drawImage(img, textRect.x + 1, textRect.y + 1, this);
for (int y = 0; y < img.getHeight(); ++y) {
for (int x = 0; x < img.getWidth(); ++x) {
int argb = img.getRGB(x, y);
if (argb != 0) {
argb = (argb & 0xFF000000) | darker;
img.setRGB(x, y, argb);
}
}
}
g.drawImage(img, textRect.x, textRect.y, this);
} else {
v.paint(g, textRect);
}
} else {
throw new IllegalStateException("The given text isn't HTML!!");
}
}
}
public static void showButtons()
{
String htmlText = "<h1>Laf</h1><p>Ha Ha!<p style='color: green; text-decoration: underline;'>Green?";
JPanel p = new JPanel(new GridLayout(0, 1, 3, 3));
HTMLJRadio button1 = new HTMLJRadio(htmlText);
p.add(button1);
HTMLJRadio button2 = new HTMLJRadio(htmlText);
button2.setEnabled(false);
p.add(button2);
JRadioButton button3 = new JRadioButton("Non html disabled");
button3.setEnabled(false);
p.add(button3);
JOptionPane.showMessageDialog(null, p);
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e) {
}
showButtons();
}
});
}
}
Наслаждайтесь!