JFrame.setResizable(true)
允许用户调整窗口的宽度和高度。是否存在允许用户仅调整高度的方法?
感谢。
编辑:以下解决方案似乎无效。在360x600 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)
不允许任何拉伸。
答案 0 :(得分:6)
以下代码可以胜任工作。
addComponentListener(new ComponentAdapter() {
@Override
public void componentResized(ComponentEvent e) {
setSize(new Dimension(preferredWidth, getHeight()));
super.componentResized(e);
}
});
答案 1 :(得分:3)
如果您有使用JNI的经验,那么这是一个可能的解决方案。
在Windows和Oracle Hotspot中,此代码允许在最小和最大尺寸之间调整窗口大小,而不会闪烁或导致任何令人讨厌的JFrame-post-resize副作用。如果在创建JFrame并使其可见后调用此代码,那么上面用于catchResized()以捕获调整大小事件的代码可以完全取消,因为Windows具有使用户无法在上方或下方调整大小的功能指定的最小/最大尺寸。
// 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;
}
答案 2 :(得分:2)
我认为没有明确的方法用于此目的。但是,您可以预设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)
之后执行。
答案 3 :(得分:0)
我相信大多数平台都会尊重setMaximumSize
和setMinimumSize
。还有setMaximizedBounds
。
什么行不通的是添加一个侦听器来重置宽度。线程问题使它看起来不愉快。如果你有PL&amp; F装饰的窗户(Windows PL&amp; F不支持),那么它们就可以被黑客攻击。
答案 4 :(得分:0)
而不是setResizable(true)
使用setResizable(false)
事实上setResizable(false)为我做了诀窍。 它甚至禁用了最大化(使图标变暗)
好的,我应该更好地解释自己。我想让可调整大小的东西也起作用。这就是我登陆这个问题的原因。但我终于接受了这个,认为这有助于OP。
我也希望调整大小,但是如果我无法调整大小,那么禁用就更好了,因为它不会搞砸你的内容位置。以为我建议作为解决方案。
答案 5 :(得分:0)
为避免闪烁,您可以覆盖JFrame中的#setBounds方法。似乎每个调整大小都会调用它。像
这样的东西@Override
public void setBounds(int x, int y, int width, int height) {
if (width == FIXED_WIDTH) {
super.setBounds(x, y, width, height);
}
}
为我做了诀窍。
答案 6 :(得分:0)
我正在使用此代码完全用于此目的并且它有效(它实际上是编辑的@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);
}
});
&#13;