общий вопрос о Java Swing

Я сделал приложение Swing, которое довольно просто по функциональности. Однако код, из которого он состоит, стал довольно большим и, на мой взгляд, очень запутанным. Все свинг-компоненты и действия находятся в одном файле. Так, например, если бы я должен был сделать еще большее приложение с большей функциональностью, код будет довольно сложно пройти.

Итак, мой вопрос заключается в том, как сделать хорошую структуру кода. Или, если есть хорошая веб-страница, я могу прочитать об этом и, если возможно, несколько примеров кода. Я проверил учебник Sun о Swing, но они показали довольно упрощенные примеры.

ОБНОВЛЕНИЕ: я немного подумал и проверил несколько примеров. Я не знаю, правильно ли я понял шаблон MVC. В любом случае, моя идея состоит в том, чтобы разделить каждый JFrame на свой собственный файл класса. После этого у меня есть один MainFrame, который является главным окном приложения. Из этого JFrame я создаю один экземпляр каждого JFrame, который у меня есть. И вызовите эти кадры из MainFrame с помощью Actions. Я не знаю, хорошая ли это идея. Однако в любом случае это значительно облегчает чтение кода.

Вот пример того, что я имел в виду

class Main implements ActionListener {

    private JFrame frame = new JFrame();
    private JButton button1 = new JButton();
    private JPanel panel = new JPanel();

    private FirstFrame frame1 = new FirstFrame();
    private SecondFrame frame2 = new SecondFrame();
    private ThirdFrame frame3 = new ThirdFrame();

    public Main() {
        button1.addActionListener(this);
    }

    public createGUI() {
        frame.setTitle("Main");
        frame.setSize(400,300);
        panel.add(button);

        frame.setVisible(true);
        frame.setLocationRelativeTo(null);
    }

    public static void main(String args[]) {
        new Main().createGUI();
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if(e.getSource() == button1)
        {
            frame1.enable();
        }
    }
}

person starcorn    schedule 26.12.2009    source источник
comment
Отличный вопрос! Я размышлял над этим какое-то время.   -  person Steve De Caux    schedule 26.12.2009


Ответы (4)


Используйте шаблон проектирования Model-View-Controller. Он касается разделения кода пользовательского интерфейса. из Бизнес-логики.

РЕДАКТИРОВАТЬ :

Поскольку OP ищет организованный код, а не гибкий дизайн, я удалил часть конструктора пользовательского интерфейса NetBeans из своего ответа.

person missingfaktor    schedule 26.12.2009
comment
Я использовал надстройки визуального пользовательского интерфейса для Eclipse, но, по моему опыту, это добавит много кода. Это тот же случай для Netbeans? - person starcorn; 26.12.2009
comment
однако, если есть ресурс для чтения, мне также нравится учиться кодировать вручную - person starcorn; 26.12.2009

Организация кода пользовательского интерфейса любого значительного размера — это проблема, о которой на удивление мало написано, учитывая, что у каждого приложения есть одна и та же проблема. Есть несколько техник, которые могут помочь:

  1. Рефакторинг - для очистки после того, как код стал неопрятным.
  2. Шаблон Model View Controller - для разделения проблем.
  3. Объектно-ориентированный дизайн — используйте множество небольших взаимодействующих классов вместо больших фрагментов кода.
  4. «При событии Выполнить действие» — идиома для отделения действий от представлений.
  5. Модели компонентов UML — визуализируйте концепции дизайна выше уровня класса.
  6. Принцип инверсии зависимостей — организуйте зависимости кода.

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

Один подход, который я видел эффективным, заключается в разделении событий, прослушивателей, действий и т. д. на их собственные классы и либо организации их в пакеты по типу, либо использования согласованного соглашения об именах для пакетов, чтобы компонент и связанные с ним классы легко идентифицировать (XDialog, XDialogMouseListener, XDialogCancelAction и т. д.).

Другой подход состоит в том, чтобы посмотреть на некоторые большие приложения с открытым исходным кодом (Eclipse, Firefox, ...) и посмотреть, как они организуют свой код GUI.

person richj    schedule 26.12.2009
comment
Как разделить код? Так как у меня есть некоторые взгляды. Это зависит от действий, поэтому я не могу это разделить. - person starcorn; 26.12.2009
comment
Если вы отделяете действие от представления, и оно больше не компилируется, вы можете ввести дополнительные методы, чтобы разрешить отдельным классам доступ к отсутствующей функциональности. Дополнительные методы должны быть организованы в интерфейсы. Интерфейс может быть объявлен с доступом на уровне пакета, если методы не должны быть общедоступными. - person richj; 26.12.2009
comment
В MVC представления обычно не зависят от действий, хотя в MV2 представление и контроллер могут быть более тесно связаны. Внедрение интерфейсов позволяет вам использовать принцип инверсии зависимостей, чтобы изменить направление любых зависимостей, которые идут неправильным путем. - person richj; 26.12.2009

Я стремлюсь извлечь как можно больше функций, не связанных с графическим интерфейсом, из компонентов Swing. Это означает, что у вас есть дополнительная косвенность. Однако:

  1. слой Swing не делает ничего, кроме взаимодействия с графическим интерфейсом
  2. бизнес-функциональность намного проще тестировать и, следовательно, поддерживать

Я не обязательно говорю о полной модели MVC (хотя это неплохо). Это скорее проблема организации класса/пакета.

person Brian Agnew    schedule 26.12.2009
comment
+1 за прагматизм, я делаю то же самое. В частности, с дизайнером графического интерфейса, таким как JFormDesigner, который позволяет очень легко добавлять действия и обработчики действий для кнопок и т. Д. Имеет смысл иметь все это в одном классе, который вызывает вспомогательные классы. Например, мое действие печати — это просто оболочка, которая вызывает new PrintTask().print(myJob). PrintTask — это отдельный (не внутренний) класс, который не имеет ничего общего с графическим интерфейсом. - person Sam Barnum; 26.12.2009

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

Ключевые моменты:

  • Используйте многоуровневый дизайн. Это не просто упорство-бизнес-интерфейс. Разделите его мельче. Например, слой макета не должен создавать компоненты (кроме макета, обычно JPanels).
  • Предпочитайте композицию наследованию. Нет смысла создавать подклассы, подобные JFrame и JPanel, поэтому не делайте этого.
  • Держите пользовательский интерфейс тонким. Например, рендереры должны иметь очень мало логики. Во-первых, это значительно упрощает тестирование (это автоматизированное тестирование, крупномасштабное ручное тестирование непродуктивно).
person Tom Hawtin - tackline    schedule 26.12.2009