Java 如何在不使用NullLayout的情况下以循环方式在JPanel上定位对象?
所以我的问题是:我有一个扩展了Java 如何在不使用NullLayout的情况下以循环方式在JPanel上定位对象?,java,swing,layout,intellij-idea,jpanel,Java,Swing,Layout,Intellij Idea,Jpanel,所以我的问题是:我有一个扩展了JProgressBar的类,基本上它看起来像一个闪烁的圆圈(它也会根据分配给该指示器的任务量分成若干段,每次我将指示器切换到下一个任务时,我都需要使用setUI,这很糟糕,但现在就可以了)。我需要在JPanel上定位其中37个圆圈,以便它们形成自己的圆圈。现在我是这样做的: private void addToPane(JPanel pane){ pane.setLayout(null); Insets insets = pane.
JProgressBar
的类,基本上它看起来像一个闪烁的圆圈(它也会根据分配给该指示器的任务量分成若干段,每次我将指示器切换到下一个任务时,我都需要使用setUI
,这很糟糕,但现在就可以了)。我需要在JPanel
上定位其中37个圆圈,以便它们形成自己的圆圈。现在我是这样做的:
private void addToPane(JPanel pane){
pane.setLayout(null);
Insets insets = pane.getInsets();
int width = pane.getWidth();
int height = pane.getHeight();
Dimension size = new Dimension(30, 30);
//Dimension mid = new Dimension(width/2, height/2);
Dimension mid = new Dimension(200, 250);
int r = 210;
double revox, revoy, angle = -Math.PI/2;
double revangle = 2*Math.PI/37;
for(int i=1; i<38; i++){
FlashingIndicator templabel = new FlashingIndicator();
templabel.setPreferredSize(size);
templabel.setUI(new ProgressIndicator(flash, 0, false));
templabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
indicate.add(templabel);
revox = r*Math.cos(angle);
revoy = r*Math.sin(angle);
indicate.get(i - 1).setBounds(insets.left + mid.width + (int) revox, insets.top + mid.height + (int) revoy, size.width, size.height);
pane.add(indicate.get(i - 1));
angle-=revangle;
}
}
private void addToPane(JPanel窗格){
pane.setLayout(空);
Insets Insets=pane.getInsets();
int width=pane.getWidth();
int height=pane.getHeight();
尺寸尺寸=新尺寸(30,30);
//尺寸中间=新尺寸(宽度/2,高度/2);
尺寸中间=新尺寸(200250);
int r=210;
双转速,转速,角度=-Math.PI/2;
双旋转角度=2*Math.PI/37;
对于(int i=1;i重写自定义中的方法以渲染指示器;可以看到一个相关示例。您可以按图所示的方式缩放渲染,以填充组件;这将避免组件内部需要自定义布局管理器。重写getPreferredSize()
,如前所述,以便您的自定义进度指示器能够正确地与封闭布局配合使用
覆盖自定义中的方法以渲染指示器;下面是一个相关示例。您可以按图所示的方式缩放渲染,以填充组件;这将避免组件内部需要自定义布局管理器。覆盖getPreferredSize()
,如前所述,以便您的自定义进度指示器能够正确地与封闭布局配合使用
考虑对整个组件使用自定义绘制。我不认为在这种情况下使用空布局是不好的。我认为它通常是不好的,因为它通常被(1)不费事学习布局管理器及其用途的人使用,(2)没有意识到要完成布局管理器为您所做的所有事情所需的工作量。但您在这里并不是在做普通的UI布局。至于根据面板大小进行布局,我模糊地记得您可以将框架渲染到内存中,然后使用其大小。@arcy“但您在这里并没有做普通的UI布局。”如果“自定义绘制”失败,我会推荐一个自定义布局。毕竟,如果布局有任何逻辑(这显然是有逻辑的)在布局管理器中封装它是更好的。NULL布局从来都不是一个好主意。考虑在整个组件中使用自定义绘制。在这种情况下,我认为NULL布局是不好的。我认为它通常是坏的,因为它通常被某人(1)使用。不费吹灰之力学习布局管理器以及它们的用途,(2)没有意识到要完成布局管理器为您所做的所有事情所需的工作量。但您在这里并不是在做普通的UI布局。至于根据面板大小进行布局,我模糊地记得您可以将框架渲染到内存中,然后使用其大小。@arcy“但您在这里并没有做普通的UI布局。”如果“自定义绘制”失败,我会推荐一个自定义布局。毕竟,如果布局有任何逻辑(这显然是有逻辑的),最好将其封装在布局管理器中。空布局从来都不是一个好主意。另请参阅此相关文章,建议使用拨号图。感谢@mKorbel,最后将其与anwser(关于GetPreferedSize()的部分)结合使用,该部分仍在查看paintDeterminate()并且感觉到我最终需要为动画编写自定义L&F,而不是当前的解决方法。@graynk:这是一种折衷。我认为您可以在自定义ProgressBarUI
中利用一些现有的L&F默认值,如JTable
所示。如果使用自定义布局管理器,您必须重新发明一些进度管道。另请参阅这篇相关文章,建议使用一个拨号图
。谢谢@mKorbel,最后将其与anwser(关于GetPreferedSize()的部分)结合使用,该部分仍在查看paintDeterminate()并且感觉到我最终需要为动画编写自定义L&F,而不是当前的解决方法。@graynk:这是一种折衷。我认为您可以在自定义ProgressBarUI
中利用一些现有的L&F默认值,如JTable
所示。如果使用自定义布局管理器,您必须重新发明一些进度管道.