Создание JFrame и наблюдаемого объекта

У меня есть класс, скажем, MyJFrame, который представляет графический интерфейс моего приложения. Он реализует интерфейс Observer и переопределяет метод update.

public class MyJFrame extends JFrame implements Observer{
  ...
  public void update(Observable arg0, Object arg1){
     ...
  }
}

Теперь я хочу также сделать свой JFram объектом Observable, но я не могу, потому что он уже расширяет класс JFrame. Я попытался создать переменную типа Observable в своем классе.

public class MyJFrame extends JFrame implements Observer{
  Observable observable = new Observable();

Проблема здесь в том, что я могу добавить Observer в это наблюдаемое поле, и я также могу уведомить наблюдателя, но я не могу вызвать метод setChanghed() (поскольку он объявлен как защищенный), который должен вызываться перед уведомлением.

У вас есть идеи о том, что я могу это реализовать?

Спасибо!!


person Maverik    schedule 06.08.2011    source источник


Ответы (3)


Расширьте Observable и объявите setChanged() общедоступным.

person Jeffrey    schedule 06.08.2011
comment
Можно поподробнее пожалуйста? Спасибо! - person Maverik; 06.08.2011
comment
Когда вы расширяете класс, вы можете повторно объявить его методы с модификатором видимости, который выше, чем раньше. Поскольку Observables setChanged() был защищен, вы можете создать подкласс Observable с общедоступным setChanged(). - person Jeffrey; 06.08.2011
comment
Я не знаю, но я был уверен, что невозможно изменить видимость метода. Спасибо, это работает! - person Maverik; 06.08.2011
comment
Вы также можете посмотреть ответ на воздушной подушке. Люди склонны выбирать PropertyChangeListener, а не Observable/Observer. - person Jeffrey; 06.08.2011
comment
То есть увеличить видимость можно, но не уменьшить, верно? То же самое для переменной? Спасибо - person Maverik; 06.08.2011

Я думаю, что многие здесь, в том числе и я, используют Шаблон проектирования Observer без использования формального Observer/Observable интерфейса/класса Java. , и есть много способов реализовать это, особенно в Swing. Вероятно, наиболее гибким является использование PropertyChangeSupport с PropertyChangeListeners, как это реализовано в SwingWorkers. Другой способ — использовать самый простой интерфейс ChangeListener.

Если вам нужна более конкретная помощь, предоставьте более подробную информацию о вашей проблеме, и, вероятно, мы сможем предложить предложения.

Редактировать 1
Это также затрагивает отдельный, но важный вопрос, на который указывает описание вашей программы: ваш класс GUI, расширяющий JFrame. Многие здесь (в том числе и я) рекомендуют вам избегать этого, если только ваш код не изменяет внутреннее поведение JFrame, то есть ваш класс переопределяет один или несколько методов JFrame. Это небольшая часть обсуждения в гораздо большей дискуссии о том, что лучше: расширение классов за счет наследования или за счет композиции.

Например: Предпочесть композицию наследованию?

Редактировать 2
Следующая незапрошенная рекомендация: я пытаюсь настроить свой код графического интерфейса на создание JPanels, а не JFrames. Таким образом, если я хочу отобразить свой графический интерфейс как автономный графический интерфейс, я просто создаю JFrame на лету, помещаю JPanel моего графического интерфейса в панель содержимого JFrame, упаковываю JFrame и отображаю его. Я делаю ту же процедуру, если хочу поместить графический интерфейс в JDialog, JApplet, JOptionPane или также в CardLayout, используя контейнер, другую JPanel,.... Это дает мне огромную гибкость в том, как я использую свой графический интерфейс.

person Hovercraft Full Of Eels    schedule 06.08.2011
comment
Итак, вы говорите, что если я хочу сделать графический интерфейс, лучше объявить JFrame как переменную моего класса и использовать ее? - person Maverik; 06.08.2011
comment
PropertyChangeListeners + SwingWorkers вместо Observable +1 - person mKorbel; 06.08.2011
comment
@lucahera: я не могу сказать, что лучше для вашей ситуации со 100% точностью, но сам я предпочитаю не расширять JFrame, если я могу этого избежать, и обычно мне это удается. - person Hovercraft Full Of Eels; 06.08.2011
comment
Забавно, потому что плагин Eclipse WindowBuilder делает то же самое, что и я. Но я думаю, что обе версии работают;) - person Maverik; 06.08.2011
comment
@lucahera: В этом нет ничего смешного, и это еще одна причина, по которой я не люблю использовать инструменты для создания графического интерфейса. :) - person Hovercraft Full Of Eels; 06.08.2011
comment
@lucahera: еще одна незапрошенная рекомендация в моем ответе в Редактировать 2 выше. - person Hovercraft Full Of Eels; 06.08.2011
comment
Мне это и вправду нравится! И я согласен! - person Maverik; 07.08.2011
comment

Это сделает это.

public class MyJFrame extends JFrame implements Observer {
    private static class MyObservable extends Observable {
        @Override
        public void setChanged() {
            super.setChanged();
        }
    }
    private final MyObservable observable = new MyObservable();

    // rest of your code
} 
person Steve McLeod    schedule 06.08.2011
comment
может быть, правильно для OP, но я думаю, что для этой реализации вывод в GUI должен быть завернут в invokeAndWait(), - person mKorbel; 06.08.2011