9

我有一个非常大的 Swing 应用程序,我想让它记住所有窗口、jframe 等的大小。因此,如果用户根据自己的喜好调整窗口大小,下次窗口看起来完全一样。

我是否有更好的选择来解决它,但在Preferences中手动写入每个窗口的位置/大小?有什么方便的方法来存储 JTable 中的列顺序吗?可能是一些框架?只是不想写样板。

不幸的是,整个大型应用程序的序列化不是一种选择。

4

5 回答 5

8

不,没有。不要忘记写主 JFrame 的边界(位置/大小)。

并且在恢复窗口位置后不要忘记检查该位置是否真的在显示的桌面区域中。屏幕配置可能会在应用程序运行之间发生变化(例如,当用户断开笔记本电脑与桌面显示器的连接时)。

于 2012-09-24T15:10:21.070 回答
6

有比将每个窗口的位置/大小写在中更好的选择Preferences吗?

不,没有。不要忘记写 main 的边界(位置/大小)JFrame。您可以将参数写入 XML 文件而不是首选项文件,但这是一个实现细节。

有什么方便的方法可以将列的顺序存储在 a 中JTable吗?

将列名和位置写入您的首选项文件。

虽然此任务很常见,但此任务的实现取决于您要从 GUI 中保存的内容。

我保存这些 GUI 参数的方法是创建一个模型类,其中包含您有兴趣保存的所有边界和其他参数。我会读取一个包含这些参数的 XML 文件并填充模型类中的字段。如果没有文件,我会设置默认值。

GUI 将使用模型类中的字段来构建 GUI。当用户修改 GUI 时,我将使用新值更新模型类。

当用户关闭 GUI 时,我会将模型类写入 XML 文件。

我更喜欢使用 XML 文件而不是属性文件,因为它更容易查看模型的结构,并且我发现当 GUI 更改时 XML 文件更容易修改。

于 2012-09-24T14:58:38.860 回答
5

这是一个开始。以下代码将找到最顶层的容器并将所有子组件的边界保存到首选项文件中,然后可以使用该首选项文件进行恢复。这可能无法处理所有情况,但它适用于我的应用程序。可以在此处跟踪未来的变化。

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 );
        }
    }
}
于 2014-08-24T18:59:03.480 回答
3

无论您想在下一次调用时记住什么(窗口位置等),都可以写入文件,并从启动时读取该文件。它需要被持久化到磁盘上,没有人知道你真正想要保存什么(可能不是时间敏感数据),并且任何“自动”解决方案都无法工作,除非它也保存时间敏感数据。

您希望您的应用程序恢复显示已删除的记录吗?可能不是。

于 2012-09-24T15:08:15.710 回答
3

我一直使用java.util.Preferences它,但是javax.jnlp.PersistenceService“即使对于在受限执行环境中运行的应用程序”也有效。

于 2012-09-24T18:40:15.307 回答