JFrame resizable height ONLY

后端 未结 7 1475
我在风中等你
我在风中等你 2020-12-15 13:16

JFrame.setResizable(true) lets the user resize both the width and height of a window. Does a method exist which allows the user to ONLY resize the height?

相关标签:
7条回答
  • 2020-12-15 13:23

    Instead of setResizable(true) use setResizable(false) Infact setResizable(false) did the trick for me. It even disabled maximization (dimmed the icon)

    Okay, I should have explained myself better. I wanted to get the resizeable thing working too. That's why I landed on this question. But I finally went with this, thought that would help the OP.

    I wanted to do resizable too, but thought if I can't get resizable to work, disabling is better because it won't mess up your content placement. Thought I'd suggest that as a solution.

    0 讨论(0)
  • 2020-12-15 13:24

    I am using this code exactly for this purpose and it works (it is actually edited @Hoazhun solution as his original code will lock both width and height, but in my version you can set height manually yet having width fixed):

    int defWindowW = 300;
    int defWindowH = 600;
    JFrame MAIN_WINDOW = new JFrame();
    
    MAIN_WINDOW.addComponentListener(new ComponentAdapter() {
    
        public void componentResized(ComponentEvent e) {
    
            int W = Integer.parseInt(e.paramString().split(",")[1].split(" ")[1].split("x")[0].replace(")", ""));
            int H = Integer.parseInt(e.paramString().split(",")[1].split(" ")[1].split("x")[1].replace(")", ""));
    
            /* FOR FIXED WIDTH - ACTIVE NOW, COMMENT IT OUT FOR DISABLING*/ MAIN_WINDOW.setSize(new Dimension(defWindowW, H));
            
            /* FOR FIXED HEIGHT - UNCOMMENT TO MAKE IT ACTIVE */
            //MAIN_WINDOW.setSize(new Dimension(W, defWindowH));
    
            super.componentResized(e);
        }
    });

    0 讨论(0)
  • 2020-12-15 13:26

    I believe most platforms will honour setMaximumSize and setMinimumSize. There is also setMaximizedBounds.

    What doesn't work is adding a listener to reset the width. Threading issues makes it look unpleasant. If you have PL&F decorated windows (not supported by the Windows PL&F), then they can be hacked about with.

    0 讨论(0)
  • 2020-12-15 13:30

    The code below does the job right.

    addComponentListener(new ComponentAdapter() {
    
        @Override
        public void componentResized(ComponentEvent e) {
            setSize(new Dimension(preferredWidth, getHeight()));
            super.componentResized(e);
        }
    
    });
    
    0 讨论(0)
  • 2020-12-15 13:30

    I do not think there is a method expressly for that purpose. However, you could preset the JFrame's preferred, minimum, and maximum size such that the widths are all equal.

    Dimension dimPreferred = frame.getPreferedSize();
    Dimension dimMinimum = frame.getMinimumSize();
    Dimension dimMaximum = frame.getMaximumSize();
    dimPreferred.setWidth( FIXED_WIDTH );
    dimMinimum.setWidth( FIXED_WIDTH );
    dimMaximum.setWidth( FIXED_WIDTH );
    frame.setPreferredSize( dimPreferred );
    frame.setMinimumSize( dimMinimum );
    frame.setMaximumSize( dimMaximum );
    

    You will probably want to do this after frame.pack() and before frame.setVisible(true).

    0 讨论(0)
  • 2020-12-15 13:31

    If you have experience with JNI, then this is a possible solution.

    In Windows and Oracle Hotspot, this code will allow a window to be resized between minimum and maximum dimensions without flickering or causing any of the nasty JFrame-post-resize side-effects. If this code is called once the JFrame is created and made visible, then the code used above in componentResized() to catch resize events can be completely done away with, as Windows has facilities to keep the user from being able to resize above or below the specified min/max sizes.

    // Java code:

    static {
        if (System.getProperty("sun.arch.data.model").equals("32"))
        {   // 32-bit JVM
            System.loadLibrary("my32bitdll");
            System.out.println("Running 32-bit JVM");
    
        } else {
            // 64-bit JVM
            System.loadLibrary("my64bitdll");
            System.out.println("Running 64-bit JVM");
        }
    }
    // Sets a window to never be resized above or below these minimum widths/heights
    public static native int setMinMaxResizeBoundaries(int hwnd, int minWidth, int minHeight, int maxWidth, int maxHeight);
    

    // C++ code (include standard windows.h, winbase.h, etc)

    // Global variables defined in DllMain.cpp
    // Used for setMinMaxResizeBoundaries()
    struct SHwndMinMax
    {
        HWND    hwnd;
        int     minWidth;
        int     minHeight;
        int     maxWidth;
        int     maxHeight;
        WNDPROC prefWndProc;
    };
    SHwndMinMax gsHwndMinMax[2048];
    int gsHwndMinMaxCount = 0;
    LRESULT CALLBACK MinMaxWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
    
    
    // Code added somwhere:
    // setMinMaxResizeBoundaries()
    // Sets the resize boundary window sizes, so the window will not be resized above/below that size
    JNIEXPORT jint JNICALL Java_your_class_here_setMinMaxResizeBoundaries(JNIEnv* env, jclass cls,
        jint hwnd,
        jint minWidth, jint minHeight,
        jint maxWidth, jint maxHeight)
    {
        // We create a hook for the window, and intercept the WM_GETMINMAXINFO message occurs, and update the info
        if (IsWindow((HWND)hwnd))
        {   // Let's add it
            if (gsHwndMinMaxCount < 2048)
            {   // We're good
                // Can add code here to check if this option is valid or not--so it can later be "unhooked" by a separate function call
                gsHwndMinMax[gsHwndMinMaxCount].hwnd        = (HWND)hwnd;
                gsHwndMinMax[gsHwndMinMaxCount].minWidth    = minWidth;
                gsHwndMinMax[gsHwndMinMaxCount].minHeight   = minHeight;
                gsHwndMinMax[gsHwndMinMaxCount].maxWidth    = maxWidth;
                gsHwndMinMax[gsHwndMinMaxCount].maxHeight   = maxHeight;
                gsHwndMinMax[gsHwndMinMaxCount].prefWndProc = (WNDPROC)SetWindowLongPtr((HWND)hwnd, GWLP_WNDPROC, (LONG_PTR)&MinMaxWindowProc);
                // Success
                ++gsHwndMinMaxCount;
                return(0);
    
            } else {
                // Failuire, too many hooks
                return(-2);
            }
    
        } else {
            // Failure, HWND is not valid
            return(-1);
        }
    }
    
    LRESULT CALLBACK MinMaxWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
        int i;
        MINMAXINFO* mmi;
    
        for (i = 0; i < gsHwndMinMaxCount; i++)
        {
            if (hwnd == gsHwndMinMax[i].hwnd)
            {   // This is our man, see if it's our message
                if (msg == WM_GETMINMAXINFO)
                {   // It is
                    // When maximized, window is at upper-left
                    mmi = (MINMAXINFO*)lParam;
                    mmi->ptMaxSize.x        = gsHwndMinMax[i].maxWidth;
                    mmi->ptMaxSize.y        = gsHwndMinMax[i].maxHeight;
                    mmi->ptMaxPosition.x    = 0;  // Can add code here to properly position the window centered in the screen, etc.
                    mmi->ptMaxPosition.y    = 0;  // Same here
                    // Set the minimum and maximum tracking size (when the user is resizing, what's the smallest and biggest window they see)
                    mmi->ptMinTrackSize.x   = gsHwndMinMax[i].minWidth;
                    mmi->ptMinTrackSize.y   = gsHwndMinMax[i].minHeight;
                    mmi->ptMaxTrackSize.x   = gsHwndMinMax[i].maxWidth;
                    mmi->ptMaxTrackSize.y   = gsHwndMinMax[i].maxHeight;
                    return(DefWindowProc(hwnd, msg, wParam, lParam));
    
                } else {
                    // Nope, pass it on
                    return(CallWindowProc(gsHwndMinMax[i].prefWndProc, hwnd, msg, wParam, lParam));
                }
            }
        }
        return(0);
    }
    

    // The following is code to get the HWND accurately:

    // Java Code (add to Java code above)

    // Returns the HWND for the specified component, or -1 if does not exist
    public static native int getComponentHWND(Component c);
    

    // Code in C++

    // getComponentHWND()
    // Called to return the HWND of the component, if it has one.
    JNIEXPORT jint JNICALL Java_your_class_here_getComponentHWND(JNIEnv* env, jclass cls, jobject obj)
    {
        HWND hWnd = 0;
        typedef jboolean (JNICALL *PJAWT_GETAWT)(JNIEnv*, JAWT*);
        JAWT awt;
        JAWT_DrawingSurface* ds;
        JAWT_DrawingSurfaceInfo* dsi;
        JAWT_Win32DrawingSurfaceInfo* dsi_win;
        jboolean result;
        jint lock;
        HMODULE _hAWT = 0;
    
        // Load AWT Library
        if (!_hAWT)
            _hAWT = LoadLibrary(L"jawt.dll");   // for Java 1.4+
    
        if (!_hAWT)
            _hAWT = LoadLibrary(L"awt.dll");    // for Java 1.3
    
        if (_hAWT)
        {
            PJAWT_GETAWT JAWT_GetAWT = (PJAWT_GETAWT)GetProcAddress(_hAWT, "JAWT_GetAWT");
            if (JAWT_GetAWT)
            {
                awt.version = JAWT_VERSION_1_4;     // Init here with JAWT_VERSION_1_3 or JAWT_VERSION_1_4
                // Get AWT API Interface
                result = JAWT_GetAWT(env, &awt);
                if (result != JNI_FALSE)
                {
                    ds = awt.GetDrawingSurface(env, obj);
                    if (ds != NULL)
                    {
                        lock = ds->Lock(ds);
                        if ((lock & JAWT_LOCK_ERROR) == 0)
                        {
                            dsi = ds->GetDrawingSurfaceInfo(ds);
                            if (dsi)
                            {
                                dsi_win = (JAWT_Win32DrawingSurfaceInfo*)dsi->platformInfo;
                                if (dsi_win)
                                    hWnd = dsi_win->hwnd;
                                else
                                    hWnd = (HWND) -1;   // Failed to obtain the handle (not running on Windows)
    
                                ds->FreeDrawingSurfaceInfo(dsi);
    
                            } else {
                                hWnd = (HWND)-2;    // Failed to get the drawing surface info block
                            }
                            ds->Unlock(ds);
    
                        } else {
                            hWnd = (HWND)-3;    // Failed to lock the drawing surface to obtain information about it
                        }
                        awt.FreeDrawingSurface(ds);
    
                    } else {
                        hWnd = (HWND)-4;    // Failed to get the drawing surface from the compoment
                    }
                } else {
                    hWnd = (HWND)-5;    // Failed to obtain a proper result from _JAWT_GetAWT()
                }
            } else {
                hWnd = (HWND)-6;    // Failed to find "_JAWT_GetAWT()" function
            }
        } else {
            hWnd = (HWND)-7;    // Failed to load awt.dll
        }
        return (jint)hWnd;
    }
    
    0 讨论(0)
提交回复
热议问题