希望拥有一个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;
}
}
现在的问题是前景色不变。文本窗格始终处于禁用状态。但是,“ 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]
这对我来说没问题,但文本窗格始终看起来可用
你有什么想法?
最佳答案
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()方法,只需从setEnabled()方法中调用setForeground()方法即可。
在更新之前将默认前景色存储在某个地方,并在以后的调用中使用它。
你能试试这个吗
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;
}
}