当我查看Frame.setResizable的文档时,我读到了:
Sets whether this frame is resizable by the user.
所以我理解我仍然可以在其上调用setSize以编程方式调整它。但如果我这样做,框架向下移动! (至少在Ubuntu,Unity下)。如果我希望框架与内容的大小相匹配,这尤其令人讨厌。例如,只需尝试以下SSCCE:
package test;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.text.AbstractDocument;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.DocumentFilter;
public class Test2 {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
final JFrame mainFrame = new JFrame("test");
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainFrame.setResizable(false);
final JTextArea field = new JTextArea() {
public Dimension getPreferredSize() {
Dimension pref = super.getPreferredSize();
return new Dimension(Math.max(50, pref.width),Math.max(20, pref.height));
}
};
((AbstractDocument)field.getDocument()).setDocumentFilter(new DocumentFilter() {
@Override
public void replace(DocumentFilter.FilterBypass fb, int offset, int length, String text, AttributeSet attrs) throws BadLocationException {
super.replace(fb, offset, length, text, attrs);
System.out.println("before "+mainFrame.getLocation().y);
mainFrame.pack();
System.out.println("after "+mainFrame.getLocation().y+"\n");
}
});
mainFrame.getContentPane().setLayout(new BorderLayout());
mainFrame.getContentPane().add(field,BorderLayout.CENTER);
mainFrame.pack();
mainFrame.setVisible(true);
}
});
}
}
键入一些字符以使窗口扩展。至少在Unity上,窗口向下移动......我不知道如何解决这个问题。
更新:
上述代码的结果如下:
before 52
after 52
before 80
after 108
before 108
after 108
before 136
after 136
before 164
after 164
before 192
after 192
...
最后,当帧被移动时我不会得到......
如果我在Frame上添加ComponentListener,这是我可以获得的堆栈跟踪:
at test.Test2$1$3.componentMoved(Test2.java:50)
at java.awt.AWTEventMulticaster.componentMoved(AWTEventMulticaster.java:169)
at java.awt.AWTEventMulticaster.componentMoved(AWTEventMulticaster.java:169)
at java.awt.Component.processComponentEvent(Component.java:6345)
at java.awt.Component.processEvent(Component.java:6296)
at java.awt.Container.processEvent(Container.java:2229)
at java.awt.Window.processEvent(Window.java:2022)
at java.awt.Component.dispatchEventImpl(Component.java:4872)
at java.awt.Container.dispatchEventImpl(Container.java:2287)
at java.awt.Window.dispatchEventImpl(Window.java:2719)
at java.awt.Component.dispatchEvent(Component.java:4698)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:747)
at java.awt.EventQueue.access$300(EventQueue.java:103)
at java.awt.EventQueue$3.run(EventQueue.java:706)
at java.awt.EventQueue$3.run(EventQueue.java:704)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:77)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:87)
at java.awt.EventQueue$4.run(EventQueue.java:720)
at java.awt.EventQueue$4.run(EventQueue.java:718)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:77)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:717)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)
它表现得就像我手动移动框架一样。在调整帧大小时,Unity可能正在做某事。
答案 0 :(得分:3)
试试以下SSCCE:
这不是SSCCE(关闭但不完全)。没有main()方法,也没有导入。我们应该能够毫不犹豫地复制/粘贴/编译/测试。
键入一些字符以使窗口扩展
在Windows 7上使用JDK8对我很好。
//mainFrame.setSize(mainFrame.getContentPane().getPreferredSize());
mainFrame.pack();
我会使用上面的代码。您将获得更好的框架大小,因为pack()
将考虑框架装饰,而不像setSize()方法。
如果pack()
无法解决问题,那么我想建议首先保存帧的位置,然后调用setLocation(...)
方法,或使用setBounds(...)
来完全控制尺寸/位置。
编辑:
最后,当移动Frame时我没有得到......
尝试这样的事情:
((AbstractDocument)field.getDocument()).setDocumentFilter(new DocumentFilter()
{
@Override
public void replace(DocumentFilter.FilterBypass fb, int offset, int length, String text, AttributeSet attrs) throws BadLocationException
{
Point location = mainframe.getLocation();
super.replace(fb, offset, length, text, attrs);
mainFrame.pack();
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
mainframe.setLocation( location );
}
});
}
});