Desafio: Maximizar um JFrame e não deixar o usuário restaurá-lo

Esse é o desafio. Suponha por exemplo o seguinte trecho

1. final JFrame frame = new JFrame();                 
2. JComponent panel = new Main().buildPanel();
3. frame.getContentPane().add(panel);
4. frame.pack();
5. frame.setExtendedState(Frame.MAXIMIZED_BOTH);
6. frame.setVisible(true);
7. frame.setResizable(false);

Queremos que não haja possibilidade do usuário restaurar o JFrame.

Por alguma razão secreta, a linha 7 apenas desabilita o botão maximizar/restaurar. Assim o usuário astuto ainda pode usar o clique duplo na barrinha ou então clicar no ícone do JFrame (usualmente uma xícara) e ter o mesmo efeito.

Não adianta pensar em:

7. Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
8. frame.setSize(dim);
9. frame.setResizable(false);

pois não queremos encobrir a barra de tarefas; a não ser que exista um método mais esperto para por exemplo descobrir a área útil da tela. E há: public Rectangle getMaximizedBounds() de java.awt.Frame. O problema é que ele pode retornar null. E ele RETORNA!

Por enquanto a solução está assim.

1. final JFrame frame = new JFrame();                 
2. JComponent panel = new Main().buildPanel();
3. frame.getContentPane().add(panel);
4. frame.pack();
5. frame.setExtendedState(Frame.MAXIMIZED_BOTH);
6. frame.setVisible(true);
7. Rectangle r = frame.getBounds();
8. frame.setExtendedState(Frame.NORMAL);
9. frame.setBounds(r);
10. frame.setResizable(false);

Mas isso é uma inaceitável porque a aplicação já inicia toda louca maximizando e restaurando do nada.

Enfim, alguém tem alguma idéia?

Pergunta provavelmente besta: por que o usuário não pode restaurar a tela?

Por dois motivos:

  1. Porque isso gera comportamentos de interface que eu não preciso resolver. Como eu não vou resolver, se o usuário restaurar vai dar pau na app. E pelo menos isso eu gostaria de evitar. Não implemento a funcionalidade, mas também não vou deixar uma bomba-relógio; um botão esperando ser apertado pra acabar com a app. Esse é o motivo mais importante.

e

  1. porque eu tenho a curiosidade de saber se é possível fazer isso em java (sem reimplementar a api :slight_smile:

Outra pergunta besta: você tem certeza que isso resolve o problema, não importando a resolução da máquina? :slight_smile:

Sim, maximizar resolve o problema não importando a resolução da máquina. Também não adianta definir um tamanho fixo, tipo 600 x 400. Você nunca sabe onde a barra de tarefas vai estar e nem seu tamanho. ( a não ser que exista um método oculto na api do tipo:

public Rectangle getTaskBarPositionAndSize()

:slight_smile:

Sendo assim, respondendo sua questão de forma simples, o único jeito de impedir o redimensionamento em todas as plataformas que é portável é utilizando Window ao invés de JFrame. Você perde a barra de título, mas é o único jeito portável mesmo.

Certo, mas ae eu perco os úteis métodos de Frame e JFrame não é isso?

frame.getContentPane().add(panel);
frame.setExtendedState(Frame.MAXIMIZED_BOTH);

Como eu faria a mesma coisa com Window, eu me pergunto.

Podemos reduzir o problema ao seguinte: Como eu dimensiono um Frame para ocupar o espaço de tela que um frame maximizado ocuparia?

Reduzindo ainda mais o problema: Como eu acho a área útil da tela?

Vamos definir área útil da tela como send = Tookit.getDefaultToolkit().getBounds() - (área da TaskBar, ou o que for)

O problema estaria resolvido se não fosse pelo seguinte fato:

(1) java.awt.Window.setBounds() não funciona enquanto o estado do JFrame é MAXIMIZED_BOTH. Alguém conhece uma saída pra isso?

Se não fosse isso, eu poderia utilizar:

0. myframe.setExtendedState(MAXIMIZED_BOTH);
1. myframe.setBounds(myframe.getBounds()); // aqui eu redimensionei a janela
2. myframe.setExtendedState(NORMAL); //restaurei a janela, mas não importa porque a janela tem o mesmo tamanho maximizado ou não por causa da linha 1.
3. myframe.setResizable(false);

Ae funcionaria direitinho. Mas tem o fato(1)

[quote=Filipe Silva]Podemos reduzir o problema ao seguinte: Como eu dimensiono um Frame para ocupar o espaço de tela que um frame maximizado ocuparia?
[/quote]

Respondi isso esses dias aqui.

Ok, obrigado pela ajuda.

Apenas para ajudar se alguem mais precisar de fazer isso… Pois este foi um dos tópicos q me ajudaram…

depois de alguns testes fiz assim, funcionou bem:

frame.setExtendedState(FrameLauncher.MAXIMIZED_BOTH); Dimension d = Toolkit.getDefaultToolkit().getScreenSize(); frame.setMinimumSize(d); frame.setResizable(false);