использование нескольких jframes: хорошая или плохая практика?

<p>я разрабатываю приложение, которое отображает изображения и воспроизводит звуки из базы данных. я пытаюсь решить, следует ли использовать отдельный jframe для добавления изображений в базу данных из графического интерфейса.</p><p>мне просто интересно, является ли хорошей практикой использование нескольких окон jframe?</p>

<blockquote> <p>мне просто интересно, является ли хорошей практикой использование нескольких jframes?</p> </blockquote><p>плохая (плохая, плохая) практика.</p><ul> <li>недружественный пользователь: пользователь видит несколько значков на панели задач, ожидая увидеть только один. плюс побочные эффекты от проблем с кодированием.</li> <li>кошмар, чтобы кодировать и поддерживать: <ul> <li>a <a href="http://docs.oracle.com/javase/tutorial/uiswing/misc/modality.html">модальное диалоговое окно</a> предлагает простую возможность сосредоточить внимание на содержимом этого диалога - выберите/исправьте/отмените это, <strong> затем </strong> продолжить. несколько кадров нет.</li> <li>диалог (или плавающая панель инструментов) с родительским элементом появится при нажатии на родительского элемента - вам придется реализовать это в кадрах, если это было желаемое поведение.</li> </ul> </li> </ul><hr><p>существует множество способов отображения множества элементов в одном графическом интерфейсе, например:</p><ul> <li> <a href="http://docs.oracle.com/javase/tutorial/uiswing/layout/card.html"><code>cardlayout</code></a> (short <a href="https://stackoverflow.com/a/5786005/418556">demo.</a> ). хорош для: <ol> <li>отображение диалогов как в мастере.</li> <li>отображение списка, дерева и т.д. для элементов, имеющих связанный компонент.</li> <li>переключение между отсутствующим компонентом и видимым компонентом.</li> </ol> </li> <li> <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/internalframe.html"><code>jinternalframe</code>/<code>jdesktoppane</code></a> обычно используется для <a href="http://en.wikipedia.org/wiki/multiple\_document\_interface">mdi</a> .</li> <li> <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/tabbedpane.html"><code>jtabbedpane</code></a> для групп компонентов.</li> <li> <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/splitpane.html"><code>jsplitpane</code></a> способ отображения двух компонентов, важность которых для одного или другого (размер) зависит от того, что делает пользователь.</li> <li> <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/layeredpane.html"><code>jlayeredpane</code></a> много хорошо .. слоистых компонентов.</li> <li> <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/toolbar.html"><code>jtoolbar</code></a> обычно содержит группы действий или элементов управления. может перетаскиваться по всему графическому интерфейсу или полностью отключаться в зависимости от потребностей пользователя. как упоминалось выше, будет минимизировано/восстановлено в соответствии с действиями родителя.</li> <li>как элементы в <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/list.html"><code>jlist</code></a> (простой пример ниже).</li> <li>как узлы в <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/tree.html"><code>jtree</code></a> .</li> <li> <a href="https://stackoverflow.com/a/5630271/418556">вложенные макеты</a> .<br> <img src="https://i.stack.imgur.com/jaqap.png"></li> </ul><p>но если эти стратегии не работают для конкретного варианта использования, попробуйте следующее. создайте один главный <code>jframe</code>, затем укажите <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/dialog.html"><code>jdialog</code></a> или <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/dialog.html#features"><code>joptionpane</code></a> для остальных свободно плавающих элементов, используя рамку в качестве родительского для диалогов.</p><h2>много изображений</h2><p>в этом случае, когда несколько элементов являются изображениями, было бы лучше использовать одно из следующих:</p><ol> <li>единственное <code>jlabel</code> (по центру на панели прокрутки) для отображения любого изображения, интересующего пользователя в данный момент. как видно из <a href="https://stackoverflow.com/a/13463684/418556"><code>imageviewer</code></a> .<br> <img src="https://i.stack.imgur.com/5jxpc.gif"></li> <li>одна строка <code>jlist</code>. как видно из <a href="https://stackoverflow.com/a/9544652/418556">этот ответ</a> . "однорядная" часть этого работает, только если они имеют одинаковые размеры. альтернативно, если вы готовы масштабировать изображения на лету, и все они имеют одинаковое соотношение сторон (например, 4: 3 или 16: 9).</li> </ol><p><img src="https://i.stack.imgur.com/q8hel.jpg"></p>

<p>многократный подход <code>jframe</code> был тем, что я реализовал с тех пор, как начал программировать приложения swing. по большей части, я сделал это в начале, потому что я не знал ничего лучше. <strong> однако </strong>, по мере того, как я становился зрелым в своем опыте и знаниях в качестве разработчика и начал читать и воспринимать мнения столь многих более опытных java разработчики в интернете, я попытался <strong> отойти </strong> от многократного подхода <code>jframe</code> (как в текущих, так и в будущих проектах) только для удовлетворения. .. получить это ... <em> сопротивление от моих клиентов! </em> когда я начал реализовывать модальные диалоговые окна для управления "дочерними" окнами и <code>jinternalframe</code>s для отдельных компонентов, <strong> мои клиенты начали жаловаться! </strong> я был очень удивлен, поскольку делал то, что считал лучшей практикой! но, как говорится, "счастливая жена - это счастливая жизнь". то же самое касается ваших клиентов. конечно, я являюсь подрядчиком, поэтому мои конечные пользователи имеют прямой доступ ко мне, разработчику, что, очевидно, не является обычным сценарием.</p><p>итак, я собираюсь объяснить преимущества многократного подхода <code>jframe</code>, а также рассказать о некоторых минусах, представленных другими.</p><ol> <li><strong> максимальная гибкость в макете </strong> - разрешая отдельные <code>jframe</code>s, вы даете своему конечному пользователю возможность распределять и контролировать то, что находится на его/ее экране. концепция чувствует себя "открытой" и не стесняющей. вы теряете это, когда идете к одному большому <code>jframe</code> и группе <code>jinternalframe</code>s.</li> <li><strong> хорошо работает для очень модульных приложений </strong> - в моем случае большинство моих приложений имеют 3 - 5 больших "модулей", которые действительно не имеют ничего общего друг с другом бы то ни было. например, один модуль может быть панелью мониторинга продаж, а другой - панелью учета. они не разговаривают друг с другом или что-то еще. однако руководитель может захотеть открыть и то, и другое, поскольку отдельные панели на панели задач облегчают его жизнь.</li> <li><strong> позволяет конечным пользователям ссылаться на внешние материалы </strong>. однажды у меня возникла такая ситуация: в моем приложении был "просмотрщик данных", из которого вы могли нажмите "добавить новый", и откроется экран ввода данных. первоначально оба были <code>jframe</code>s. однако я хотел, чтобы экран ввода данных был <code>jdialog</code>, чьим родителем был просмотрщик данных. я внес изменение, и сразу же мне позвонил конечный пользователь, который сильно полагался на то, что он может свернуть или закрыть <strong> средство просмотра </strong> и сохранить <strong> редактор </strong> открылся, когда он ссылался на другую часть программы (или веб-сайт, я не помню). он <strong> не </strong> на мультимониторе, поэтому ему нужно, чтобы диалог ввода был первым и <em> что-то еще </em> быть вторым, с просмотром данных полностью скрытым. это было невозможно с <code>jdialog</code> и, конечно, было бы невозможно и с <code>jinternalframe</code>. я неохотно изменил его, чтобы он стал отдельным <code>jframes</code> для его здравомыслия, но это преподало мне важный урок.</li> <li><strong> миф: трудно кодировать </strong> - это не так в моем опыте. я не понимаю, почему было бы проще создать <code>jinternalframe</code>, чем <code>jframe</code>. на самом деле, по моему опыту, <code>jinternalframes</code> предлагает гораздо меньшую гибкость. я разработал систематический способ обработки открытия и закрытия <code>jframe</code>s в моих приложениях, который действительно хорошо работает. я почти полностью контролирую фрейм из самого кода фрейма; создание нового фрейма <code>swingworker</code>s, который управляет извлечением данных в фоновых потоках и кода графического интерфейса пользователя в edt, восстановление/вывод на передний план фрейма, если пользователь пытается открыть его дважды, и т. д. все, что вам нужно, чтобы открыть мое <code>jframe</code>s, это вызов открытого статического метода <code>open()</code> и метода open в сочетании с событием <code>windowclosing()</code> обрабатывают все остальное (фрейм уже открыт? он не открыт, но загружается? и т. д.) я сделал этот подход шаблоном, так что его не сложно реализовать для каждый кадр.</li> <li><strong> миф/недоказанный: ресурс тяжелый </strong> - я хотел бы увидеть некоторые факты за этим умозрительным утверждением. хотя, возможно, вы могли бы сказать, что <code>jframe</code> требует больше места, чем <code>jinternalframe</code>, даже если вы откроете 100 <code>jframe</code>s, сколько еще ресурсов вы действительно будете использовать? если вас беспокоит утечка памяти из-за ресурсов: вызов <code>dispose()</code> освобождает все ресурсы, используемые фреймом для сборки мусора (и, опять же, я говорю, <code>jinternalframe</code> должен вызывать точно такую же проблему).</li> </ol><p>я много писал и чувствую, что могу писать больше. в любом случае, я надеюсь, что за меня не проголосуют просто потому, что это непопулярное мнение. вопрос явно ценный, и я надеюсь, что дал ценный ответ, даже если это не общее мнение.</p><p>отличным примером нескольких кадров/одного документа на кадр ( <a href="http://en.wikipedia.org/wiki/single\_document\_interface">sdi</a> ) по сравнению с одним кадром/несколькими документами на кадр ( <a href="http://en.wikipedia.org/wiki/multiple\_document\_interface">mdi</a> ) является microsoft excel. некоторые из mdi преимуществ:</p><ul> <li>можно иметь несколько окон непрямоугольной формы, чтобы они не скрывали рабочий стол или другое окно от другого процесса (например, веб-браузера)</li> <li>во время записи во втором окне excel можно открыть окно из другого процесса через одно окно excel - при использовании mdi попытка записи в одном из внутренних окон даст фокус всему окну excel, следовательно, скрывая окно от другого процесса</li> <li>на разных экранах можно размещать разные документы, что особенно полезно, если экраны не имеют одинакового разрешения</li> </ul><p>sdi (интерфейс с одним документом, то есть каждое окно может иметь только один документ):</p><p><img src="https://i.stack.imgur.com/5iv4s.png" alt="enter image description here"></p><p>mdi (многодокументный интерфейс, то есть каждое окно может иметь несколько документов):</p><p><img src="https://i.stack.imgur.com/helur.png" alt="enter image description here"></p>

<p>я бы хотел противопоставить аргумент "не дружественный пользователю" примером, с которым я только что работал.</p><p>в нашем приложении у нас есть главное окно, в котором пользователи запускают различные "программы" в виде отдельных вкладок. в максимально возможной степени мы старались держать наше приложение в этом единственном окне.</p><p>одна из "программ", которые они запускают, представляет список отчетов, которые были сгенерированы системой, и пользователь может щелкнуть значок в каждой строке, чтобы открыть диалоговое окно просмотра отчетов. этот вьюер показывает эквивалент страниц (4) в книжной/альбомной ориентации отчета, поэтому пользователям нравится, что это окно довольно большое, почти полностью заполняющее их экраны.</p><p>несколько месяцев назад мы начали получать запросы от наших клиентов, чтобы сделать эти окна просмотра отчетов немодальными, чтобы они могли одновременно открывать несколько отчетов.</p><p>некоторое время я отказывался от этого запроса, так как не думал, что это хорошее решение. однако мое мнение изменилось, когда я узнал, как пользователи обходят этот "недостаток" нашей системы.</p><p>они открывали программу просмотра, используя функцию "сохранить как", чтобы сохранить отчет как pdf в определенном каталоге, используя acrobat reader, чтобы открыть файл pdf, и затем они сделайте то же самое со следующим отчетом. у них будет несколько читателей acrobat, работающих с различными выводами отчетов, которые они хотят просмотреть.</p><p>поэтому я смягчился и сделал зрителя немодальным. это означает, что у каждого зрителя есть значок на панели задач.</p><p>когда последняя версия была выпущена для них на прошлой неделе, подавляющим ответом было то, что они любят это. это было одним из наших самых популярных последних улучшений в системе.</p><p>итак, вы идете вперед и говорите своим пользователям, что то, что они хотят, плохо, но в конечном итоге это не принесет вам пользы.</p><p>некоторые замечания:</p><ul> <li>кажется, лучше всего использовать jdialog для этих немодальных окон.</li> <li>используйте конструкторы, которые используют новый <code>modalitytype</code> вместо логического аргумента <code>modal</code>. это то, что дает этим диалогам значок панели задач.</li> <li>для немодальных диалогов, передайте в конструктор нулевого родителя, но найдите его относительно своего "родительского" окна.</li> <li>версия 6 java в windows имеет <a href="http://bugs.sun.com/view\_bug.do?bug\_id=6829546">ошибка</a> , что означает, что ваше главное окно может стать "всегда сверху" без вашего ведома. обновление до версии 7, чтобы исправить это</li> </ul>

<p>сделайте jinternalframe в основной кадр и сделайте его невидимым. затем вы можете использовать его для дальнейших событий.</p><pre><code>jinternalframe.setsize(300,150); jinternalframe.setvisible(true); </code></pre>

<p>прошло много времени с тех пор, как я в последний раз касался свинга, но в целом это плохая практика. некоторые из основных недостатков, которые приходят на ум:</p><ul> <li> <p><strong>это дороже:</strong> вам придется выделять больше ресурсов для рисования jframe, чем другие виды оконных контейнеров, такие как dialog или jinternalframe.</p> </li> <li> <p><strong>не удобно для пользователя:</strong> нелегко перемещаться в кучу jframe, склеенных вместе, это будет выглядеть, как будто ваше приложение представляет собой набор приложений, несовместимых и плохо спроектированных.</p> </li> <li> <p><strong>легко использовать jinternalframe</strong> это своего рода реторика, теперь это намного проще, и другие люди умнее (или с большим количеством свободного времени), чем мы уже продумали через шаблон desktop и jinternalframe, поэтому я бы порекомендовал используй это.</p> </li> </ul>

<p>плохая практика определенно. одна из причин заключается в том, что он не очень удобен для пользователя, поскольку каждый <code>jframe</code> отображает новый значок на панели задач. контроль нескольких <code>jframe</code>s заставит вас рвать на себе волосы.</p><p>лично я бы использовал один <code>jframe</code> для вашего типа приложения. способы отображения нескольких вещей зависит от вас, их много. <code>canvas</code>es, <code>jinternalframe</code>, <code>cardlayout</code>, даже <code>jpanel</code>s возможно.</p><p>несколько объектов jframe = боль, неприятности и проблемы.</p>

<p>я думаю, использование нескольких <code>jframe</code>s не очень хорошая идея.</p><p>вместо этого мы можем использовать <code>jpanel</code>s более одного или нескольких <code>jpanel</code> в одном и том же <code>jframe</code>.</p><p>также мы можем переключаться между этим <code>jpanel</code>s. таким образом, это дает нам свободу отображать больше, чем просто в <code>jframe</code>.</p><p>для каждого <code>jpanel</code> мы можем создавать разные вещи, и все это <code>jpanel</code> может отображаться на одном <code>jframe</code>one за один раз.</p><p>для переключения между этим <code>jpanel</code>s используйте <code>jmenubar</code> с <code>jmenuitems</code> для каждого <code>jpanel</code>or 'jbutton<code>for each</code>jpanel`.</p><p>использование нескольких <code>jframe</code> не является хорошей практикой, но в этом нет ничего плохого, если нам нужно более одного <code>jframe</code>.</p><p>но лучше изменить одно <code>jframe</code> для наших различных потребностей, а не иметь несколько <code>jframe</code>s.</p>

<p>если фреймы будут одинакового размера, почему бы не создать фрейм и не передать фрейм в качестве ссылки на него.</p><p>когда вы прошли кадр, вы можете решить, как его заполнить. это было бы похоже на метод расчета среднего числа фигур. будете ли вы создавать метод снова и снова?</p>

<p>это не очень хорошая практика, но даже если вы хотите использовать ее, вы можете использовать шаблон синглтона в качестве ее хорошего. я использовал одноэлементные шаблоны в большинстве моих проектов, это хорошо.</p>