Program not repainting upon JFrame height maximizing

前端 未结 2 987
长情又很酷
长情又很酷 2021-01-07 00:07

You can resize JFrame with mouse dragging in several ways:

  1. You can resize it\'s height (top/bottom edge)
  2. You can resize it\'s width (left/right edge)<
2条回答
  •  挽巷
    挽巷 (楼主)
    2021-01-07 00:40

    BTW: Action 5 can also be invoked by double-clicking on the top/bottom corner of a window (in Windows 8 at least).

    @Enwired: Your solution works only when the window is actually moved during the maximize. But it does not work, when the window is already at y=0, when invoking the vertical maximize. (I use a little tool called AltDrag which snaps windows to the borders of the screen, which makes this case a lot more likely. But a new window which wasn't moved or repositioned initially might have the same problem.)

    I noticed, that when a window is vertically maximized paint() is called once on the window.

    So a solution for the maximize action would be to override paint() and do this:

    @Override
    public void paint(Graphics g)
    {
        checkResizeWindow(this);
        super.paint(g);
    }
    
    public static void checkResizeWindow(Window window)
    {
        if (!window.isShowing())
        {
            return;
        }
        Component[] components = window.getComponents();
        if (components.length == 0)
        {
            return;
        }
        Component comp = components[0];
        Insets insets = window.getInsets();
        Dimension innerSize = window.getSize();
        innerSize.width -= insets.left + insets.right;
        innerSize.height -= insets.top + insets.bottom;
        if (!innerSize.equals(comp.getSize()))
        {
            window.invalidate();
            window.validate();
        }
    }
    

    The calculation i use is to determine if the window actually needs revalidation, by checking the the innerSize against the first child component's size (which usually is a single Panel filling out the whole innerSize).

    But, the same original problem still remains for the restore action. We would have to find an event which is called in that case and also call checkResizeWindow() at that point.

    I was also thinking about...

    • using other events like MouseMotion or Focus, but they occur only later and some might even occur very often which could cause problems with our checkResizeWindow() method when being invoked too fast repeatedly.
    • using a recurring polling check calling checkResizeWindow() on every window, but polling is a bad concept in general and has it's own downsides.

提交回复
热议问题