O uso de vários JFrames: boas ou más práticas? [Fechado]
Estou desenvolvendo um aplicativo que exibe imagens e reproduz sons de um banco de dados. Estou tentando decidir se devo ou não usar um JFrame separado para adicionar imagens ao banco de dados da GUI.
Só estou me perguntando se é uma boa prática usar várias janelas JFrame.
Respostas
Só estou me perguntando se é uma boa prática usar vários JFrames.
Prática ruim (ruim, ruim).
- Usuário hostil: o usuário vê vários ícones em sua barra de tarefas quando espera ver apenas um. Além dos efeitos colaterais dos problemas de codificação.
- Um pesadelo para codificar e manter:
- Um diálogo modal oferece a oportunidade fácil de focar a atenção no conteúdo desse diálogo - escolha / corrija / cancele isso e prossiga. Quadros múltiplos, não.
- Uma caixa de diálogo (ou barra de ferramentas flutuante) com um pai virá à frente quando o pai for clicado - você teria que implementar isso em frames se esse fosse o comportamento desejado.
Existem várias maneiras de exibir muitos elementos em uma GUI, por exemplo:
- CardLayout(breve demonstração ). Bom para:
- Mostrando caixas de diálogo semelhantes ao assistente.
- Exibindo seleções de lista, árvore etc. para itens que têm um componente associado.
- Alternando entre nenhum componente e componente visível.
- JInternalFrame/JDesktopPane normalmente usado para um MDI .
- JTabbedPane para grupos de componentes.
- JSplitPane Uma forma de exibir dois componentes cuja importância entre um ou outro (o tamanho) varia de acordo com o que o usuário está fazendo.
- JLayeredPane muitos componentes bem .. em camadas.
- JToolBarnormalmente contém grupos de ações ou controles. Pode ser arrastado ao redor da GUI ou totalmente de acordo com a necessidade do usuário. Conforme mencionado acima, irá minimizar / restaurar de acordo com o pai fazendo isso.
- Como itens em a JList(exemplo simples abaixo).
- Como nós em a JTree.
- Layouts aninhados .
Mas se essas estratégias não funcionarem para um caso de uso específico, tente o seguinte. Estabeleça um único principal e JFrame
, em seguida, tenha JDialogou JOptionPaneocorrências para o restante dos elementos flutuantes livres, usando o quadro como pai para as caixas de diálogo.
Muitas imagens
Neste caso, onde os vários elementos são imagens, seria melhor usar um dos seguintes:
- Um único
JLabel
(centralizado em um painel de rolagem) para exibir qualquer imagem na qual o usuário esteja interessado naquele momento. Como visto em ImageViewer.
- Uma única linha
JList
. Conforme visto nesta resposta . A parte da 'linha única' só funciona se forem todas as mesmas dimensões. Como alternativa, se você estiver preparado para dimensionar as imagens instantaneamente, e todas elas tiverem a mesma proporção (por exemplo, 4: 3 ou 16: 9).
A JFrame
abordagem múltipla tem sido algo que implementei desde que comecei a programar aplicativos Swing. Na maior parte, eu fiz isso no começo porque não sabia de nada. No entanto , conforme amadureci em minha experiência e conhecimento como desenvolvedor e comecei a ler e absorver as opiniões de muitos desenvolvedores Java mais experientes online, fiz uma tentativa de me afastar da JFrame
abordagem múltipla (tanto em projetos atuais quanto em projetos futuros ) apenas para encontrar ... veja só ... resistência dos meus clientes! Quando comecei a implementar diálogos modais para controlar janelas "filho" e programas JInternalFrame
para componentes separados, meus clientes começaram a reclamar! Fiquei bastante surpreso, pois estava fazendo o que achei ser a melhor prática! Mas, como se costuma dizer, "Uma esposa feliz é uma vida feliz." O mesmo vale para seus clientes. Claro, eu sou um contratante, então meus usuários finais têm acesso direto a mim, o desenvolvedor, o que obviamente não é um cenário comum.
Então, vou explicar os benefícios da JFrame
abordagem múltipla , bem como acabar com alguns dos contras que outros apresentaram.
- Flexibilidade máxima em layout - ao permitir programas separados
JFrame
, você dá ao usuário final a capacidade de espalhar e controlar o que está em sua tela. O conceito parece "aberto" e não constrangedor. Você perde isso quando vai para um grandeJFrame
e um monte deJInternalFrame
s. - Funciona bem para aplicativos muito modularizados - No meu caso, a maioria dos meus aplicativos tem de 3 a 5 grandes "módulos" que realmente não têm nada a ver um com o outro. Por exemplo, um módulo pode ser um painel de vendas e outro pode ser um painel de contabilidade. Eles não se falam nem nada. No entanto, o executivo pode querer abrir os dois e, sendo quadros separados na barra de tarefas, torna sua vida mais fácil.
- Facilita a consulta de materiais externos pelos usuários finais - Certa vez, tive a seguinte situação: meu aplicativo tinha um "visualizador de dados", no qual você podia clicar em "Adicionar novo" e abrir uma tela de entrada de dados. Inicialmente, ambos eram
JFrame
s. No entanto, eu queria que a tela de entrada de dados fosse umaJDialog
cujo pai fosse o visualizador de dados. Fiz a alteração e imediatamente recebi uma ligação de um usuário final que confiava fortemente no fato de que ele poderia minimizar ou fechar o visualizador e manter o editor aberto enquanto ele fazia referência a outra parte do programa (ou um site, eu não não me lembro). Ele não está em um monitor múltiplo, então precisava que a caixa de diálogo de entrada fosse a primeira e outra coisa para ser a segunda, com o visualizador de dados completamente oculto. Isso era impossível com umJDialog
e certamente seria impossível com umJInternalFrame
também. Eu relutantemente mudei de volta para ser separadoJFrames
por causa da sanidade dele, mas isso me ensinou uma lição importante. - Mito: Difícil de codificar - Isso não é verdade na minha experiência. Não vejo por que seria mais fácil criar um do
JInternalFrame
que umJFrame
. Na verdade, na minha experiência,JInternalFrames
oferece muito menos flexibilidade. Eu desenvolvi uma maneira sistemática de lidar com a abertura e fechamento deJFrame
s em meus aplicativos que realmente funciona bem. Eu controlo o quadro quase completamente de dentro do próprio código do quadro; a criação do novo quadro,SwingWorker
s que controlam a recuperação de dados em threads de fundo e o código GUI em EDT, restaurando / trazendo para frente o quadro se o usuário tentar abri-lo duas vezes, etc. Tudo que você precisa para abrir o meuJFrame
s é chamar um método estático públicoopen()
e o método aberto, combinado com umwindowClosing()
evento, trata do resto (o quadro já está aberto? Não está aberto, mas carregando? etc.) Fiz dessa abordagem um modelo para que não seja difícil de implementar para cada quadro . - Mito / Não Provado: Recursos Pesados - Eu gostaria de ver alguns fatos por trás dessa afirmação especulativa. Embora, talvez, você possa dizer que a
JFrame
precisa de mais espaço do que aJInternalFrame
, mesmo se você abrir 100JFrame
s, quantos recursos a mais você realmente estaria consumindo? Se sua preocupação são vazamentos de memória devido a recursos: a chamadadispose()
libera todos os recursos usados pelo frame para a coleta de lixo (e, novamente, eu digo, aJInternalFrame
deve invocar exatamente a mesma preocupação).
Já escrevi muito e sinto que poderia escrever mais. De qualquer forma, espero não ser rejeitado simplesmente porque é uma opinião impopular. A pergunta é claramente valiosa e espero ter fornecido uma resposta valiosa, mesmo que não seja a opinião comum.
Um ótimo exemplo de quadros múltiplos / documento único por quadro ( SDI ) vs quadro único / documentos múltiplos por quadro ( MDI ) é o Microsoft Excel. Alguns dos benefícios do MDI:
- é possível ter algumas janelas em forma não retangular - para que não escondam a área de trabalho ou outra janela de outro processo (por exemplo, navegador da web)
- é possível abrir uma janela de outro processo sobre uma janela do Excel enquanto escreve na segunda janela do Excel - com MDI, tentar escrever em uma das janelas internas dará foco a toda a janela do Excel, ocultando a janela de outro processo
- é possível ter documentos diferentes em telas diferentes, o que é especialmente útil quando as telas não têm a mesma resolução
SDI (Interface de Documento Único, ou seja, cada janela só pode ter um único documento):
MDI (Multiple-Document Interface, ou seja, cada janela pode ter vários documentos):
Gostaria de rebater o argumento "não amigável" com um exemplo com o qual acabei de falar.
Em nosso aplicativo, temos uma janela principal onde os usuários executam vários 'programas' como guias separadas. Tanto quanto possível, tentamos manter nosso aplicativo nesta única janela.
Um dos 'programas' que eles executam apresenta uma lista de relatórios que foram gerados pelo sistema, e o usuário pode clicar em um ícone em cada linha para abrir uma caixa de diálogo do visualizador de relatório. Este visualizador está mostrando o equivalente à (s) página (s) A4 retrato / paisagem do relatório, então os usuários gostam que essa janela seja bem grande, quase enchendo suas telas.
Há alguns meses, começamos a receber solicitações de nossos clientes para tornar essas janelas do visualizador de relatórios sem janela restrita, para que pudessem ter vários relatórios abertos ao mesmo tempo.
Por algum tempo resisti a esse pedido, pois não achava que fosse uma boa solução. No entanto, minha mente mudou quando descobri como os usuários estavam contornando essa 'deficiência' do nosso sistema.
Eles estavam abrindo um visualizador, usando o recurso 'Salvar como' para salvar o relatório como PDF em um diretório específico, usando o Acrobat Reader para abrir o arquivo PDF, e então fariam o mesmo com o próximo relatório. Eles teriam vários Leitores Acrobat em execução com as várias saídas de relatório que desejavam ver.
Então cedi e tornei o visualizador sem modelo. Isso significa que cada visualizador possui um ícone na barra de tarefas.
Quando a última versão foi lançada para eles na semana passada, a resposta esmagadora deles é que eles AMARAM. É um de nossos aprimoramentos recentes mais populares no sistema.
Então você vai em frente e diz a seus usuários que o que eles querem é ruim, mas no final das contas não vai te ajudar em nada.
ALGUMAS NOTAS:
- Parece ser a melhor prática usar o JDialog para essas janelas sem janela restrita
- Use os construtores que usam o argumento new
ModalityType
em vez do booleanomodal
. Isso é o que dá a essas caixas de diálogo o ícone da barra de tarefas. - Para diálogos sem janela restrita, passe um pai nulo para o construtor, mas localize-o em relação à janela 'pai'.
- A versão 6 do Java no Windows tem um bug que significa que sua janela principal pode ficar 'sempre visível' sem você avisar. Atualize para a versão 7 para corrigir isso
Transforme um jInternalFrame no quadro principal e torne-o invisível. Então você pode usá-lo para outros eventos.
jInternalFrame.setSize(300,150);
jInternalFrame.setVisible(true);
Já faz um tempo desde a última vez que toquei no swing, mas em geral é uma má prática fazer isso. Algumas das principais desvantagens que vêm à mente:
É mais caro: você terá que alocar muito mais recursos para desenhar um JFrame que outro tipo de container de janela, como Dialog ou JInternalFrame.
Não amigável: não é fácil navegar em um monte de JFrame agrupados, parecerá que seu aplicativo é um conjunto de aplicativos inconsistentes e com design inadequado.
É fácil de usar JInternalFrame Isso é meio retórico, agora é muito mais fácil e outras pessoas mais espertas (ou com mais tempo livre) do que nós já pensamos no padrão Desktop e JInternalFrame, então eu recomendo usá-lo.
Má prática, definitivamente. Um dos motivos é que ele não é muito "amigável" pelo fato de cada JFrame
um mostrar um novo ícone na barra de tarefas. O controle de vários JFrame
s terá que arrancar seus cabelos.
Pessoalmente, eu usaria o ONE JFrame
para o seu tipo de aplicativo. Os métodos de exibição de várias coisas dependem de você, há muitos. Canvas
es, JInternalFrame
, CardLayout
, mesmo JPanel
é possivelmente.
Vários objetos JFrame = Dor, problemas e problemas.
Acho que usar vários Jframe
s não é uma boa ideia.
Em vez disso, podemos usar JPanel
s mais de um ou mais JPanel
no mesmo JFrame
.
Também podemos alternar entre este JPanel
s. Portanto, isso nos dá liberdade para exibir mais do que apenas uma coisa no JFrame
.
Para cada um JPanel
podemos projetar coisas diferentes e tudo isso JPanel
pode ser exibido em JFrame
um de cada vez.
Para alternar entre esta JPanel
s uso JMenuBar
com JMenuItems
para cada JPanel
ou 'JButton for each
JPanel`.
Mais de um JFrame
não é uma boa prática, mas não há nada de errado se quisermos mais de um JFrame
.
Mas é melhor mudar um JFrame
para nossas diferentes necessidades em vez de ter vários JFrame
s.
Se os frames vão ter o mesmo tamanho, por que não criar o frame e passar o frame então como uma referência a ele?
Depois de passar pelo quadro, você pode decidir como preenchê-lo. Seria como ter um método para calcular a média de um conjunto de algarismos. Você criaria o método repetidamente?
Não é uma boa prática, mas mesmo que você deseje usá-lo, você pode usar o padrão singleton como adequado. Eu usei os padrões singleton na maior parte do meu projeto, é bom.