我想佈局一些的JLabel在我的應用程序如本例所示:哪些佈局可以做到這一點?
我總是在中間此JLabel和其他人的JLabel的數量是可變它可以從1走30。我已經選擇好的數列/行,並在空格設置一些空的JLabel嘗試網格佈局,但我不能得到一個好的結果,並不能找到如何與MigLayout做到這一點,沒有任何一個具有良好的佈局結構或任何其他解決方案。
PS:我不想顯示圓圈,它只是表明JLabels是在一個圓圈中排列的。
我想佈局一些的JLabel在我的應用程序如本例所示:哪些佈局可以做到這一點?
我總是在中間此JLabel和其他人的JLabel的數量是可變它可以從1走30。我已經選擇好的數列/行,並在空格設置一些空的JLabel嘗試網格佈局,但我不能得到一個好的結果,並不能找到如何與MigLayout做到這一點,沒有任何一個具有良好的佈局結構或任何其他解決方案。
PS:我不想顯示圓圈,它只是表明JLabels是在一個圓圈中排列的。
我懷疑你的要求是如此專業,有沒有佈局管理,可以做你所需要的。 Try creating your own!
我想你已經釘這一個。 +1 – 2012-04-20 09:37:42
...然後來@Peter證明我錯了!:) – vaughandroid 2012-04-20 09:44:54
**在開始創建自定義佈局管理器之前,請確保沒有現有的佈局管理器符合您的要求。** - >所以通過結合您的答案和@Peter的一個我可以得到它,+1 – 2012-04-20 10:23:37
JH實驗室有ClockLayout:
這是一個特殊目的創造了一個非常愚蠢的佈局。它只是從頂部順時針將其組件放置在一個圓圈內。
偉大的佈局,但這裏沒有中心元素,所以我必須實現我的自定義clocklayout。 +1 – 2012-04-20 10:21:17
我使用的是Windows窗體,因爲我沒有安裝Java工具,但想法是一樣的,您將不得不想象您將添加JLabel而不是按鈕,並且這是一個JFrame或JWindow而不是.NET Form。
代碼應該是這樣的,如果我們假設800×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);
}
}
謝謝,但我想要一個佈局解決方案,因爲它不建議使用絕對定位。 – 2012-04-20 10:19:53
噢,好吧,你不可以創建自己的佈局管理器,根據面板的實際寬度計算出點數?只是一個因素類型的東西 – sacha 2012-04-20 10:36:58
我喜歡@東東Baqueta的和@薩沙的想法:
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<nmembers; j++) {
m = target.getComponent(j);
if(m.isVisible()) {
d = m.getPreferredSize();
m.setSize(d.width, d.height);
x = cx + rw * Math.cos(r) - .5 * d.width;
y = cy + rh * Math.sin(r) - .5 * d.height;
m.setLocation((int)(x+.5), (int)(y+.5));
r += radian;
}
}
}
}
});
JPanel p = new JPanel(new BorderLayout());
p.add(initPanel(panel));
return p;
}
private static JComponent initPanel(JComponent p) {
p.setBorder(BorderFactory.createEmptyBorder(50,50,50,50));
for(int i=0; i<6; i++) {
p.add(new JLabel("No."+i));
}
return p;
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override public void run() {
createAndShowGUI();
}
});
}
public static void createAndShowGUI() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.getContentPane().add(new CircleLayoutTest().makeUI());
f.setSize(320 ,320);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
,我喜歡你的大多數代碼+1,只有你的代碼在所有方向上都可以被重新分配,非常感謝你 – mKorbel 2012-04-20 17:18:17
我喜歡它順利調整大小的事實。 +1 – 2012-04-20 17:33:46
你不不需要一個專門支持這個的佈局管理器。可以計算出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<Point> points = new ArrayList<Point>();
points.add(centre);
//Add points
for (int i=0; i<n; i++) {
double theta = i*angle;
int dx = (int)(radius * Math.sin(theta));
int dy = (int)(-radius * Math.cos(theta));
Point p = new Point(centre.x + dx, centre.y + dy);
points.add(p);
}
draw(points);
}
private static void draw(List<Point> 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);
}
}
哇,這很有趣:-) – 2012-04-20 11:55:52
MigLayout可以做到絕對定位與 「POS X Y [X2] [Y2]」 作爲組分約束。 MigLayout真的是佈局經理來統治他們。看看他們的頭版Webstart的演示,它展示了良好的絕對定位。你仍然要計算像與自定義佈局管理理念組件的位置。
你也可以只turn off the layout。
如果你想獲得真正的創意,你可以看看JHotDraw。
好問題,並且非常描述性(小以字節爲單位)的圖像。 +1 – 2012-04-20 09:37:22
謝謝,我想在這裏後,連續30天,我開始有點適應:) – 2012-04-20 11:31:09