在OS X中辅助(或任何非主要)监视器上最大化未修饰帧时出现问题。似乎在第二台监视器上最大化帧时,使用主监视器的边界并且帧大小超出屏幕范围(如果主监视器更大)或者它没有填满整个屏幕(如果主监视器更小)。
OS X Yosemite中的Java 1.8.0_40出现问题。在Windows和Linux中测试时没有出现此问题。
运行应用程序时,它看起来像这样。添加了数字网格,以便能够查看框架是否超出屏幕边界。
以下是代码:
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class MaximizeTest extends JFrame {
public static void main(String[] args) {
MaximizeTest frame = new MaximizeTest();
frame.dispose();
frame.setUndecorated(true);
frame.pack();
frame.setSize(400, 400);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private final JPanel mainPanel = new NumberGridPanel();
private final JButton maximizeButton = new JButton();
private final JButton closeButton = new JButton();
public MaximizeTest() {
initComponents();
// Added this to be able to drag the frame to other monitors
MouseAdapter mouseAdapter = new DragMouseAdapter();
addMouseListener(mouseAdapter);
addMouseMotionListener(mouseAdapter);
setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
maximizeButton.setCursor(Cursor.getDefaultCursor());
closeButton.setCursor(Cursor.getDefaultCursor());
}
private void initComponents() {
GridBagConstraints gridBagConstraints;
mainPanel.setLayout(new GridBagLayout());
maximizeButton.setText("Maximize/Minimize");
maximizeButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
int state = getExtendedState();
if ((state & Frame.MAXIMIZED_BOTH) != 0) {
setExtendedState(state & ~Frame.MAXIMIZED_BOTH);
setSize(400, 400);
} else {
// Take OS taskbars and dockbars into account
Insets screenInsets = Toolkit.getDefaultToolkit().getScreenInsets(getGraphicsConfiguration());
if (screenInsets.left == 0 && screenInsets.right == 0
&& screenInsets.top == 0 && screenInsets.bottom == 0) {
setMaximizedBounds(null);
} else {
Rectangle screenBounds = getGraphicsConfiguration().getBounds();
Rectangle newBounds = new Rectangle(
screenInsets.left,
screenInsets.top,
screenBounds.width - (screenInsets.left + screenInsets.right),
screenBounds.height - (screenInsets.top + screenInsets.bottom));
setMaximizedBounds(newBounds);
}
setExtendedState(state | Frame.MAXIMIZED_BOTH);
}
}
});
gridBagConstraints = new GridBagConstraints();
gridBagConstraints.anchor = java.awt.GridBagConstraints.PAGE_END;
mainPanel.add(maximizeButton, gridBagConstraints);
closeButton.setText("Close");
closeButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
System.exit(0);
}
});
gridBagConstraints = new GridBagConstraints();
gridBagConstraints.anchor = java.awt.GridBagConstraints.PAGE_START;
mainPanel.add(closeButton, gridBagConstraints);
getContentPane().add(mainPanel, java.awt.BorderLayout.CENTER);
}
private static class NumberGridPanel extends JPanel {
@Override
protected void paintComponent(Graphics g) {
g.setColor(Color.BLUE);
int gridSize = 30;
int cols = getWidth() / gridSize;
int rows = getHeight() / gridSize;
for (int col = 0; col < cols; col++) {
for (int row = 0; row < rows; row++) {
g.drawString(Integer.toString((col + row) * gridSize), col * gridSize, row * gridSize + 10);
}
}
}
}
private class DragMouseAdapter extends MouseAdapter {
private int previousMouseX;
private int previousMouseY;
@Override
public void mousePressed(MouseEvent e) {
previousMouseX = e.getXOnScreen();
previousMouseY = e.getYOnScreen();
}
@Override
public void mouseDragged(MouseEvent e) {
int state = getExtendedState();
if ((state & Frame.MAXIMIZED_BOTH) == 0) { // if not maximized
setLocation(
e.getXOnScreen() - previousMouseX + getX(),
e.getYOnScreen() - previousMouseY + getY());
previousMouseX = e.getXOnScreen();
previousMouseY = e.getYOnScreen();
}
}
}
}
到目前为止,我还未能在网上找到有关此问题的任何内容。如果有人能帮我解决这个问题,或者指出我正确的方向,我将不胜感激。提前谢谢。
编辑:
经过进一步调查后,似乎不是主屏幕的分辨率影响第二屏幕上的最大化区域,而是两个屏幕的虚拟排列的y偏移。如果主屏幕低于虚拟排列中的辅助屏幕,则在最大化帧时,辅助屏幕顶部会出现间隙。
此外,在更改主屏幕的分辨率后,问题完全消失,即使将分辨率更改回原来的状态,甚至在完成操作系统重启后,我也无法再次重现。