哪种布局可以做到这一点?

我正在尝试在我的应用程序中布局一些JLabel,如下例所示:

在此处输入图像描述

我总是把这个JLabel放在中间,其他JLabel的数量是可变的,它可以从1到30.我通过选择大量的列/行并在白色空间中设置一些空的JLabel来尝试网格布局但是我无法获得良好的结果,并且无法找到如何使用MigLayout ,任何人都有一个良好的布局解决方案或任何其他解决方案。

PS :我不想展示圆圈,只是为了表明JLabel排成一个圆圈。

您不需要专门支持此function的布局管理器。 您可以使用一些相当简单的三角函数计算x,y位置,然后使用常规布局,例如SpringLayout

 import java.awt.Point; import java.util.ArrayList; import java.util.List; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.SpringLayout; public class CircleLayout { /** * Calculate x,y positions of n labels positioned in * a circle around a central point. Assumes AWT coordinate * system where origin (0,0) is top left. * @param args */ public static void main(String[] args) { int n = 6; //Number of labels int radius = 100; Point centre = new Point(200,200); double angle = Math.toRadians(360/n); List points = new ArrayList(); points.add(centre); //Add points for (int i=0; i points) { JFrame frame = new JFrame("Labels in a circle"); frame.setSize(500, 500); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JPanel panel = new JPanel();; SpringLayout layout = new SpringLayout(); int count = 0; for (Point point : points) { JLabel label = new JLabel("Point " + count); panel.add(label); count++; layout.putConstraint(SpringLayout.WEST, label, point.x, SpringLayout.WEST, panel); layout.putConstraint(SpringLayout.NORTH, label, point.y, SpringLayout.NORTH, panel); } panel.setLayout(layout); frame.add(panel); frame.setVisible(true); } } 

数学截图

我怀疑你的要求是如此专业,以至于没有可以满足你需要的LayoutManager。 尝试创建自己的!

JH实验室有一个ClockLayout :

这是一个非常愚蠢的布局,为特殊目的而创建。 它只是将组件放在一个圆圈中,从顶部顺时针方向。

我喜欢@ Baqueta和@ sacha的想法:

 import java.awt.*; import java.awt.event.*; import javax.swing.*; public class CircleLayoutTest { public JComponent makeUI() { JPanel panel = new JPanel() { @Override protected void paintComponent(Graphics g) { super.paintComponent(g); Insets i = getInsets(); g.translate(i.left, i.top); g.setColor(Color.RED); int w = getWidth() - i.left - i.right; int h = getHeight() - i.top - i.bottom; g.drawOval(0, 0, w, h); g.translate(-i.left, -i.top); } }; panel.setLayout(new FlowLayout() { @Override public void layoutContainer(Container target) { synchronized(target.getTreeLock()) { int nmembers = target.getComponentCount(); if(nmembers<=0) return; Insets i = target.getInsets(); double cx = .5 * target.getWidth(); double cy = .5 * target.getHeight(); Component m = target.getComponent(0); Dimension d = m.getPreferredSize(); m.setSize(d.width, d.height); m.setLocation((int)(cx+.5-.5*d.width),(int)(cy+.5-.5*d.height)); if(nmembers-1<=0) return; double rw = .5 * (target.getWidth() - i.left - i.right); double rh = .5 * (target.getHeight() - i.top - i.bottom); double x = 0, y = 0, r = 0; double radian = 2.0 * Math.PI / (nmembers-1); for(int j=1; j 

我使用的是Windows表单,因为我没有安装Java工具,但想法是一样的,你只需要想象你是在添加JLabel而不是Buttons而且这是一个JFrame或JWindow而不是.NET表单。

代码应该是这样的,如果我们假设一个800 x 800像素区域来布局东西

 public partial class Form1 : Form { public Form1() { InitializeComponent(); this.Load += new EventHandler(Form1_Load); } void Form1_Load(object sender, EventArgs e) { int numberItems = 18; int centreX = 400; int centreY = 400; double offset = Math.PI; double step = Math.PI * 2 / numberItems; Button b = null; for (int i = 0; i < numberItems; i++) { b = new Button(); b.Width = 30; b.Height = 30; SetPosition(b, 370, offset, i, step); this.Controls.Add(b); } b = new Button(); b.Width = 30; b.Height = 30; b.Location = new Point(centreX, centreY); this.Controls.Add(b); } private void SetPosition(Button button, int legLength, double offset, double posOffSet, double step) { int x = (int)(legLength + Math.Sin(offset + posOffSet * step) * legLength); int y = (int)(legLength + Math.Cos(offset + posOffSet * step) * legLength); button.Location = new Point(x, y); } } 
  1. MigLayout可以使用“pos xy [x2] [y2]”作为组件约束进行绝对定位。 MigLayout确实是布局管理器来统治它们。 查看首页上的webstart演示,它可以很好地展示绝对定位。 您仍然需要计算组件的位置,例如自定义布局管理器的想法。

  2. 你也可以关掉布局 。

  3. 如果你想要真正有创意,你可以看看JHotDraw 。