“同心圆”布局管理器

第一次尝试自己写布局管理器,实用价值不大,核心代码和测试代码如下:

ConcentricCirclesPanel.java

  1. import java.awt.Component;
  2. import java.awt.Container;
  3. import java.awt.Dimension;
  4. import java.awt.Graphics;
  5. import java.awt.Graphics2D;
  6. import java.awt.Insets;
  7. import java.awt.LayoutManager;
  8. import java.awt.LayoutManager2;
  9. import java.awt.RenderingHints;
  10. import javax.swing.JPanel;


  11. public class ConcentricCirclesPanel extends JPanel {

  12.     private static final long serialVersionUID = 6265955429442551839L;

  13.     protected void paintComponent(Graphics g) {
  14.         super.paintComponent(g);
  15.         LayoutManager layout = getLayout();
  16.         if (!(layout instanceof ConcentricCirclesLayout)) return;
  17.         ConcentricCirclesLayout ccl = (ConcentricCirclesLayout)layout;
  18.         int fcr = ccl.getFirstCircleRadius();
  19.         int ri = ccl.getRadiusIncrement();
  20.         int cn = ccl.getCircleNum();
  21.         Insets insets = getInsets();
  22.         int cx = insets.left + (getWidth() - insets.left - insets.right) / 2;
  23.         int cy = insets.top + (getHeight() - insets.top - insets.bottom) / 2;
  24.         ((Graphics2D) g).setRenderingHint(
  25.             RenderingHints.KEY_ANTIALIASING,
  26.             RenderingHints.VALUE_ANTIALIAS_ON
  27.         );
  28.         for (int r = fcr, ENDR = fcr + ri * (cn - 1); r <= ENDR; r += ri) {
  29.             g.drawOval(cx - r, cy - r, r * 2, r * 2);
  30.         }
  31.     }


  32.     public static class ConcentricCirclesLayout implements LayoutManager2 {

  33.         private int firstCircleRadius;
  34.         private int radiusIncrement;
  35.         private int circleNum;
  36.         private double angleDegrees;
  37.         private Component[] comps;

  38.         public ConcentricCirclesLayout() {
  39.             this(202030.0);
  40.         }

  41.         public ConcentricCirclesLayout(int firstCircleRadius, int radiusIncrement, int circleNum, double angleDegrees) {
  42.             super();
  43.             if (firstCircleRadius < 0throw new IllegalArgumentException("firstCircleRadius < 0");
  44.             if (radiusIncrement < 1throw new IllegalArgumentException("radiusIncrement < 0");
  45.             if (circleNum < 1throw new IllegalArgumentException("circleNum < 0");
  46.             this.firstCircleRadius = firstCircleRadius;
  47.             this.radiusIncrement = radiusIncrement;
  48.             this.circleNum = circleNum;
  49.             this.angleDegrees = angleDegrees;
  50.             this.comps = new Component[this.circleNum];
  51.         }

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

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

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

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

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

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

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

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

  88.         @Deprecated
  89.         public void addLayoutComponent(String name, Component comp) {
  90.             synchronized (comp.getTreeLock()) {
  91.                 if (name == null) name = "0";
  92.                 int num = 0;
  93.                 try {
  94.                     num = Integer.parseInt(name);
  95.                 } catch (NumberFormatException e) {
  96.                     throw new IllegalArgumentException("cannot add to layout: unknown constraint: " + name);
  97.                 }
  98.                 addLayoutComponent(comp, Integer.valueOf(num));
  99.             }
  100.         }

  101.         public void removeLayoutComponent(Component comp) {
  102.             synchronized (comp.getTreeLock()) {
  103.                 for (int i = this.comps.length - 1; i >= 0; i--) {
  104.                     if (comp == this.comps[i]) {
  105.                         this.comps[i] = null;
  106.                         break;
  107.                     }
  108.                 }
  109.             }
  110.         }

  111.         public float getLayoutAlignmentX(Container target) {
  112.             return 0.5F;
  113.         }

  114.         public float getLayoutAlignmentY(Container target) {
  115.             return 0.5F;
  116.         }

  117.         public void invalidateLayout(Container target) {
  118.         }

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

  126.         public Dimension minimumLayoutSize(Container parent) {
  127.             return new Dimension(00);
  128.         }

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

  132.         public void layoutContainer(Container parent) {
  133.             synchronized (parent.getTreeLock()) {
  134.                 final double a = Math.toRadians(this.angleDegrees);
  135.                 Insets insets = parent.getInsets();
  136.                 int cx = insets.left + (parent.getWidth() - insets.left - insets.right) / 2;
  137.                 int cy = insets.top + (parent.getHeight() - insets.top - insets.bottom) / 2;
  138.                 Component[] cs = this.comps;
  139.                 for (int i = 0, LEN = cs.length; i < LEN; i++) {
  140.                     Component c = null;
  141.                     if ((c = cs[i]) == nullcontinue;
  142.                     Dimension d = c.getPreferredSize();
  143.                     int radius = this.firstCircleRadius + this.radiusIncrement * i;
  144.                     int dx = (int) (cx + radius * Math.cos(a) + 0.5);
  145.                     int dy = (int) (cy - radius * Math.sin(a) + 0.5);
  146.                     c.setBounds(dx - d.width / 2, dy - d.height / 2, d.width, d.height);
  147.                 }
  148.             }
  149.         }

  150.     }

  151. }


CCTestFrame.java
  1. import java.awt.BorderLayout;
  2. import java.awt.Color;
  3. import java.awt.Dimension;
  4. import javax.swing.JButton;
  5. import javax.swing.JFrame;


  6. public class CCTestFrame extends JFrame implements Runnable {

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

  11.     public CCTestFrame() {
  12.         super("CCTestFrame");
  13.         setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  14.         setBounds(6060800600);
  15.         final int N = 5;
  16.         this.ccPanel = new ConcentricCirclesPanel();
  17.         this.layout = new ConcentricCirclesPanel.ConcentricCirclesLayout(3950, N, 156.0);
  18.         this.buttons = new JButton[N];
  19.         this.ccPanel.setBackground(Color.BLACK);
  20.         this.ccPanel.setForeground(Color.GREEN);
  21.         this.ccPanel.setLayout(this.layout);
  22.         for (int i = 0; i < N; i++) {
  23.             JButton btn = new JButton(Integer.toString(i));
  24.             btn.setPreferredSize(new Dimension(4523));
  25.             this.buttons[i] = btn;
  26.             this.ccPanel.add(btn, Integer.valueOf(i));
  27.         }
  28.         getContentPane().add(this.ccPanel, BorderLayout.CENTER);
  29.         Thread thread = new Thread(this);
  30.         thread.setDaemon(true);
  31.         thread.start();
  32.     }

  33.     public void run() {
  34.         Color[] cs = new Color[120];
  35.         for (int i = cs.length - 1; i >= 0; i--) {
  36.             cs[i] = new Color(Color.HSBtoRGB(i / 120.0F, 0.86F, 1.0F));
  37.         }
  38.         int c = 0;
  39.         double a = 360.0;
  40.         try {
  41.             while (true) {
  42.                 for (int i = this.buttons.length - 1; i >= 0; i--) {
  43.                     this.buttons[i].setBackground(cs[c]);
  44.                 }
  45.                 c++;
  46.                 c %= 120;
  47.                 this.layout.setAngleDegrees(a);
  48.                 this.ccPanel.doLayout();
  49.                 a -= 1.6;
  50.                 a %= 360.0;
  51.                 Thread.sleep(30L);
  52.             }
  53.         } catch (InterruptedException e) {
  54.             //e.printStackTrace();
  55.         }
  56.     }

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

  60. }


  • 2
    点赞
  • 0
    收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页
评论 2

打赏作者

sagezk

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值