环形布局管理器 + 环形弹出菜单(学习swing的一些小成果)

最近闲来无事, 学习学习swing。
在查看JPopMenu的代码时候突发奇想, 想实现一个环形的弹出菜单,说干就干。

我们都知道, swing 组件的位置和大小是由于layout 管理的,所以想实现环形的弹出菜单就必须实现一个环形的布局管理器。请看我的实现

效果
环形布局管理器 + 环形弹出菜单(学习swing的一些小成果)


package info.mikewang.gui.layout;

import static java.lang.Math.PI;
import static java.lang.Math.round;
import static java.lang.Math.sin;
import static java.lang.Math.cos;

import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.LayoutManager;
import java.awt.Point;
import java.awt.Rectangle;

public class CircleLayout implements LayoutManager {

	int maxCompWidth = 0; // 最大组件宽度
	int maxCompHeight = 0; // 最大组件高度

	int lc = 0; // 组件数(边的个数,即多边形边的个数)

	double v = 1.5D; // 缩放因子
	double cd = 0; // 组件和组件之间的距离(中心点到中心点)

	int l; // 外截正方形边长/2

	int lw = 0; // 调整过的边长
	int lh = 0;

	@Override
	public void addLayoutComponent(String name, Component comp) {

	}

	@Override
	public void layoutContainer(Container parent) {

		synchronized (parent.getTreeLock()) {

			Dimension d = parent.getPreferredSize();

			Point cp = new Point(d.width / 2, d.height / 2);

			double dx = 0, dy = 0;
			int cpx = 0, cpy = 0;
			for (int i = 0; i < lc; i++) {

     // 下面两行的代码要是看不懂的话,就去翻翻初中2年纪的几何书吧

				dx = sin(i * (2 * PI / lc)) * l;
				dy = -cos(i * (2 * PI / lc)) * l;

				cpx = (int) (cp.x + dx);
				cpy = (int) (cp.y + dy);
				Point cpp = new Point(cpx, cpy);
				Component comp = parent.getComponent(i);
				Dimension compSize = comp.getPreferredSize();

				comp.setBounds(calcR(cpp, compSize));
			}
		}
	}

	@Override
	public Dimension minimumLayoutSize(Container parent) {
		lc = parent.getComponentCount();

		Component[] components = parent.getComponents();
		for (Component component : components) {
			Dimension d = component.getPreferredSize();
			if (d.width > this.maxCompWidth) {
				this.maxCompWidth = d.width;
			}
			if (d.height > this.maxCompHeight) {
				this.maxCompHeight = d.height;
			}
		}

		calc();

		return new Dimension(lw, lh);
	}

	@Override
	public Dimension preferredLayoutSize(Container parent) {
		return minimumLayoutSize(parent);
	}

	@Override
	public void removeLayoutComponent(Component comp) {

	}

	private void calc() {
		cd = maxCompWidth * v;

		// 根据正多边形的一条边长,计算出这个多边形外切圆形的外切矩形的边长(近似值)
		// 使用正弦定理,
		double x = cd / sin(2 * PI / lc);
		l = (int) round(x);

		lh = 2 * l + maxCompHeight;
		lw = 2 * l + maxCompWidth;
	}

	private Rectangle calcR(Point p, Dimension d) {
		int y = p.y - d.height / 2;
		int x = p.x - d.width / 2;
		return new Rectangle(new Point(x, y), d);
	}
}



环形 弹出菜单实现


package info.mikewang.gui.layout;


import javax.swing.JPopupMenu;

public class CirclePopupMenu extends JPopupMenu {

	private static final long serialVersionUID = 7318307166817760768L;

	public CirclePopupMenu() {
		this.setLayout(new CircleLayout());
	}
}



有个问题, 顺便在这里问一下:

如何才能把弹出窗口的背景设置成透明呀??

你可能感兴趣的:(java,C++,c,swing,C#)