Почему невозможно эффективно переопределить setEnabled Swing? - PullRequest
2 голосов
/ 18 марта 2012

Моя цель - не дать setEnabled в Swing превратить мои JLabels и другие компоненты J в нечитаемые.(Причина этого в том, что у меня есть другое решение для обозначения включенных значков состояния.)

На основании ответов SO на один из моих предыдущих вопросов я решил переопределить setEnabled.Тем не менее, как вы увидите ниже, мое переопределение setEnabled по-прежнему приводит к тому, что компоненты становятся серыми, несмотря на отсутствие какого-либо вызова super (toggle).Может кто-нибудь объяснить, почему невозможно эффективно переопределить поведение 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 ]

3 голосов
/ 18 марта 2012

Внешний вид включен / отключен управляется делегатом пользовательского интерфейса компонента для выбранного внешнего видаНапример, делегат кнопки обычно получается из javax.swing.plaf.ButtonUI.

3 голосов
/ 18 марта 2012

Ваше переопределение setEnabled () работает при том, что указано оператором print.
Чтобы предотвратить отключение компонента, переопределите isEnabled () и верните true:

 public boolean isEnabled() { 
    return true;
 }
3 голосов
/ 18 марта 2012

Не знаю, почему вы так думаете, например, возьмите эту программу:

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

3 голосов
/ 18 марта 2012

В функции Swings setEnabled нет ничего особенного, вы можете переопределить ее как любую другую функцию.Вызов someToggleLabel.setEnabled(false) в вашем коде, очевидно, не отключит JLabel (по фундаментальной семантике Java).Что-то еще должно быть не так.

Если вы хотите иметь возможность отключить компонент (как кажется, поскольку вы говорите, что у вас есть другой способ показать его), я предлагаю вам не "отключать" механизм, который обеспечивает свингдля отключения компонента, но вместо этого попытайтесь изменить внешний вид и почувствуйте, как это сделать.

Рассматривали ли вы, например, использование JLabel.setDisabledIcon?

Смежные вопросы, которыеВы могли бы найти полезным:

0 голосов
/ 18 марта 2012

В разных случаях я замечал, что переопределенный метод setEnabled, который я написал на своих собственных компонентах (я обычно расширяю от JPanel), вызывался во время создания экземпляра.Конечно, мой собственный конструктор не вызывал его явно.

Итак, это означает, что JPanel или один из его предков вызывает setEnabled (возможно косвенно) в своем конструкторе.

Переопределять опаснометод, который вызывается в конструкторе предка, возможно, это является причиной вашей проблемы.См. Что не так с переопределенными вызовами методов в конструкторах? для получения дополнительной информации об этой проблеме.

0 голосов
/ 18 марта 2012

Если ваша проблема в том, что цвет переднего плана или фона не тот, который вы хотите, добавьте переопределение в setForeground или setBackground, установите точку останова в этом методе и запустите ее через отладчик. Затем посмотрите на свой стек при достижении точки останова, чтобы определить проблему. Иногда это вызывает вызов setEditable, который вызывает у меня проблемы. HTH и удачи;)

...