2011-09-13 9 views
9

Il seguente codice di oscillazione non funziona correttamente sulla mia macchina o le mie macchine collaboratori (tutti i Windows XP & Java 6):JFrame.setExtendedState (MAXIMIZED_BOTH) funziona con frame non decorati?

public class Test { 
    public static void main(String[] args) { 
     final JFrame frame = new JFrame(); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setSize(800, 600); 
     frame.setLayout(new FlowLayout()); 
     frame.add(new JButton(new AbstractAction("Maximize") { 
      @Override 
      public void actionPerformed(ActionEvent e) { 
       frame.setExtendedState((frame.getExtendedState() & Frame.MAXIMIZED_BOTH) == Frame.MAXIMIZED_BOTH ? JFrame.NORMAL : JFrame.MAXIMIZED_BOTH); 
      } 
     })); 
     frame.setUndecorated(true); 
     frame.setVisible(true); 
    } 
} 

massimizza la finestra, ma non prende in considerazione l'attività di Windows barra (riempie lo schermo). Se commentate "frame.setUndecorated (true);" sembra funzionare correttamente.

Il Javadoc sembra implicare che questo dovrebbe funzionare. È un bug in Java? È limitato a una versione specifica o versione di Windows? C'è una soluzione?

Ho visto un few workarounds, ma sembrano incompleti. Non posso essere la prima persona a codificare le mie decorazioni frame in Java.

EDIT: Dopo aver scaricato l'OpenJDK e scavare attraverso il codice nativo, ho trovato che Java sta chiamando la funzione Win32 SetWindowPlacement e in alcune condizioni alterare MINMAXINFO per ottenere la dimensione finestra di destra. Penso che quello che stavo vedendo era il comportamento predefinito di Windows per una finestra senza titolo o bordo (anche se non riesco a trovarlo documentato da nessuna parte). Ho scoperto che chiamare JFrame.setMaximizedBounds() fornisce i limiti usati per modificare la struttura MINMAXINFO di win32. Così alterando la mia azione eseguita e utilizzando la dimensione della finestra suggerito da camickr come i miei MaximizedBounds, ho un po 'più vicino:

GraphicsConfiguration graphicsConfiguration = frame.getGraphicsConfiguration(); 
frame.setMaximizedBounds(graphicsConfiguration.getBounds()); 
frame.setExtendedState((frame.getExtendedState() & Frame.MAXIMIZED_BOTH) == Frame.MAXIMIZED_BOTH ? JFrame.NORMAL : JFrame.MAXIMIZED_BOTH); 

Ora la finestra di ingrandimento non nasconde la barra dei menu. Ma ora ho un altro problema. Non riesco a massimizzare da un monitor secondario. La cornice scompare.

Aggiungo alcuni tag Win32 nella speranza di ottenere un programmatore C++ che riconosca questo problema.

SOLUZIONE: A quanto pare non posso ancora rispondere alla mia domanda, quindi mi limiterò a mettere la mia soluzione qui. Ho dovuto usare una classe di sole, e non ho ancora testato su tutte le piattaforme diverse da Windows, ma finora questo sembra funzionare bene con più monitor, e molteplici configurazioni della barra delle applicazioni:

GraphicsConfiguration config = frame.getGraphicsConfiguration(); 
Rectangle usableBounds = SunGraphicsEnvironment.getUsableBounds(config.getDevice()); 
frame.setMaximizedBounds(new Rectangle(0, 0, usableBounds.width, usableBounds.height)); 
frame.setExtendedState((frame.getExtendedState() & Frame.MAXIMIZED_BOTH) == Frame.MAXIMIZED_BOTH ? JFrame.NORMAL : JFrame.MAXIMIZED_BOTH); 
+0

ci sono molti thread su, http://download.oracle.com/javase/tutorial/extra/fullscreen/exclusivemode.html, su questo forum – mKorbel

+0

Grazie, ma non sto provando a fare un'app a schermo intero . Probabilmente avrei dovuto essere più chiaro riguardo ai miei obiettivi, ma sto cercando di sostituire la barra del titolo e i controller del sistema operativo con i miei (come Google Chrome, Microsoft Office, ecc.). Sun ha anche provato a farlo una volta, ma ha lo stesso problema che faccio io: 'frame.getRootPane(). SetWindowDecorationStyle (JRootPane.FRAME);' –

risposta

4

Interessante. Quando ci provo sembra che succeda in due passaggi. Prima si espande per riempire lo spazio sopra la barra delle attività, quindi una frazione di secondo dopo copre la barra delle applicazioni. Non ho idea del perché.

In ogni caso per una soluzione alternativa è possibile utilizzare:

GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment(); 
Rectangle bounds = env.getMaximumWindowBounds(); 
System.out.println("Screen Bounds: " + bounds); 

per impostare manualmente i limiti della cornice quando si vuole massimizzare esso.

+0

Questo sembra avvicinarsi, ma impostare i limiti del frame reimposta lo stato esteso su 'normale'. Potrei creare la mia sottoclasse di frame e tenere traccia del mio stato esteso e dei limiti precedenti, ma il sistema operativo non è a conoscenza di questo stato simulato e mi tradirebbe in piccoli modi.Inoltre, avrei bisogno di trovare un modo per ottenere i limiti della finestra su più monitor. –

+0

Questa era l'idea per tracciare i limiti e dichiarare te stesso. Non so quali potrebbero essere i problemi sottili Non posso offrire altri consigli lì. Non ho mai giocato con esso, ma per più monitor puoi guardare la classe 'GraphicsDevice'. – camickr

Problemi correlati