“同心圆”布局管理器

论坛 期权论坛 编程之家     
选择匿名的用户   2021-5-31 15:16   21   0
第一次尝试自己写布局管理器,实用价值不大,核心代码和测试代码如下:

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(20, 20, 3, 0.0);
  40. }

  41. public ConcentricCirclesLayout(int firstCircleRadius, int radiusIncrement, int circleNum, double angleDegrees) {
  42. super();
  43. if (firstCircleRadius < 0) throw new IllegalArgumentException("firstCircleRadius < 0");
  44. if (radiusIncrement < 1) throw new IllegalArgumentException("radiusIncrement < 0");
  45. if (circleNum < 1) throw 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 < 0) throw 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 < 1) throw 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(0, 0);
  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]) == null) continue;
  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(60, 60, 800, 600);
  15. final int N = 5;
  16. this.ccPanel = new ConcentricCirclesPanel();
  17. this.layout = new ConcentricCirclesPanel.ConcentricCirclesLayout(39, 50, 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(45, 23));
  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. }


分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:3875789
帖子:775174
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP