Java 记住秋千中的窗口位置
我有一个相当大的swing应用程序,我想让它记住所有窗口、jframes等的大小。所以,如果用户按自己喜欢的方式调整窗口大小,下次窗口看起来完全一样 我是否有更好的解决方法,但手动写入每个窗口的位置/大小?有没有什么方便的方法可以在JTable中存储列的顺序?可能是某种框架?只是不想写样板 不幸的是,整个大型应用程序的序列化不是一个选项 是否有比在Java 记住秋千中的窗口位置,java,swing,user-interface,persistence,Java,Swing,User Interface,Persistence,我有一个相当大的swing应用程序,我想让它记住所有窗口、jframes等的大小。所以,如果用户按自己喜欢的方式调整窗口大小,下次窗口看起来完全一样 我是否有更好的解决方法,但手动写入每个窗口的位置/大小?有没有什么方便的方法可以在JTable中存储列的顺序?可能是某种框架?只是不想写样板 不幸的是,整个大型应用程序的序列化不是一个选项 是否有比在首选项中写入每个窗口的位置/大小更好的选项 不,没有。不要忘记写主JFrame的边界(位置/大小)。您可以将参数写入XML文件而不是首选项文件,但这是
首选项中写入每个窗口的位置/大小更好的选项
不,没有。不要忘记写主JFrame
的边界(位置/大小)。您可以将参数写入XML文件而不是首选项文件,但这是一个实现细节
在JTable
中存储列的顺序有什么方便的方法吗
将列名和位置写入首选项文件
虽然此任务很常见,但此任务的实现取决于要从GUI保存的内容
保存这些GUI参数的方法是创建一个模型类,该类包含您感兴趣保存的所有边界和其他参数。我将读取包含这些参数的XML文件,并填充模型类中的字段。如果没有文件,我会设置默认值
GUI将使用模型类中的字段来构建GUI。当用户修改GUI时,我会用新值更新模型类
当用户关闭GUI时,我会将模型类写入一个XML文件
与属性文件相比,我更喜欢使用XML文件,因为它更容易查看模型的结构,而且我发现当GUI更改时,XML文件更容易修改。无论您在下一次调用时想记住什么(窗口位置等),都要写入文件,然后从启动时读取该文件。它需要保存到磁盘,没有人知道您真正想要保存什么(可能不是时间敏感数据),任何“自动”解决方案都无法工作,除非它还保存时间敏感数据
是否希望应用程序还原时显示已删除的记录?可能不会
不,没有。别忘了写主框架的边界(位置/大小)
恢复窗口位置后,别忘了检查该位置是否真的在显示的桌面区域。在应用程序运行期间,屏幕配置可能会发生变化(例如,当用户断开笔记本电脑与桌面显示器的连接时)。我一直使用java.util.Preferences
,但“即使是在受限执行环境中运行的应用程序,也可以使用此选项。”这是一个开始。下面的代码将找到最顶层的容器,并将所有子组件的边界保存到一个首选项文件中,然后该文件可用于恢复。这可能无法处理所有情况,但它适用于我的应用程序。未来的变化可以改变
恐怕没有API支持这样的东西。因为也没有API从XML创建表。可能我错了,但这项任务似乎很常见,可能已经存在一些框架,或者没有样板文件就可以轻松完成。您能解释一下如何检查位置是否在显示的桌面区域吗?关闭应用程序时,我存储Frame.getLocation()中的值(如果在主监视器左侧的监视器上关闭该帧,则该值可能为负值)。因此,简单地添加所有屏幕宽度并没有帮助。
public class WindowBoundsRestorer
{
private final String filename;
private Properties properties;
public WindowBoundsRestorer( String filename )
{
this.filename = filename;
}
private void setBounds( String key, Component c )
{
key = key + c.getName();
String position = properties.getProperty( key );
if ( c.getName() != null && ! StringUtils.isBlank( position ) )
{
String[] nums = position.split( "," );
c.setBounds( Integer.parseInt( nums[0] ), Integer.parseInt( nums[1] ),
Integer.parseInt( nums[2] ), Integer.parseInt( nums[3] ) );
}
if ( c instanceof Container )
{
key = key + "/";
Container container = (Container) c;
for ( Component child : container.getComponents() )
setBounds( key, child );
}
}
/**
* Loads the properties from the .xml file and sets all named windows with a matching
* name.
*
* @param component Any component in the Swing app. The top-most container will be
* determined from this component.
*/
public void restore( Component component )
{
properties = new Properties();
InputStream is = null;
try
{
is = new FileInputStream( filename );
properties.loadFromXML( is );
}
catch ( IOException e )
{
e.printStackTrace();
return;
}
finally
{
IOUtils.closeQuietly( is );
}
Component top = component;
while ( top.getParent() != null )
top = top.getParent();
setBounds( "", top );
}
private void getBounds( String key, Component c )
{
key = key + c.getName();
String position = String.format( "%d,%d,%d,%d", c.getX(), c.getY(), c.getWidth(), c.getHeight() );
properties.setProperty( key, position );
if ( c instanceof Container )
{
key = key + "/";
Container container = (Container) c;
for ( Component child : container.getComponents() )
getBounds( key, child );
}
}
public void save( Component component )
{
Component top = component;
while ( top.getParent() != null )
top = top.getParent();
properties = new Properties();
getBounds( "", top );
OutputStream os = null;
try
{
os = new FileOutputStream( filename );
properties.storeToXML( os, "Browser" );
}
catch ( IOException e )
{
e.printStackTrace();
}
finally
{
IOUtils.closeQuietly( os );
}
}
}