JFrame仅适用于可resize的高度

JFrame.setResizable(true)允许用户调整窗口的宽度和高度。 是否存在允许用户仅调整高度的方法?

谢谢。

编辑:下面的解决方案似乎不起作用。 在360×600 JFrame上,

 setResizable(true); pack(); setMaximizedBounds(new java.awt.Rectangle(0, 0, 360, 1200)); setMaximumSize(new java.awt.Dimension(360, 1200)); setMinimumSize(new java.awt.Dimension(360, 600)); setPreferredSize(new java.awt.Dimension(360, 600)); setVisible(true); 

仍然允许完全拉伸JFrame的宽度,并且设置setResizable(false)不允许任何拉伸。

下面的代码完成了工作。

 addComponentListener(new ComponentAdapter() { @Override public void componentResized(ComponentEvent e) { setSize(new Dimension(preferredWidth, getHeight())); super.componentResized(e); } }); 

如果您有JNI的经验,那么这是一个可能的解决方案。

在Windows和Oracle Hotspot中,此代码允许在最小和最大维度之间调整窗口大小,而不会闪烁或导致任何令人讨厌的JFrame-post-resize副作用。 如果在创建JFrame并使其可见之后调用此代码,那么上面在componentResized()中用于捕获resize事件的代码可以完全取消,因为Windows具有使用户无法在上方或下方resize的function指定的最小/最大尺寸。

// Java代码:

 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 ++代码(包括标准的windows.h,winbase.h等)

 // 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); } 

//以下是准确获取HWND的代码:

// Java代码(添加到上面的Java代码)

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

// 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; } 

我认为没有明确的方法用于此目的。 但是,您可以预设JFrame的首选,最小和最大大小,使宽度全部相等。

 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 ); 

您可能希望 frame.pack()frame.setVisible(true) 之前执行此操作。

我相信大多数平台都会尊重setMaximumSizesetMinimumSize 。 还有setMaximizedBounds

什么是行不通的是添加一个侦听器来重置宽度。 线程问题使它看起来不愉快。 如果你有PL&F装饰的窗户(Windows PL&F不支持),那么他们可以被黑客入侵。

而不是setResizable(true)使用setResizable(false) Infact setResizable(false)为我做了诀窍。 它甚至禁用最大化(使图标变暗)

好的,我应该更好地解释自己。 我想让可resize的东西也起作用。 这就是我登陆这个问题的原因。 但我终于接受了这个,认为这将有助于OP。

我也想进行大小调整,但是如果我无法resize,那么禁用就更好了,因为它不会搞砸你的内容放置。 以为我建议作为解决方案。

为避免闪烁,您可以覆盖JFrame中的#setBounds方法。 似乎每个resize都会调用它。 就像是

 @Override public void setBounds(int x, int y, int width, int height) { if (width == FIXED_WIDTH) { super.setBounds(x, y, width, height); } } 

为我做了诀窍。

我正在使用此代码完全用于此目的并且它有效(它实际上是编辑@Hoazhun解决方案,因为他的原始代码将锁定宽度和高度,但在我的版本中,您可以手动设置高度,但宽度固定):

 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); } });