程序不会在 JFrame 高度最大化时重新绘制 [英] Program not repainting upon JFrame height maximizing

查看:23
本文介绍了程序不会在 JFrame 高度最大化时重新绘制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您可以通过多种方式通过鼠标拖动来调整 JFrame 的大小:

You can resize JFrame with mouse dragging in several ways:

  1. 您可以调整它的高度(顶部/底部边缘)
  2. 您可以调整它的宽度(左/右边缘)
  3. 您可以调整两者的大小(在角落)
  4. 您可以通过将整个窗口拖动到显示器顶部边缘来最大化它
  5. 您可以通过将其顶部/底部边缘拖动到显示器的顶部/底部边缘来最大化其高度

我的程序正在重绘除数字 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();
      }
    });

这篇关于程序不会在 JFrame 高度最大化时重新绘制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆