Организация графического интерфейс на Swing

347
16 января 2017, 19:56

Как правильно реализовать связку событие->слушатель->код, реагирующий на событие. В каком классе должен быть инициализирован слушатель, в каком исполнен, и куда поместить код, реагирующий на событие (представление конечно есть, но недостаточно ясно.) Большая просьба, отвечать с примерами.

Answer 1

Swing построен на основе паттерна MVC. И этот паттерн будет проще всего использовать при построении своего приложения. Для примера возьмем простое приложение, которое может сохранять текстовые значения в списке и показывать его на форме.

Модель

public class Model extends Observable {
    private List<String> data;
    public Model() {
        data = new ArrayList<>();
    }
    public void addDatum(String datum) {
        data.add(datum);
        setChanged();
        notifyObservers();
    }
    public void removeDatum(String datum) {
        int indexOfElementToRemove = data.indexOf(datum);
        if (indexOfElementToRemove != -1) {
            data.remove(indexOfElementToRemove);
            setChanged();
            notifyObservers();
        }
    }
    public int size() {
        return data.size();
    }
    public String get(int index) {
        return data.get(index);
    }
}

Она может добавлять/удалять строчки, а так же реализует паттер Наблюдатель, что бы уведомлять о своих изменениях. Модель не зависит от остальных компонентов и ничего про них не знает.

Контроллер

public interface Controller {
    void setView(View view);
    void setModel(Model model);
    void start();
    void addAction(String text);
    void removeAction(String text);
}

Контроллер очень простой и имеет всего два действия - добавить и удалить строчку. Он знает о модели и умеет транслировать действия в методы изменения модели.

Отображение (View)

public class View implements ActionListener {
    // класс обертка для модели
    private class ModelWrapper extends AbstractListModel<String> implements Observer{
        private Model model;
        public ModelWrapper(Model model) {
            this.model = model;
            model.addObserver(this);
        }
        @Override
        public int getSize() {
            return model.size();
        }
        @Override
        public String getElementAt(int index) {
            return model.get(index);
        }
        // модель вызывает этот метод, когда в ней что-то поменялось
        // это часть паттерна Наблюдатель
        @Override
        public void update(Observable o, Object arg) {
            fireContentsChanged(this, 0, model.size());
        }
    }
    private JFrame frame;
    private JList<String> list;
    private JButton add;
    private JButton remove;
    private JTextField field;
    private Controller controller;
    public View() {
        initComponents();
    }
    @Override
    public void actionPerformed(ActionEvent e) {
        if (e.getSource() == add) {
            controller.addAction(field.getText());
        } else if (e.getSource() == remove) {
            controller.removeAction(list.getSelectedValue());
        }
    }
    // ниже создаются кнопки и пр графические элементы
} 

Отображение знает о модели и умеет реагировать на ее изменения, но модель не меняет. Так же отображение знает о контроллере и транслирует манипуляции с интерфейсом в действия контроллера.

Это один из возможных вариантов организации интерфейса. Полный и запускаемый код с тестами доступен на GitHub SimpleMVC

READ ALSO
Расположение, размеры и фон DialogFragment

Расположение, размеры и фон DialogFragment

DialogFragment вызывается Fragmentshow(getFragmentManager(), "ggg"); данные для фрагмента берутся в xml файле

339
SWT-приложение не запускается под Ubuntu

SWT-приложение не запускается под Ubuntu

Пытаюсь портировать десктопное SWT-приложение на UbuntuЗагрузил Eclipse Neon (6

522
Приложение для заказа товаров [требует правки]

Приложение для заказа товаров [требует правки]

Реализовать программу заказа товаровКак реализовать само приложение, знаю

320
Java, апплеты, графика 2d [требует правки]

Java, апплеты, графика 2d [требует правки]

Задача: Определение взаимного расположение точек, те

309