индикаторы выполнения + MVC в Java =? - PullRequest
4 голосов
/ 20 мая 2009

Итак, у меня есть это замечательное элегантное MVC-архитектурное приложение на Java Swing, и теперь я хочу добавить индикатор выполнения, и я запутался в хороших методах проектирования, чтобы включить JProgressBar в мое представление. Должен ли я:

  • добавить DefaultBoundedRangeModel в состояние моего контроллера и экспортировать его?

    class Model {
      final private DefaultBoundedRangeModel progress
        = new DefaultBoundedRangeModel();
    
      public void getProgressModel() { return progress; }
      public void setProgressCount(int i) { progress.setValue(i); }
    }
    
    class Controller {
      Model model;
      int progressCount;
      void doSomething()
      {
         model.setProgressCount(++progressCount);
      }
    }
    
    class View {
      void setup(Model m)
      {
        JProgressBar progressBar = /* get or create progress bar */  ;
        progressBar.setModel(m.getProgressModel());
      }
    }
    
    /* dilemma: Model allows progress to be exported so technically
     all of the progress state could be set by someone else; should it be put
     into a read-only wrapper? */
    
  • использовать JGoodies Binding, чтобы попытаться связать визуальное состояние JProgressBar с состоянием моей модели?

    class Model {
      private int progress;
    
      public void getProgressCount() { return progress; }
      public void setProgressCount(int i) { progress = i; }
    }
    
    class View {
      void setup(Model m)
      {
        ProgressBar progressBar = /* get or create progress bar */  ;
        CallSomeMagicMethodToConnect(m, "progressCount", progressBar, "value");
        // is there something that works like the above?
        // how do I get it to automatically update???
      }
    }
    
  • или что-то еще ???

edit: более конкретно: кто-то может указать мне на Хороший Пример реалистичного источника для приложения на Java, у которого есть строка состояния, которая включает индикатор выполнения, и имеет приличную реализацию MVC этого?

Ответы [ 3 ]

3 голосов
/ 21 мая 2009

Нет (до 1) и НОООО (до 2). По крайней мере, на мой взгляд.

Нет (до 1): во-первых, DefaultBoundedRangeModel является классом javax.swing. На мой взгляд, этим классам нет места в моделях. Например, подумайте о модели, живущей на сервере, доступ к которой осуществляется через RMI - внезапное появление класса javax.swing кажется «неправильным». Однако реальная проблема заключается в том, что вы передаете часть своей модели (ограниченной модели) кому-то другому, не контролируя инициированные события или выполненные запросы.

Нет (до 2): Тьфу. Связывание - это весело, но (по крайней мере, на мой взгляд) следует использовать для синхронизации между моделью пользовательского интерфейса и компонентами пользовательского интерфейса, а не между моделью данных и моделью пользовательского интерфейса. Опять же, подумайте, что произойдет, если ваша модель данных будет находиться на удаленном сервере, к которому обращается RMI.

И что? Ну, это только предложение, но я бы добавил интерфейс прослушивателя событий и добавил стандартные методы подписки прослушивателя событий (addListner (...), removeListener (...)). Я бы позвонил этим слушателям из моей модели, когда у меня будут происходить обновления. Конечно, я бы обязательно задокументировал вызывающий поток (или сказал, что он не может быть определен), чтобы клиент (пользовательский интерфейс в данном случае) мог правильно синхронизироваться (invokeLater и друзья). Поскольку служба прослушивателя будет доступна контроллеру, это позволит модели жить где угодно (даже если слушатели будут вызываться удаленно или объединяться). Кроме того, это приведет к отделению модели от пользовательского интерфейса, что позволит создавать больше моделей, содержащих ее (переводчики / декораторы / зависимые модели).

Надеюсь, это поможет.

3 голосов
/ 25 мая 2009

В нашем приложении (MVC, около 100 KLOC) это выглядит так (фактически, Pattern Observer):

/**
 * Observer on progress changes
 */
public interface IProgressListener {
  public void setProgress(ProgressEvent e);
}

public class ProgressEvent extends ... {
  private int progressCount;
  // setter + getter
  ...
}

class Model {
  public void addProgressListener(IProgressListener l);
  protected void fireProgressChange(ProgressEvent e);   // call .setProgress() on listeners
}

class Controller {
  private Model model;
}

class View extends ProgressBar implements IProgressListener {
  ...
  // IProgressListener implementation
  public void setProgress(ProgressEvent e) {
    this.setValue(e.getProgress());
  }
  ...
}
3 голосов
/ 20 мая 2009

Я бы сказал, что-то еще.

Проблема, с которой я столкнулся при работе с MVC, заключается в определении уровня абстракции модели.

  • Модель может быть своего рода объектами для компонентов пользовательского интерфейса

  • Модель также может быть другим видом объектов для самой программы.

и

  • Модель может быть такой же высокой, как бизнес-модели.

В этом случае я бы выделил пары модель / компонент для индикатора выполнения и обработал бы их в отдельном классе контроллера.

Эта статья описывает архитектуру свинга и может прояснить, как она использует модели внутри.

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