Si je minimise une JFrame
qui a été Aéro-ancrée à gauche de l'écran en cliquant sur l'minimiser le bouton de la Windows WindowDecoration et d'agrandir par Alt-Tab ou en cliquant dans la barre des tâches de Windows, le cadre devient restauré correctement ancrée à gauche. Bon!
Mais si je réduis l'image par
setExtendedState( getExtendedState() | Frame.ICONIFIED );
et regardez l'aperçu en passant la souris sur la barre des tâches de Windows, il montre l'image d'une mauvaise position. Après unminimizing par Alt-Tab ou en cliquant dans la barre des tâches de Windows, l'image est reconstituée à cette mauvaise position et de la taille. Le cadre, les limites sont les "unsnapped" valeurs", qui normalement, Windows se souvient de restaurer si vous faites glisser le cadre de l'ScreenBorder.
Un enregistrement d'écran du Bug:
Ma conclusion est que Java ne sait pas sur AeroSnap et offre le mauvais limites pour Windows. (Par exemple, Toolkit.getDefaultToolkit().isFrameStateSupported( Frame.MAXIMIZED_VERT ) );
renvoie la valeur false.)
C'est mon fix pour le bug:
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.Point;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
/**
* Fix for the "Frame does not know the AeroSnap feature of Windows"-Bug.
*
* @author bobndrew 20160106
*/
public class SwingFrameStateWindowsAeroSnapBug extends JFrame
{
Point location = null;
Dimension size = null;
public SwingFrameStateWindowsAeroSnapBug( final String title )
{
super( title );
initUI();
}
private void initUI()
{
setDefaultCloseOperation( EXIT_ON_CLOSE );
setLayout( new FlowLayout() );
final JButton minimize = new JButton( "Minimize" );
final JButton maximize = new JButton( "Maximize" );
final JButton normal = new JButton( "Normal" );
add( normal );
add( minimize );
add( maximize );
pack();
setSize( 200, 200 );
final ActionListener listener = actionEvent ->
{
if ( actionEvent.getSource() == normal )
{
setExtendedState( Frame.NORMAL );
}
else if ( actionEvent.getSource() == minimize )
{
//Size and Location have to be saved here, before the minimizing of an AeroSnapped WindowsWindow leads to wrong values:
location = getLocation();
size = getSize();
System.out.println( "saving location (before iconify) " + size + " and " + location );
setExtendedState( getExtendedState() | Frame.ICONIFIED );//used "getExtendedState() |" to preserve the MAXIMIZED_BOTH state
//does not fix the bug; needs a Window-Drag after DeMinimzing before the size is applied:
// setSize( size );
// setLocation( location );
}
else if ( actionEvent.getSource() == maximize )
{
setExtendedState( getExtendedState() | Frame.MAXIMIZED_BOTH );
}
};
minimize.addActionListener( listener );
maximize.addActionListener( listener );
normal.addActionListener( listener );
addWindowStateListener( windowEvent ->
{
System.out.println( "oldState=" + windowEvent.getOldState() + " newState=" + windowEvent.getNewState() );
if ( size != null && location != null )
{
if ( windowEvent.getOldState() == Frame.ICONIFIED )
{
System.out.println( "Fixing (possibly) wrong size and location on de-iconifying to " + size + " and " + location + "\n" );
setSize( size );
setLocation( location );
//Size and Location should only be applied once. Set NULL to avoid a wrong DeMinimizing of a following Windows-Decoration-Button-Minimize!
size = null;
location = null;
}
else if ( windowEvent.getOldState() == (Frame.ICONIFIED | Frame.MAXIMIZED_BOTH) )
{
System.out.println( "Set size and location to NULL (old values: " + size + " and " + location + ")" );
//Size and Location does not have to be applied, Java can handle the MAXIMIZED_BOTH state. Set NULL to avoid a wrong DeMinimizing of a following Windows-Decoration-Button-Minimize!
size = null;
location = null;
}
}
} );
}
public static void main( final String[] args )
{
SwingUtilities.invokeLater( new Runnable()
{
@Override
public void run()
{
new SwingFrameStateWindowsAeroSnapBug( "AeroSnap and the Frame State" ).setVisible( true );
}
} );
}
}
Cela semble fonctionner pour toutes les situations sous Windows7, mais il se sent comme trop déconner avec la fenêtre de gestion. Et j'ai évité de tester cette sous Linux ou MacOS pour une raison ;-)
Est-il un meilleur moyen de faire AeroSnap et Java Cadres de travailler ensemble?
Edit:
J'ai déposé un bug chez Oracle: http://bugs.java.com/bugdatabase/view_bug.do?bug_id=8147840