程序不会在 JFrame 高度最大化时重新绘制
您可以通过多种方式通过鼠标拖动来调整 JFrame 的大小:
You can resize JFrame with mouse dragging in several ways:
- 您可以调整它的高度(顶部/底部边缘)
- 您可以调整它的宽度(左/右边缘)
- 您可以调整两者的大小(在角落)
- 您可以通过将整个窗口拖动到显示器顶部边缘来最大化它
- 您可以通过将其顶部/底部边缘拖动到显示器的顶部/底部边缘来最大化其高度
我的程序正在重绘除数字 5 之外的每一个动作.
My program is being repainted on every one of this actions except the number 5.
这是为什么呢?
这可能是我的程序中的错误吗?似乎并非如此.我不知道我会在哪里针对该特定情况提出重绘请求...似乎 JFrame 本身应该在每次调整大小后对其 contentPane 调用重绘,对吧?
Could that be bug in my program? It doesn't seem so. I don't know where would I put repaint request for that particular case... It seems that JFrame itself should call repaint on it's contentPane after each resize, right?
它闻起来像 Java 本身的一个错误,在 JFrame 类中.
It smells like a bug in Java itself, in JFrame class.
SSCCE:
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
class Gui
{
Gui()
{
JFrame masterWindow = new JFrame("My very own SSCCE");
masterWindow.setSize(1100, 100);
masterWindow.setLocationRelativeTo(null);
masterWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
masterWindow.setVisible(true);
}
}
class Main
{
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
@Override
public void run()
{
new Gui();
}
});
}
}
抓住 JFrame 的上边缘并将其拖动到屏幕的上边缘并释放.底部延伸部分应该是黑色的.如果你然后最大化它,它应该是灰色的.
Grab the top edge of the JFrame and drag it to the top edge of the screen and release. Bottom extended part should be pitch black. If you then maximize it, it will all be grey, as it should.
我还是说这是 Java 或 Windows 的错误.
I still say it's Java or Windows bug.
推荐答案
这似乎是 Java 的 Windows 实现中的一个错误.(我也在使用 Windows 7 和 JDK7.)
It appears to be a bug in the Windows implementation of Java. (I am also using Windows 7 and JDK7.)
当 Windows 决定改变窗口的高度时,Window 会收到 COMPONENT_MOVED
事件,但不会收到 COMPONENT_RESIZED
事件.
When Windows decides to change the height of the window, a COMPONENT_MOVED
event is received by Window, but no COMPONENT_RESIZED
event is received.
在 Windows 类中,非公共方法 dispatchEventImpl()
将通过调用 invalidate()
和 响应
,但它会忽略 COMPONENT_RESIZED
事件>validate()COMPONENT_MOVED
事件.
Inside the Windows class, the non-public method dispatchEventImpl()
will respond to COMPONENT_RESIZED
events by calling invalidate()
and validate()
, but it will ignore COMPONENT_MOVED
events.
这是一种在发生此类事件后使窗口重新验证自身的蛮力方法.这可能偶尔会使窗口在其他情况下重新验证,但不是很频繁,因为 Window 类本身在每个 COMPONENT_RESIZED
事件之后都进行重新验证,并且报告的错误仅在窗口正在运行时发生由用户主动调整大小.
Here is a brute-force method of making the window re-validate itself after such an event. This may occasionally make the window re-validate in other situations, but not very often since the Window class itself is doing re-validation after every COMPONENT_RESIZED
event, and the reported bug only happens when the window is being actively resized by the user.
masterWindow.addComponentListener(new ComponentAdapter() {
private int oldWidth = 0;
private int oldHeight = 0;
@Override
public void componentResized(ComponentEvent e) {
oldWidth = masterWindow.getWidth();
oldHeight = masterWindow.getHeight();
}
@Override
public void componentMoved(ComponentEvent e) {
if (masterWindow.getWidth() != oldWidth || masterWindow.getHeight() != oldHeight) {
masterWindow.invalidate();
masterWindow.validate();
}
oldWidth = masterWindow.getWidth();
oldHeight = masterWindow.getHeight();
}
});
相关文章