Использование нескольких JFrames: хорошая или плохая практика?
Я разрабатываю приложение, которое отображает изображения и воспроизводит звуки из базы данных. Я пытаюсь решить, следует ли использовать отдельный JFrame для добавления изображений в базу данных из графического интерфейса.
Мне просто интересно, является ли хорошей практикой использование нескольких окон JFrame?
9 ответов
Мне просто интересно, является ли хорошей практикой использование нескольких JFrames?
Плохая (плохая, плохая) практика.
- Недружественный пользователь: пользователь видит несколько значков на панели задач, ожидая увидеть только один. Плюс побочные эффекты от проблем с кодированием.
- Кошмар, чтобы кодировать и поддерживать:
- Модальное диалоговое окно предлагает простую возможность сосредоточить внимание на содержании этого диалогового окна - выберите / исправьте / отмените это, затем продолжите. Несколько кадров нет.
- Диалог (или плавающая панель инструментов) с родителем появится при нажатии на родителя - вам придется реализовать это в кадрах, если это было желаемое поведение.
Существует множество способов отображения множества элементов в одном графическом интерфейсе, например:
CardLayout
(короткая демонстрация.) Хорош для:- Отображение диалогов как в мастере.
- Отображение списка, дерева и т. Д. Для элементов, имеющих связанный компонент.
- Переключение между отсутствующим компонентом и видимым компонентом.
JInternalFrame
/JDesktopPane
обычно используется для MDI.JTabbedPane
для групп компонентов.JSplitPane
Способ отображения двух компонентов, значение которых между одним или другим (размер) зависит от того, что делает пользователь.JLayeredPane
далеко много хорошо.. слоистых компонентов.JToolBar
обычно содержит группы действий или элементов управления. Может перетаскиваться по всему графическому интерфейсу или полностью отключаться в соответствии с потребностями пользователя. Как упоминалось выше, будет минимизировано / восстановлено в соответствии с действиями родителя.- Как предметы в
JList
(простой пример ниже). - Как узлы в
JTree
, - Вложенные макеты.
Но если эти стратегии не работают для конкретного варианта использования, попробуйте следующее. Установить единый основной JFrame
тогда есть JDialog
или же JOptionPane
экземпляры появляются для остальных свободно плавающих элементов, используя рамку в качестве родителя для диалогов.
Много изображений
В этом случае, когда несколько элементов являются изображениями, было бы лучше использовать одно из следующих:
- Один
JLabel
(по центру на панели прокрутки), чтобы отобразить любое изображение, интересующее пользователя в данный момент. Как видно вImageViewer
, - Один ряд
JList
, Как видно из этого ответа. "Однорядная" часть этого работает, только если они имеют одинаковые размеры. С другой стороны, если вы готовы масштабировать изображения на лету, и все они имеют одинаковое соотношение сторон (например, 4:3 или 16:9).
Кратный JFrame
с тех пор, как я начал программировать Swing-приложения, я реализовал этот подход. По большей части, я сделал это в начале, потому что я не знал ничего лучше. Тем не менее, по мере того, как я становился зрелым в своем опыте и знаниях в качестве разработчика и начал читать и воспринимать мнения многих более опытных разработчиков Java в Интернете, я попытался отойти от множества JFrame
подход (как в текущих проектах, так и в будущих) только для того, чтобы встретить... получить это... сопротивление от моих клиентов! Когда я начал внедрять модальные диалоги для управления "дочерними" окнами и JInternalFrame
s для отдельных компонентов, мои клиенты начали жаловаться! Я был очень удивлен, поскольку делал то, что считал лучшей практикой! Но, как говорится, "счастливая жена - это счастливая жизнь". То же самое касается ваших клиентов. Конечно, я являюсь подрядчиком, поэтому мои конечные пользователи имеют прямой доступ ко мне, разработчику, что, очевидно, не является обычным сценарием.
Итак, я собираюсь объяснить преимущества множественного JFrame
подход, а также миф-перебор некоторых минусов, которые другие представили.
- Предельная гибкость компоновки
JFrame
s, вы даете своему конечному пользователю возможность распространять и контролировать то, что находится на его / ее экране. Концепция чувствует себя "открытой" и не стесняющей. Вы теряете это, когда вы идете к одному большомуJFrame
и кучаJInternalFrame
s. - Хорошо работает для очень модульных приложений. В моем случае большинство моих приложений имеют 3 - 5 больших "модулей", которые действительно не имеют никакого отношения друг к другу. Например, один модуль может быть панелью мониторинга продаж, а другой - панелью учета. Они не разговаривают друг с другом или что-то еще. Однако руководитель может захотеть открыть и то, и другое, поскольку отдельные панели на панели задач облегчают его жизнь.
- Позволяет конечным пользователям легко ссылаться на внешние материалы. Однажды у меня возникла такая ситуация: у моего приложения был "просмотрщик данных", из которого можно было нажать "Добавить новый", и он откроет экран ввода данных. Первоначально оба были
JFrame
s. Тем не менее, я хотел, чтобы экран ввода данных былJDialog
чей родитель был просмотрщиком данных. Я внес изменение, и сразу же мне позвонил конечный пользователь, который сильно полагался на то, что он может свернуть или закрыть средство просмотра и оставить редактор открытым, пока он ссылается на другую часть программы (или веб-сайт, который я не помню). Он не работает на нескольких мониторах, поэтому ему нужно, чтобы диалог ввода был первым, а что-то еще - вторым, а средство просмотра данных было полностью скрыто. Это было невозможно сJDialog
и, конечно, было бы невозможно сJInternalFrame
также. Я неохотно изменил его обратно, чтобы быть отдельнымJFrames
для его здравомыслия, но это преподало мне важный урок. - Миф: трудно кодировать - это не так в моем опыте. Я не понимаю, почему было бы легче создать
JInternalFrame
чемJFrame
, На самом деле, по моему опыту,JInternalFrames
предлагают гораздо меньше гибкости. Я разработал систематический способ обработки открытия и закрытияJFrame
в моих приложениях это действительно хорошо работает. Я почти полностью контролирую фрейм из самого кода фрейма; создание нового кадра,SwingWorker
s, которые управляют поиском данных в фоновых потоках и кода графического интерфейса пользователя в EDT, восстанавливая / выводя на передний план кадр, если пользователь пытается открыть его дважды, и т. д. Все, что вам нужно, чтобы открыть мойJFrame
s вызывает публичный статический методopen()
и открытый метод, в сочетании сwindowClosing()
событие обрабатывает все остальное (фрейм уже открыт? он не открыт, но загружается? и т. д.). Я сделал этот подход шаблоном, чтобы его было несложно реализовать для каждого фрейма. - Миф / Недоказанный: Ресурс Тяжелый - я хотел бы увидеть некоторые факты за этим умозрительным утверждением. Хотя, возможно, вы могли бы сказать
JFrame
нужно больше места, чемJInternalFrame
, даже если вы откроете 100JFrame
s, сколько еще ресурсов вы бы действительно потребляли? Если вас беспокоит утечка памяти из-за ресурсов:dispose()
освобождает все ресурсы, используемые фреймом для сборки мусора (и, опять же, я говорю,JInternalFrame
должен вызывать точно такие же проблемы).
Я много писал и чувствую, что могу писать больше. В любом случае, я надеюсь, что за меня не проголосуют просто потому, что это непопулярное мнение. Вопрос явно ценный, и я надеюсь, что дал ценный ответ, даже если это не общее мнение.
Отличным примером использования нескольких кадров / одного документа на кадр ( SDI) и одного кадра / нескольких документов на кадр ( MDI) является Microsoft Excel. Некоторые из преимуществ MDI:
- можно иметь несколько окон непрямоугольной формы, чтобы они не скрывали рабочий стол или другое окно от другого процесса (например, веб-браузера)
- во время записи во втором окне Excel можно открыть окно из другого процесса через одно окно Excel - при использовании MDI попытка записи в одном из внутренних окон приведет к фокусированию всего окна Excel, следовательно, сократив окно от другого процесса
- на разных экранах можно размещать разные документы, что особенно полезно, если экраны не имеют одинакового разрешения
SDI (интерфейс с одним документом, т. Е. Каждое окно может иметь только один документ):
MDI (многодокументный интерфейс, т. Е. Каждое окно может иметь несколько документов):
Я бы хотел противопоставить аргумент "не дружественный пользователю" примером, с которым я только что работал.
В нашем приложении у нас есть главное окно, в котором пользователи запускают различные "программы" в виде отдельных вкладок. В максимально возможной степени мы старались держать наше приложение в этом единственном окне.
Одна из "программ", которые они запускают, представляет список отчетов, сгенерированных системой, и пользователь может щелкнуть значок в каждой строке, чтобы открыть диалоговое окно просмотра отчетов. Этот вьюер показывает эквивалент страниц (4) в книжной / альбомной ориентации отчета, поэтому пользователям нравится, что это окно довольно большое, почти полностью заполняющее их экраны.
Несколько месяцев назад мы начали получать запросы от наших клиентов, чтобы сделать эти окна просмотра отчетов немодальными, чтобы они могли одновременно открывать несколько отчетов.
Некоторое время я отказывался от этого запроса, так как не думал, что это хорошее решение. Однако мое мнение изменилось, когда я узнал, как пользователи обходят этот "недостаток" нашей системы.
Они открывали средство просмотра, используя функцию "Сохранить как", чтобы сохранить отчет в виде PDF-файла в определенный каталог, используя Acrobat Reader, чтобы открыть файл PDF, и затем они делали то же самое со следующим отчетом. У них будет несколько читателей Acrobat, работающих с различными выводами отчетов, которые они хотят просмотреть.
Поэтому я смягчился и сделал зрителя немодальным. Это означает, что у каждого зрителя есть значок на панели задач.
Когда последняя версия была выпущена для них на прошлой неделе, подавляющий ответ от них заключается в том, что они ЛЮБЯТ это. Это было одним из наших самых популярных последних улучшений в системе.
Таким образом, вы идете вперед и говорите своим пользователям, что то, что они хотят, плохо, но в конечном итоге это не принесет вам пользы.
НЕКОТОРЫЕ ЗАМЕЧАНИЯ:
- Кажется, лучше всего использовать JDialog для этих немодальных окон.
- Используйте конструкторы, которые используют новый
ModalityType
а не логическоеmodal
аргумент. Это то, что дает этим диалогам значок панели задач. - Для немодальных диалогов, передайте в конструктор нулевого родителя, но найдите его относительно своего "родительского" окна.
- В версии 6 Java на Windows есть ошибка, которая означает, что ваше главное окно может стать "всегда сверху" без вашего ведома. Обновление до версии 7, чтобы исправить это
Сделайте jInternalFrame в основной кадр и сделайте его невидимым. Затем вы можете использовать его для дальнейших событий.
jInternalFrame.setSize(300,150);
jInternalFrame.setVisible(true);
Прошло много времени с тех пор, как я в последний раз касался свинга, но в целом это плохая практика. Некоторые из основных недостатков, которые приходят на ум:
Это дороже: вам придется выделять больше ресурсов для рисования JFrame, чем другие виды оконных контейнеров, такие как Dialog или JInternalFrame.
Не удобно для пользователя. Нелегко ориентироваться в куче JFrame, склеенных вместе, это будет выглядеть так, как будто ваше приложение является набором непоследовательных и плохо спроектированных приложений.
Использовать JInternalFrame просто. Это своего рода реторика, теперь это намного проще, и другие люди умнее (или с большим количеством свободного времени), чем мы уже продумали шаблон Desktop и JInternalFrame, поэтому я бы рекомендовал использовать его.
Плохая практика определенно. Одна из причин заключается в том, что он не очень "удобен" для того факта, что каждый JFrame
показывает новый значок на панели задач. Управление несколькими JFrame
s заставит тебя рвать на себе волосы.
Лично я бы использовал ОДИН JFrame
для вашего вида применения. Способы отображения нескольких вещей зависит от вас, их много. Canvas
эс, JInternalFrame
, CardLayout
, четное JPanel
возможно.
Несколько объектов JFrame = боль, неприятности и проблемы.
Я думаю, используя несколько Jframe
с не очень хорошая идея.
Вместо этого мы можем использовать JPanel
более одного или более JPanel
В то же самое JFrame
,
Также мы можем переключаться между этим JPanel
s. Так что это дает нам свободу отображать больше, чем на вещи в JFrame
,
Для каждого JPanel
мы можем проектировать разные вещи и все это JPanel
может отображаться на сингле JFrame
один за раз.
Для переключения между этим JPanel
использование JMenuBar
с JMenuItems
для каждого JPanel
или 'JButtonfor each
JPanel`.
Больше одного JFrame
это не хорошая практика, но нет ничего плохого, если мы хотим больше, чем один JFrame
,
Но лучше поменять JFrame
для наших разных потребностей, а не иметь несколько JFrame
s.
Если фреймы будут одинакового размера, почему бы не создать фрейм и вместо этого передать фрейм как ссылку на него.
Когда вы прошли кадр, вы можете решить, как его заполнить. Это было бы похоже на метод расчета среднего числа фигур. Вы бы создали метод снова и снова?
Это не очень хорошая практика, но даже если вы хотите использовать ее, вы можете использовать шаблон синглтона в качестве ее хорошего. Я использовал одноэлементные шаблоны в большинстве моих проектов, это хорошо.