记住摆动的窗口位置

Avr*_*gon 9 java user-interface swing persistence

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

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

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

Ada*_*yga 8

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

恢复窗口位置后,不要忘记检查位置是否真的在显示的桌面区域.屏幕配置可以在应用程序运行之间改变(例如,当用户将笔记本电脑与桌面监视器断开连接时).

  • 你能解释一下如何检查位置是否在显示的桌面区域?关闭应用程序时,我存储了Frame.getLocation()中的值(如果在主监视器左侧的监视器上关闭了帧,则可能为负值).因此,简单地添加所有屏幕宽度并没有帮助. (2认同)

Gil*_*anc 6

有没有比写出每个窗口的位置/大小更好的选择Preferences

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

有没有方便的方法来存储列的顺序JTable

将列名称和位置写入首选项文件.

虽然此任务很常见,但此任务的实现取决于您希望从GUI保存的内容.

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

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

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

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


Dee*_*egC 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 );
        }
    }
}
Run Code Online (Sandbox Code Playgroud)