Уведомление объектов о событии - PullRequest
1 голос
/ 21 декабря 2011

Я ищу эффективный метод для запуска изменения набора объектов после того, как изменение было сделано для ключевого объекта. Что я хочу сделать, это: Есть один объект, который при изменении выполняет метод в других объектах.

Я пытался использовать PropertyChangeListener для достижения этой цели:

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class BoundSample {
    public static void main(String args[]) {
        JFrame frame = new JFrame("PropertyChangeListener Sample");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        final JButton button1 = new JButton("Open");
        final JButton button2 = new JButton("Cancel");

        final String[] languages = { "English", "Spanish" };

        final JComboBox combo = new JComboBox(languages);

        final JPanel panel = new JPanel();


        ActionListener actionListener = new ActionListener() {
            public void actionPerformed(ActionEvent actionEvent) {
                JComboBox comboTmp = (JComboBox) actionEvent.getSource();

                if (combo.getSelectedItem().equals("English") || combo.getSelectedItem().equals("Ingles")) {
                    String[] langs = { "English", "Spanish" };
                    comboTmp.setModel(new JComboBox(langs).getModel());
                }
                else if (combo.getSelectedItem().equals("Spanish") || combo.getSelectedItem().equals("Espanol")) {
                    String[] langs = { "Ingles", "Espanol" };
                    comboTmp.setModel(new JComboBox(langs).getModel());
                }
            }
        };

        PropertyChangeListener propertyChangeListener = new PropertyChangeListener() {
            public void propertyChange(PropertyChangeEvent propertyChangeEvent) {
                String property = propertyChangeEvent.getPropertyName();

                JComboBox comboTmp = (JComboBox) propertyChangeEvent.getSource();
                String language = (String) comboTmp.getItemAt(0);

                System.out.println(language);

                if ("model".equals(property)) {
                    if (language.equals("English")) {
                        button1.setLabel("Open");
                        button2.setLabel("Cancel");
                    } else if (language.equals("Ingles")) {
                        button1.setLabel("Abierto");
                        button2.setLabel("Cancelar");
                    }

                }
            }
        };

        combo.addPropertyChangeListener(propertyChangeListener);
        combo.addActionListener(actionListener);

        Container contentPane = frame.getContentPane();
        panel.add(button1, BorderLayout.CENTER);
        panel.add(button2, BorderLayout.SOUTH);

        contentPane.add(combo, BorderLayout.NORTH);
        contentPane.add(panel, BorderLayout.SOUTH);

        frame.setSize(300, 100);
        frame.setVisible(true);
    }
}

Проблема с этим подходом состоит в том, что с ростом числа объектов метод propertyChange () будет расходоваться, и им станет трудно управлять. Кроме того, чтобы добавить новый JComponent, мне также придется изменить propertyChange ().

Есть ли способ сделать это наоборот, заставляя объекты «искать» изменения в ключевом объекте и заставлять их действовать соответствующим образом вместо того, чтобы воздействовать на них, выполняя действие в PropertyChangeListener ключевого объекта ? Или, может быть, другой изящный способ сделать это?

Ответы [ 2 ]

3 голосов
/ 21 декабря 2011

Прежде всего, рекомендация - всегда обращайтесь к носителю языка для выполнения ваших переводов. Это помогает избежать определенных типов ошибок. Например, слово, которое вы выбрали в качестве замены слова «open», обычно используется как прилагательное (например, «открытое окно»), а не как глагол, в то время как вы используете неопределенное время для слова «отмена». У вас также нет знаков ударения, что может запутать некоторых читателей (некоторые слова отличаются только из-за их знаков ударения ...).

Далее, вы не должны жестко кодировать выбор или использование языка; они должны быть загружены из файлов .properties или аналогичных. Это делает техническое обслуживание тривиальным, особенно при добавлении дополнительных языков. @ Ответ Морта об использовании шаблона наблюдателя правильный - именно так должны обрабатываться обновления. Вот (очень грубо), как бороться с языковыми аспектами:
Для начала вам понадобятся .properties файлы.

spanishButtonNames.properties
==================================
openButton=Abrir
cancelButton=Cancelar

englishButtonNames.properties
==================================
opernButton=Open
cancelButton=Cancel

Вы захотите обернуть их в какой-нибудь PropertyManager, который будет иметь дело с загрузкой файлов ресурсов за кулисами, когда запрашивается язык (и, возможно, освобождает ресурсы).

Далее, при создании кнопок назовите их:

JButton openButton = new JButton();
openButton.setName("openButton");
// And add them to a list
buttonList.add(openButton);
// More buttons....

Обновление кнопок из списка кнопок является тривиальным. Вы можете просто прослушивать (и распространять) buttonList сообщения:

for(JButton button : buttonList) {
    button.setText(languagePropertyManager.getProperty(button.getName()));
}

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

2 голосов
/ 21 декабря 2011

Знаете ли вы образец наблюдателя ?Он делает то, что вам нужно: объекты регистрируются на объекте, чтобы получать уведомления, когда что-то происходит.

шаблон наблюдателя

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...