您的位置:首页 > 其它

“同心圆”布局管理器

2008-11-20 21:46 246 查看
第一次尝试自己写布局管理器,实用价值不大,核心代码和测试代码如下:

ConcentricCirclesPanel.java

import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.LayoutManager;
import java.awt.LayoutManager2;
import java.awt.RenderingHints;
import javax.swing.JPanel;

public class ConcentricCirclesPanel extends JPanel {

private static final long serialVersionUID = 6265955429442551839L;

protected void paintComponent(Graphics g) {
super.paintComponent(g);
LayoutManager layout = getLayout();
if (!(layout instanceof ConcentricCirclesLayout)) return;
ConcentricCirclesLayout ccl = (ConcentricCirclesLayout)layout;
int fcr = ccl.getFirstCircleRadius();
int ri = ccl.getRadiusIncrement();
int cn = ccl.getCircleNum();
Insets insets = getInsets();
int cx = insets.left + (getWidth() - insets.left - insets.right) / 2;
int cy = insets.top + (getHeight() - insets.top - insets.bottom) / 2;
((Graphics2D) g).setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON
);
for (int r = fcr, ENDR = fcr + ri * (cn - 1); r <= ENDR; r += ri) {
g.drawOval(cx - r, cy - r, r * 2, r * 2);
}
}

public static class ConcentricCirclesLayout implements LayoutManager2 {

private int firstCircleRadius;
private int radiusIncrement;
private int circleNum;
private double angleDegrees;
private Component[] comps;

public ConcentricCirclesLayout() {
this(20, 20, 3, 0.0);
}

public ConcentricCirclesLayout(int firstCircleRadius, int radiusIncrement, int circleNum, double angleDegrees) {
super();
if (firstCircleRadius < 0) throw new IllegalArgumentException("firstCircleRadius < 0");
if (radiusIncrement < 1) throw new IllegalArgumentException("radiusIncrement < 0");
if (circleNum < 1) throw new IllegalArgumentException("circleNum < 0");
this.firstCircleRadius = firstCircleRadius;
this.radiusIncrement = radiusIncrement;
this.circleNum = circleNum;
this.angleDegrees = angleDegrees;
this.comps = new Component[this.circleNum];
}

public int getFirstCircleRadius() {
return this.firstCircleRadius;
}

public void setFirstCircleRadius(int firstCircleRadius) {
if (firstCircleRadius < 0) throw new IllegalArgumentException("firstCircleRadius < 0");
this.firstCircleRadius = firstCircleRadius;
}

public int getRadiusIncrement() {
return this.radiusIncrement;
}

public void setRadiusIncrement(int radiusIncrement) {
if (radiusIncrement < 1) throw new IllegalArgumentException("radiusIncrement < 0");
this.radiusIncrement = radiusIncrement;
}

public int getCircleNum() {
return this.circleNum;
}

public double getAngleDegrees() {
return this.angleDegrees;
}

public void setAngleDegrees(double angleDegrees) {
this.angleDegrees = angleDegrees;
}

public void addLayoutComponent(Component comp, Object constraints) {
synchronized (comp.getTreeLock()) {
if (constraints == null) constraints = Integer.valueOf(0);
if (!(constraints instanceof Integer)) {
throw new IllegalArgumentException("cannot add to layout: constraint must be a Integer (or null)");
}
int num = ((Integer)constraints).intValue();
if (num < 0 || num >= this.circleNum) {
throw new IndexOutOfBoundsException("component index out of bounds");
}
this.comps[num] = comp;
}
}

@Deprecated
public void addLayoutComponent(String name, Component comp) {
synchronized (comp.getTreeLock()) {
if (name == null) name = "0";
int num = 0;
try {
num = Integer.parseInt(name);
} catch (NumberFormatException e) {
throw new IllegalArgumentException("cannot add to layout: unknown constraint: " + name);
}
addLayoutComponent(comp, Integer.valueOf(num));
}
}

public void removeLayoutComponent(Component comp) {
synchronized (comp.getTreeLock()) {
for (int i = this.comps.length - 1; i >= 0; i--) {
if (comp == this.comps[i]) {
this.comps[i] = null;
break;
}
}
}
}

public float getLayoutAlignmentX(Container target) {
return 0.5F;
}

public float getLayoutAlignmentY(Container target) {
return 0.5F;
}

public void invalidateLayout(Container target) {
}

public Dimension preferredLayoutSize(Container parent) {
Insets insets = parent.getInsets();
int diameter = (this.firstCircleRadius + this.radiusIncrement * (this.circleNum - 1)) * 2;
int width = insets.left + insets.right + diameter;
int height = insets.top + insets.bottom + diameter;
return new Dimension(width, height);
}

public Dimension minimumLayoutSize(Container parent) {
return new Dimension(0, 0);
}

public Dimension maximumLayoutSize(Container target) {
return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
}

public void layoutContainer(Container parent) {
synchronized (parent.getTreeLock()) {
final double a = Math.toRadians(this.angleDegrees);
Insets insets = parent.getInsets();
int cx = insets.left + (parent.getWidth() - insets.left - insets.right) / 2;
int cy = insets.top + (parent.getHeight() - insets.top - insets.bottom) / 2;
Component[] cs = this.comps;
for (int i = 0, LEN = cs.length; i < LEN; i++) {
Component c = null;
if ((c = cs[i]) == null) continue;
Dimension d = c.getPreferredSize();
int radius = this.firstCircleRadius + this.radiusIncrement * i;
int dx = (int) (cx + radius * Math.cos(a) + 0.5);
int dy = (int) (cy - radius * Math.sin(a) + 0.5);
c.setBounds(dx - d.width / 2, dy - d.height / 2, d.width, d.height);
}
}
}

}

}

CCTestFrame.java
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import javax.swing.JButton;
import javax.swing.JFrame;

public class CCTestFrame extends JFrame implements Runnable {

private static final long serialVersionUID = -1488776778002491586L;
private final ConcentricCirclesPanel.ConcentricCirclesLayout layout;
private final ConcentricCirclesPanel ccPanel;
private final JButton[] buttons;

public CCTestFrame() {
super("CCTestFrame");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(60, 60, 800, 600);
final int N = 5;
this.ccPanel = new ConcentricCirclesPanel();
this.layout = new ConcentricCirclesPanel.ConcentricCirclesLayout(39, 50, N, 156.0);
this.buttons = new JButton
;
this.ccPanel.setBackground(Color.BLACK);
this.ccPanel.setForeground(Color.GREEN);
this.ccPanel.setLayout(this.layout);
for (int i = 0; i < N; i++) {
JButton btn = new JButton(Integer.toString(i));
btn.setPreferredSize(new Dimension(45, 23));
this.buttons[i] = btn;
this.ccPanel.add(btn, Integer.valueOf(i));
}
getContentPane().add(this.ccPanel, BorderLayout.CENTER);
Thread thread = new Thread(this);
thread.setDaemon(true);
thread.start();
}

public void run() {
Color[] cs = new Color[120];
for (int i = cs.length - 1; i >= 0; i--) {
cs[i] = new Color(Color.HSBtoRGB(i / 120.0F, 0.86F, 1.0F));
}
int c = 0;
double a = 360.0;
try {
while (true) {
for (int i = this.buttons.length - 1; i >= 0; i--) {
this.buttons[i].setBackground(cs[c]);
}
c++;
c %= 120;
this.layout.setAngleDegrees(a);
this.ccPanel.doLayout();
a -= 1.6;
a %= 360.0;
Thread.sleep(30L);
}
} catch (InterruptedException e) {
//e.printStackTrace();
}
}

public static void main(String[] args) {
new CCTestFrame().setVisible(true);
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: