我正在使用 MigLayout 在网格中排列图像。我可以让宽度占据列中可用的整个空间,但是我希望高度相应地增长,这样图像的比例仍然是固定的。
最好的方法是什么?我可以使用约束中的表达式来做到这一点,还是必须覆盖 getPreferredSize()?
谢谢!
我正在使用 MigLayout 在网格中排列图像。我可以让宽度占据列中可用的整个空间,但是我希望高度相应地增长,这样图像的比例仍然是固定的。
最好的方法是什么?我可以使用约束中的表达式来做到这一点,还是必须覆盖 getPreferredSize()?
谢谢!
经过大量研究,我意识到使用 Swing 没有很好的方法来做到这一点。问题不仅来自 MigLayout,还来自诸如 ScrollPaneLayout 之类的布局,它假定在不同的有效宽度(不是首选宽度)之后首选高度将保持不变。
有两种选择:
1)目前,我正在使用纵横比组件约束进行自己的 MigLayout 实现。你可以在这里下载:
https://github.com/lqbweb/miglayout-aspect
到目前为止,它适用于在具有 1 个组件/单元的简单网格案例中缩小和增长 X。我仍然需要测试跨越,在单元格中流动和对接......我将保持更新该存储库,欢迎任何帮助。
由于您可能会将其用作 ViewPort 上的视图,因此如果您将它与返回 true 的 Scrollable.getScrollableTracksViewportWidth() 一起使用,您将不得不修改视图的 getPreferredSize,因此它不会返回真正的首选高度,而是与宽度匹配的那个。在我的代码中,网格有一个 getter,并且网格具有返回给定宽度的首选高度的功能。
2)保持 MigLayout 的当前实现不变(在此答案时为 4.2),我只找到了一种方法来实现这一点:通过向布局添加回调并使用类似这样的方法实现 getSize() 方法:
migLayout.addLayoutCallback(new LayoutCallback() {
/**
* This is run before the layout starts laying out
*/
@Override
public BoundSize[] getSize(ComponentWrapper comp) {
if(comp.getComponent() instanceof DCMImageWrapper) {
DCMImageWrapper img=(DCMImageWrapper) comp.getComponent(); //this is the BufferedImage embedded in a JLabel
int calculatedHeight=img.getHeightFor(comp.getWidth());
UnitValue maxHeight=new UnitValue(calculatedHeight);
BoundSize height=new BoundSize(maxHeight, maxHeight, maxHeight, null);
return new BoundSize[]{null, height};
} else {
return null;
}
}
private double getCurrentAspect(ComponentWrapper comp) {
if(comp.getWidth()==0 || comp.getHeight()==0) return 0;
double currentAspect=comp.getWidth()/(double)comp.getHeight();
return currentAspect;
}
/**
* Check if the aspect still valid
*/
@Override
public void correctBounds(ComponentWrapper comp) {
if(comp.getComponent() instanceof DCMImageWrapper) {
DCMImageWrapper img=(DCMImageWrapper) comp.getComponent();
double currentAspect=getCurrentAspect(comp);
double origAspect=img.getDCMImage().getAspect();
double currentError=Math.abs(origAspect-currentAspect);
if(currentError > img.getDCMImage().getAspectError()) {
//recalculate layout
revalidate();
}
}
}
});
然后,添加如下组件:
CC constraints=new CC();
constraints.shrinkX(100);
constraints.minWidth("1");
constraints.minHeight("1");
add(tmpImg, constraints);
但是,您必须添加并保持更新布局约束 (LC) 以手动设置布局的首选大小,因为在回调之后它会出现偏差。