Question

want to have a JTextPane whose content can always be selected by the user. Therefore I created my own subclass of JTextPane and always return true in the method "isEnabled()". Additionally I introduce a new member m_enabled which is responsible for returning the correct foreground color (enabled/disabled)

public class StylesExample1 {
public static final String text = "Lorem ipsum dolor...";
public static boolean m_enabled = true;

public static void main(String[] args) throws BadLocationException {
    try {
        UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
    } catch (Exception evt) {
    }

    JFrame f = new JFrame("Frame");
    final JTextPane pane = new MyPane();
    pane.setText(text);

    pane.setPreferredSize(new Dimension(200, 200));
    f.getContentPane().add(pane);
    JButton b = new JButton("Toggle Enabled state");
    b.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {
            m_enabled = !m_enabled;
            System.err.println("setting textpane enabled to " + m_enabled);
            pane.setEnabled(m_enabled);
        }
    });
    f.getContentPane().add(b);
    f.getContentPane().setLayout(new FlowLayout());
    f.setSize(400, 300);
    f.setVisible(true);
}
}

class MyPane extends JTextPane {

private static final long serialVersionUID = 1L;
private boolean m_enabled = true;

public void setEnabled(boolean enabled) {
    m_enabled = enabled;
}

@Override
public Color getForeground() {
    if (m_enabled) {
        System.err.println("foreground color: " + super.getForeground());
        return super.getForeground();
    } else {
        System.err.println("foreground color: " + getDisabledTextColor());
        return getDisabledTextColor();
    }
}

@Override
public boolean isEnabled() {
    return true;
}
}

The Problem now is that the foreground color does not change. It always looks as the textpane is disabled. However the debug information in "getForeground" say the following

setting textpane enabled to true
foreground color: javax.swing.plaf.ColorUIResource[r=0,g=0,b=0]
setting textpane enabled to false
foreground color: javax.swing.plaf.ColorUIResource[r=109,g=109,b=109]

This looks okay to me, but the textpane always looks diabledenter image description here

Do you have any ideas?

Was it helpful?

Solution

super.getForeground() is returning disabled color in the next call because once you set it to disabled color it will propagate to super class also as shown below:

Here is code directly from JComponent

public void setForeground(Color fg) {
    Color oldFg = getForeground();
super.setForeground(fg);
if ((oldFg != null) ? !oldFg.equals(fg) : ((fg != null) && !fg.equals(oldFg))) {
    // foreground already bound in AWT1.2
    repaint();
}
}

No need to override getForeground() method just call setForeground() method form setEnabled() method.

Store default foreground color somewhere before updating and use it in further calls.

Can you try this one

class MyPane extends JTextPane {

    private static final long serialVersionUID = 1L;
    private boolean m_enabled = true;
    private Color defaultForegroundColor, disabledTextColor;

    public MyPane() {
        defaultForegroundColor = getForeground();
        disabledTextColor = getDisabledTextColor();
    }

    public void setEnabled(boolean enabled) {
        m_enabled = enabled;

        if (m_enabled) {
            setForeground(defaultForegroundColor);
        } else {
            setForeground(disabledTextColor);
        }
    }

    @Override
    public boolean isEnabled() {
        return true;
    }
}

OTHER TIPS

Looks like you're missing a repaint() call in your ActionListener. I can't tell more, as you don't have the code for your MyPane class available :)

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