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