Я признаю, что занимаюсь веб-разработкой, поэтому у меня нет большого опыта работы с Swing.
Но я всегда думал, что подход к нему будет разбить приложение на пакеты / view, / model и / controller. Отношения будут однонаправленными: / controller будет знать как / model, так и / view, но ни один из них не будет импортировать какие-либо классы из / controller или друг друга.
Компоненты слоя / view никогда не будут JFrames; они всегда были бы JPanel или другим подходящим контейнером, который мог бы быть при необходимости составлен из JFrames. Каждый будет иметь ссылки на интерфейсы Listener, инициализированные в конструкторах, и будет обращаться к ним для обработки событий:
public class ExamplePanel extends JPanel implements ActionListener
{
private JButton button;
private ActionListener buttonListener;
public ExamplePanel(ActionListener buttonListener)
{
this.button = new JButton("Do Something");
this.buttonListener = buttonListener;
this.button.addListener(this.buttonListener);
}
public void actionPerformed(ActionEvent e)
{
this.buttonListener.actionPerformed(e);
}
}
Эта схема хорошо работает с внедрением зависимостей, поскольку теперь контроллер может использовать локальную или удаленную реализацию этого интерфейса прослушивателя, изменяя поведение таким образом, чтобы это никак не влияло на клиента.
Я признаю, что никогда не следовал этому до конца.
У пользователей Spring богатый клиентский модуль Swing, но он, похоже, потерял популярность. Похоже, они решили, что направление BlazeDS - лучший выбор для богатых клиентов. Но, возможно, вы сможете почерпнуть некоторые дизайнерские идеи из их подхода.