JTextPane不显示正确的前景色

时间:2014-03-31 07:36:41

标签: java swing colors jtextpane

希望拥有一个JTextPane,其内容始终可由用户选择。因此,我创建了自己的JTextPane子类,并始终在方法“isEnabled()”中返回true。另外,我引入了一个新成员m_enabled,它负责返回正确的前景色(启用/禁用)

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;
}
}

现在的问题是前景色不会改变。它总是看起来像是禁用了textpane。但是“getForeground”中的调试信息说明如下

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]

这对我来说没问题,但是textpane总是看起来是enter image description here

你有什么想法吗?

2 个答案:

答案 0 :(得分:1)

super.getForeground()在下次调用时返回禁用的颜色,因为一旦将其设置为禁用颜色,它也将传播到超类,如下所示:

以下是直接来自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();
}
}

  

无需重写getForeground()方法只需调用setForeground()方法形式的setEnabled()方法。

在更新之前将某个默认前景颜色存储在某处,并在进一步调用中使用它。

你能试试这个

吗?
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;
    }
}

答案 1 :(得分:0)

您似乎错过了repaint()中的ActionListener来电。我无法说明,因为您没有MyPane课程的代码可用:)