Windows WindowDecorationの最小化ボタンをクリックし、Alt-Tabbingでウィンドウを最小化するかWindowsタスクバーでクリックを最小化することで、画面の左側にAero-SnappedしたJFrame
を最小化すると、フレームが正しくスナップされます左に。良い!これは、WindowsのAero Snap機能についてJava Frameを教える唯一の方法ですか?
しかし、私は
setExtendedState(getExtendedState() | Frame.ICONIFIED);
によってフレームを最小化してWindowsのタスクバー上にマウスを移動することにより、プレビューを見れば、それはフレーム間違った位置を示しています。 Alt-Tabbingでウィンドウを最小化した後、またはWindowsのTaskBarでクリックした後、フレームが間違った位置とサイズで復元されます。フレーム境界は、ウィンドウをScreenBorderから離してドラッグすると復元されることをWindowsが通常記憶している「スナップされていない」値です。バグの
画面録画:
私の結論は、JavaがAeroSnapについて知らないこと、であり、Windowsに間違った境界を提供します。
これはバグのための私の修正である(例えばToolkit.getDefaultToolkit().isFrameStateSupported(Frame.MAXIMIZED_VERT));
falseを返す):
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);
}
});
}
}
これは、のWindows7の下にあるすべての状況で動作しているようですが、それはあまりにも多くのウィンドウ管理いじりのように感じています。何らかの理由でこれをLinuxやMacOSでテストすることは避けました;-)
AeroSnapとJavaフレームを連携させるより良い方法はありますか?
編集:
私は、Oracleのバグを提出しました:http://bugs.java.com/bugdatabase/view_bug.do?bug_id=8147840
まだ存在しない場合は、JDKバグとして提出する必要があります。 – user1803551
ちょっとした注意: 'Frame.ICONIFIED'の代わりに' JFrame.ICONIFIED'を使うと 'Frame'インポートを削除できます。 – user1803551
これはJDK 9(http://bugs.java.com/bugdatabase/view_bug.do?bug_id=8037575)で修正されたようです。 – user1803551