Question

How do I get a JLabel displaying a HTML string to appear greyed out (which is the behaviour of JLabels that don't display HTML text)? Is there another way than actually changing the colour myself by modifying the foreground property?

JLabel label1 = new JLabel("Normal text");
JLabel label2 = new JLabel("<html>HTML <b>text</b>");
// Both labels are now black in colour

label1.setEnabled(false);
label2.setEnabled(false);
// label1 is greyed out, label2 is still black in colour

Thank you very much for all of your responses. From what I gather, it seems that Java doesn't support automatic greying out of JLabels when they use HTML text. Suraj's solution has come closest to the fix considering the limitations.

I have however, tried a different out-of-the box approach, where I have put the HTML text JLabels inside of an inner JPanel and did this:

mInnerPanel.setEnabled(shouldShow); //shouldShow is a boolean value

Which hasn't worked. Any suggestions for this way?


EDIT: Added implemented solution.

Was it helpful?

Solution

If text is HTML, the text wont be grayed out because of the following code in BasicLabelUI#paint()

        View v = (View) c.getClientProperty(BasicHTML.propertyKey);
        if (v != null) {
        v.paint(g, paintTextR);
        }

As you can see if the text is html, then the View is used to paint and it is not checked wheter the label is enabled or not. Hence we need to do it explictly as shown below:

label2.addPropertyChangeListener(new PropertyChangeListener() {
   public void propertyChange(PropertyChangeEvent evt) {
    if (!evt.getPropertyName().equals("enabled"))
     return;
    if (evt.getNewValue().equals(Boolean.FALSE))
     label2.setText("<html><font color=gray>HTML <b>text</b></html>");
    else
     label2.setText("<html><font color=black>HTML <b>text</b></html>");
   }
  });

OTHER TIPS

Implemented solution:

    Color foreground = (shouldShow) ? SystemColor.textText : SystemColor.textInactiveText;
    for (Component comp : mInnerPanel.getComponents())
    {
        comp.setForeground(foreground);
    }

Caved in and used setForeground in the end, as it appears that Java seems to explicitly ignore the enabled property when painting JLabels so long as it contains HTML text. See also @Suraj's answer, for "pure" solution.

I would suggest the following, which is combination of two solutions provided here:

public class HtmlLabel extends JLabel{
    public void setEnabled(boolean enabled){
        if(getClientProperty(BasicHTML.propertyKey) != null ){
            Color foreground = (enabled) ? SystemColor.textText : SystemColor.textInactiveText;
            setForeground(foreground);
        }
        super.setEnabled(enabled);
    }
}

You can specify the font color in the HTML.

Override the paint method in the UI, set the client property BasicHTML.propertyKey to null if it is disabled and call super...

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top