为什么不能有效地覆盖Swing的setEnabled?

时间:2012-03-17 23:13:39

标签: java swing override

我的目标是防止Swing中的setEnabled使我的JLabel和其他JComponents变得不可读。 (原因是我有另一个解决方案来指示启用状态 - 图标。)

基于对我之前的一个问题的SO回答,我决定覆盖setEnabled。然而正如您将在下面找到的那样,尽管没有对super(切换)的任何调用,但我的overEiding setEnabled仍会导致组件变灰。有人可以解释为什么看起来无法有效地覆盖setEnabled的行为吗?

public class ToggleLabel extends JLabel {

private boolean toggle;

public ToggleLabel(String text, boolean toggle) {
    super(text);
    setEnabled(toggle);
}

public ToggleLabel(Icon image, boolean toggle) {
    super(image);
    setEnabled(toggle);
}
@Override
public void setEnabled(boolean toggle) {
    this.toggle = toggle;
    System.out.println("I am used");

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

}

6 个答案:

答案 0 :(得分:3)

Swings setEnabled函数没什么特别之处,你可以像任何其他函数一样覆盖它。在代码中调用someToggleLabel.setEnabled(false)显然禁用JLabel(通过基本的Java语义)。别的东西一定是错的。

如果你想要能够禁用该组件(因为你说你有另一种显示它的方式)我建议你不要“禁用”机制swing提供的禁用组件但是试图改变外观和感觉如何。

您是否考虑使用JLabel.setDisabledIcon

您可能会觉得有用的相关问题:

答案 1 :(得分:3)

我不知道你为什么这么认为,例如,采取这个程序:

package so;

import java.awt.Color;
import java.util.Arrays;

import javax.swing.Icon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;


public class Example {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame f = new JFrame();
                JPanel p = new JPanel();
                ToggleLabel tl = new ToggleLabel("hello");
                p.add(tl);
                tl.setBackground(Color.GREEN);
                tl.setEnabled(false);
                f.add(p);
                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                f.pack();
                f.setVisible(true);     
            }
        });
    }

    private static class ToggleLabel extends JLabel {

        private boolean toggle;

        public ToggleLabel(String s) {
            super(s);
        }

        @Override
        public void setEnabled(boolean toggle) {
            this.toggle = toggle;
            System.out.println("I am used");

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

}

正如您所看到的,打印出“我已被使用”,程序在运行时看起来像这样:

enter image description here

答案 2 :(得分:3)

你的setEnabled()覆盖工作在print语句的注释下 要防止组件被禁用,请覆盖isEnabled()并返回true:

 public boolean isEnabled() { 
    return true;
 }

答案 3 :(得分:3)

启用/禁用外观由组件的UI委托控制,用于所选的Look&感觉。例如,按钮的委托通常来自javax.swing.plaf.ButtonUI

答案 4 :(得分:0)

如果您的问题是前景色或背景色不是您想要的,请向setForeground或setBackground添加覆盖,在该方法中放置一个断点并通过调试器运行它。然后在遇到断点时查看堆栈以确定问题。有时它调用我发现的setEditable导致我出现问题。 HTH,祝你好运;)

答案 5 :(得分:0)

我注意到,在不同的场合,我在我自己的组件上编写的覆盖setEnabled方法(我通常从JPanel扩展)在实例时被调用。当然我自己的构造函数没有明确地调用它。

因此,这意味着JPanel或其祖先之一在其构造函数中调用setEnabled(可能是间接的)。

覆盖在祖先的构造函数中调用的方法是危险的,这可能是导致问题的原因。有关此问题的更多信息,请参阅What's wrong with overridable method calls in constructors?