Ссылка на класс Java в своем собственном конструкторе - PullRequest
0 голосов
/ 09 мая 2018

Я создаю класс Java Swing под названием ListView, который пытается быть списком общего назначения.

public class ListView<T> extends JPanel {
    private IListViewDataSource<T> dataSource;
    private JPanel list;

    public ListView(IListViewDataSource<T> dataSource, Dimension dimension) {
        this.dataSource = dataSource;

        list = new JPanel(new GridLayout(0, 1));
        this.add(new JScrollPane(list));


        this.setPreferredSize(dimension);
    }

    public void loadRows() {
        for (int i = 0; i < dataSource.getNumberOfElements(); i++) {
            JLabel label = new JLabel(dataSource.getTitleOfElement(dataSource.getElementAtPosition(i)));
            list.add(label);
        }
    }
}

Для этого я объявил интерфейс под названием IListViewDataSource, который определяет методы, необходимые для представления списка для получения его данных.

public interface IListViewDataSource<T> {
    T getElementAtPosition(int position);
    int getNumberOfElements();
    String getTitleOfElement(T element);
}

Я хотел, чтобы была возможность создать новый ListView с тем источником данных, который вы объявляете, для того, чтобы вводить данные в список. Пока все хорошо.

Теперь я создаю другой класс с именем OfferListView, который расширяет ListView, и чтобы не иметь ненужного дополнительного файла, я хотел, чтобы он реализовал свой собственный ListViewDataSource. Проблема в том, что я не могу вызвать super(this, dimension) внутри конструктора для этого нового класса, так как мне тогда сказали, что this нельзя использовать до вызова конструктора суперкласса.

Этот «шаблон» - то, что используется при программировании с UIKit для iOS, и я думаю, что это довольно хорошо, но я не могу заставить его работать на Java. Как я мог подойти к этому?

1 Ответ

0 голосов
/ 09 мая 2018
Стратегия

Domain-View-Controller использовалась в 90-х годах на сайте smalltalk для отделения представления от домена и до сих пор используется в веб-разработке.

Без написания всех классов для представлений и т. Д. Существует два способа отделения представления от домена.

(1st :) Когда view передает что-либо объекту domain, он сохраняет polling для проверки любых дополнительных изменений. Это означает, что как только объект представления (текстовое поле, фрейм или что-либо еще) пересылает запрос в домен, он продолжает проверять через несколько секунд или минут, если что-то изменилось. Однако этот подход не очень хорош.

(2-й :) Шаблон проектирования наблюдателя. Когда что-то меняется, оно автоматически уведомляет всех слушателей. Ваше представление должно реализовать интерфейс, а домен должен предоставить метод подписки для всех объектов, которые реализуют этот интерфейс. Вот пример, и я не скомпилировал его, однако он явно отделяет view от domain.

public class View implements PropertyChangeListener {

    private DomainObject object;

    public View(DomainObject object) {
        assert(object != null);
        this.setObject(object);
    }

    public void enterText(String text) {
        this.getObject().update(text);
    }

    @Override
    public void propertyChange(PropertyChangeEvent evt) {
         if(evt.getPropertyName().equals("string_updated"))
             System.out.println("New value is " + evt.getNewValue());
    }

    public DomainObject getObject() {
        return object;
    }

    public void setObject(DomainObject object) {
        this.object = object;
    }

}

Вот класс домена:

public class DomainObject {

    private String text;


    public DomainObject(String test) {
        this.setText(test);
    }


    public String getText() {
        return text;
    }
    public void setText(String text) {
        this.text = text;
    }

    public void update(String string) {
        this.setText(string);
        this.getListener().stream().forEach(e -> e.propertyChange(new PropertyChangeEvent(this,"string_updated","",this.getText())));
    }

    private ArrayList<PropertyChangeListener> listener;

    public void subscribe(PropertyChangeListener listener) {
        this.getListener().add(listener);
    }


    public ArrayList<PropertyChangeListener> getListener() {
        return listener;
    }


    public void setListener(ArrayList<PropertyChangeListener> listener) {
        this.listener = listener;
    }


}

Как я вижу, вы пытаетесь иметь много видов, если они содержатся внутри друг друга, тогда используйте также Composite design pattern.

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