记住摆动的窗口位置

时间:2012-09-24 13:25:11

标签: java swing user-interface persistence

我有一个非常大的摇摆应用程序,我想让它记住所有窗口,jframe等的大小。因此,如果用户调整窗口他喜欢的方式,下次窗口看起来完全相同。

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

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

5 个答案:

答案 0 :(得分:8)

  

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

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

答案 1 :(得分:6)

  

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

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

  

有没有方便的方法来存储JTable

中列的顺序

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

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

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

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

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

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

答案 2 :(得分:3)

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

您是否希望应用程序使用已删除的记录进行恢复?可能不是。

答案 3 :(得分:3)

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

答案 4 :(得分:3)

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

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