Java Swing:如何创建一个不会在西部组件上移动的东部拥抱组件

Java Swing:如何创建一个不会在西部组件上移动的东部拥抱组件,java,swing,docking,Java,Swing,Docking,我已经尝试了几种方法来正确渲染。我希望我的徽标区域在调整窗口大小时拥抱东部,但不要与西部组件重叠。下面的代码不支持east,我认为这是有意义的,因为logoArea框不知道它应该占用其余的水平空间 如果我将logoArea直接添加到“area”中,那么它将拥抱东部,但如果窗口收缩过大,它将与西部组件重叠。有什么想法吗 Box box = Box.createHorizontalBox(); box.add( main ); for( JComponent item : items ) //

我已经尝试了几种方法来正确渲染。我希望我的徽标区域在调整窗口大小时拥抱东部,但不要与西部组件重叠。下面的代码不支持east,我认为这是有意义的,因为logoArea框不知道它应该占用其余的水平空间

如果我将logoArea直接添加到“area”中,那么它将拥抱东部,但如果窗口收缩过大,它将与西部组件重叠。有什么想法吗

 Box box = Box.createHorizontalBox();
 box.add( main );
 for( JComponent item : items ) //western stuff
 {
    box.add( Box.createHorizontalStrut( 8 ) );
    box.add( item );
 }

 //eastern stuff
 Box logoArea= Box.createHorizontalBox();
 logoArea.add( new JLabel( LAF.Icon.png( "CompanyLogo" ) ), BorderLayout.EAST );

 box.add( Box.createHorizontalStrut( 8 ) );
 box.add( logoArea, BorderLayout.EAST );

 JPanel area = new JPanel( new BorderLayout() );
 area.setBorder( BorderFactory.createEmptyBorder( 2, 2, 2, 2 ) );
 area.add( box, BorderLayout.WEST );
 return area;  //dashboard is built
编辑


要回答@Nitin,我希望它向左移动,直到到达西部组件,然后停止移动并从右侧拆下。

我真的不知道任何标准布局会按照您的要求运行,但创建一个并不困难。检查这个小示例(十字形绘画显示内容和徽标边界):

publicstaticvoidmain(字符串[]args)
{
JFrame=newjframe();
LogoLayout=新LogoLayout();
frame.setLayout(布局);
frame.add(新的JLabel(“与文本长度具有相同首选大小的标签”)
{
受保护组件(图形g)
{
超级组分(g);
g、 setColor(Color.BLACK);
g、 抽绳(0,0,getWidth(),getHeight());
g、 抽绳(getWidth(),0,0,getHeight());
}
},布局。内容);
frame.add(新的JComponent()
{
受保护组件(图形g)
{
g、 setColor(Color.BLACK);
g、 抽绳(0,0,getWidth(),getHeight());
g、 抽绳(getWidth(),0,0,getHeight());
}
公共维度getPreferredSize()
{
返回新维度(100100);
}
},layout.LOGO);
框架尺寸(700500);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(空);
frame.setVisible(true);
}
公共静态类LogoLayout实现LayoutManager
{
公共字符串CONTENT=“CONTENT”;
公共字符串LOGO=“LOGO”;
私有映射约束=newhashmap();
public void addLayoutComponent(字符串名称,组件组成)
{
constraints.put(comp,name);
}
公共void removeLayoutComponent(组件组件组件)
{
约束。移除(comp);
}
公共无效布局容器(容器父级)
{
Insets bi=parent.getInsets();
int contentSize=0;
int logoSize=0;
int maxHeight=0;
对于(组件:parent.getComponents())
{
维度ps=component.getPreferredSize();
if(constraints.get(component).equals(CONTENT))
{
contentSize=Math.max(ps.width,contentSize);
}
else if(constraints.get(component).equals(LOGO))
{
logoSize=Math.max(ps.width,logoSize);
}
maxHeight=Math.max(ps.height,maxHeight);
}
int width=parent.getWidth()-bi.left-bi.right;
int height=parent.getHeight()-bi.top-bi.bottom;
对于(组件:parent.getComponents())
{
if(constraints.get(component).equals(CONTENT))
{
if(contentSize+logoSize<宽度)
{
组件设置边界(双左、双顶、宽度-标识尺寸、高度);
}
其他的
{
component.setBounds(bi.left、bi.top、contentSize、height);
}
}
else if(constraints.get(component).equals(LOGO))
{
if(contentSize+logoSize<宽度)
{
成分
.立根(双左+宽-标志尺寸、双顶、标志尺寸、高度);
}
其他的
{
int scaledLogoSize=宽度-内容大小;
如果(scaledLogoSize>0)
{
component.setBounds(bi.left+宽度-缩放logosize,bi.top,
标度标识(尺寸、高度);
}
}
}
}
}
公共维度preferredLayoutSize(容器父级)
{
Insets bi=parent.getInsets();
int contentSize=0;
int logoSize=0;
int maxHeight=0;
对于(组件:parent.getComponents())
{
维度ps=component.getPreferredSize();
if(constraints.get(component).equals(CONTENT))
{
contentSize=Math.max(ps.width,contentSize);
}
else if(constraints.get(component).equals(LOGO))
{
logoSize=Math.max(ps.width,logoSize);
}
maxHeight=Math.max(ps.height,maxHeight);
}
返回新维度(bi.left+contentSize+logoSize+bi.right,
双顶部+最大高度+双底部);
}
公共维度minimumLayoutSize(容器父级)
{
返回preferredLayoutSize(父级);
}
}
当窗口变大时,这就是您希望您的徽标发挥作用的方式吗


注意:通过这种方式,您还可以在需要添加(例如)其他特定组件位置、徽标和内容之间的间隙或其他任何内容时修改布局…

让容器使用BorderLayout,然后将组件放置在BorderLayout.LINE_END位置。当窗口收缩超过此值以容纳组件时,预期会出现什么行为?@Hovercraft:这种方法与我的第二种方法存在相同的行为,“如果我添加logoArea di
public static void main ( String[] args )
{
    JFrame frame = new JFrame ();

    LogoLayout layout = new LogoLayout ();
    frame.setLayout ( layout );

    frame.add ( new JLabel ( "Label with same preferred size as text length" )
    {
        protected void paintComponent ( Graphics g )
        {
            super.paintComponent ( g );

            g.setColor ( Color.BLACK );
            g.drawLine ( 0, 0, getWidth (), getHeight () );
            g.drawLine ( getWidth (), 0, 0, getHeight () );
        }
    }, layout.CONTENT );

    frame.add ( new JComponent ()
    {
        protected void paintComponent ( Graphics g )
        {
            g.setColor ( Color.BLACK );
            g.drawLine ( 0, 0, getWidth (), getHeight () );
            g.drawLine ( getWidth (), 0, 0, getHeight () );
        }

        public Dimension getPreferredSize ()
        {
            return new Dimension ( 100, 100 );
        }
    }, layout.LOGO );

    frame.setSize ( 700, 500 );
    frame.setDefaultCloseOperation ( JFrame.EXIT_ON_CLOSE );
    frame.pack ();
    frame.setLocationRelativeTo ( null );
    frame.setVisible ( true );
}

public static class LogoLayout implements LayoutManager
{
    public String CONTENT = "Content";
    public String LOGO = "Logo";

    private Map<Component, String> constraints = new HashMap<Component, String> ();

    public void addLayoutComponent ( String name, Component comp )
    {
        constraints.put ( comp, name );
    }

    public void removeLayoutComponent ( Component comp )
    {
        constraints.remove ( comp );
    }

    public void layoutContainer ( Container parent )
    {
        Insets bi = parent.getInsets ();
        int contentSize = 0;
        int logoSize = 0;
        int maxHeight = 0;
        for ( Component component : parent.getComponents () )
        {
            Dimension ps = component.getPreferredSize ();
            if ( constraints.get ( component ).equals ( CONTENT ) )
            {
                contentSize = Math.max ( ps.width, contentSize );
            }
            else if ( constraints.get ( component ).equals ( LOGO ) )
            {
                logoSize = Math.max ( ps.width, logoSize );
            }
            maxHeight = Math.max ( ps.height, maxHeight );
        }

        int width = parent.getWidth () - bi.left - bi.right;
        int height = parent.getHeight () - bi.top - bi.bottom;
        for ( Component component : parent.getComponents () )
        {
            if ( constraints.get ( component ).equals ( CONTENT ) )
            {
                if ( contentSize + logoSize < width )
                {
                    component.setBounds ( bi.left, bi.top, width - logoSize, height );
                }
                else
                {
                    component.setBounds ( bi.left, bi.top, contentSize, height );
                }
            }
            else if ( constraints.get ( component ).equals ( LOGO ) )
            {
                if ( contentSize + logoSize < width )
                {
                    component
                            .setBounds ( bi.left + width - logoSize, bi.top, logoSize, height );
                }
                else
                {
                    int scaledLogoSize = width - contentSize;
                    if ( scaledLogoSize > 0 )
                    {
                        component.setBounds ( bi.left + width - scaledLogoSize, bi.top,
                                scaledLogoSize, height );
                    }
                }
            }
        }
    }

    public Dimension preferredLayoutSize ( Container parent )
    {
        Insets bi = parent.getInsets ();
        int contentSize = 0;
        int logoSize = 0;
        int maxHeight = 0;
        for ( Component component : parent.getComponents () )
        {
            Dimension ps = component.getPreferredSize ();
            if ( constraints.get ( component ).equals ( CONTENT ) )
            {
                contentSize = Math.max ( ps.width, contentSize );
            }
            else if ( constraints.get ( component ).equals ( LOGO ) )
            {
                logoSize = Math.max ( ps.width, logoSize );
            }
            maxHeight = Math.max ( ps.height, maxHeight );
        }
        return new Dimension ( bi.left + contentSize + logoSize + bi.right,
                bi.top + maxHeight + bi.bottom );
    }

    public Dimension minimumLayoutSize ( Container parent )
    {
        return preferredLayoutSize ( parent );
    }
}