Компоненты положения в круге - PullRequest
5 голосов
/ 14 января 2012

Я хочу расположить 10 JPanels по кругу. Каждая панель имеет одинаковый размер, и длина между двумя панелями должна быть одинаковой. Поэтому я подумал, что проще всего взять нулевой макет и вычислить ограничивающий прямоугольник вручную через polarcoordiantes:

JPanel panel = new JPanel(null);

int r = 100;
int phi = 90;

for (int i = 0; i < 10; i++) {
    JPanel x = new JPanel();
    x.setBackground(Color.red);
    x.setBounds((int) (r * Math.sin(phi)) + 100, (int) (r * Math.cos(phi)) + 100, 4, 4);

    panel.add(x);
    phi = (phi + 36) % 360;
}

Но это не работает! Некоторые элементы находятся по кругу, некоторые из них не в пикселях ... Я понятия не имею, почему ?! Я также не могу найти LayoutManager, который может сделать это для меня, что делать?

Ответы [ 2 ]

6 голосов
/ 14 января 2012

Пока X-Zero давал правильный ответ (1+ на его пост), я создал SSCCE:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import javax.swing.*;

public class PanelsOnCircle extends JPanel {
   private static final int RADIUS = 100;
   private static final int GAP = 20;
   private static final int PREF_W = 2 * RADIUS + 2 * GAP;
   private static final int PREF_H = PREF_W;
   private static final int SLICES = 10;
   private static final int SIDE = 4;

   public PanelsOnCircle() {
      JPanel panel = new JPanel(null);

      for (int i = 0; i < SLICES; i++) {
         double phi = (i * Math.PI * 2) / SLICES; 
         JPanel smallPanel = new JPanel();
         smallPanel.setBackground(Color.red);
         int x = (int) (RADIUS * Math.sin(phi) + RADIUS - SIDE / 2) + GAP;
         int y = (int) (RADIUS * Math.cos(phi) + RADIUS - SIDE / 2) + GAP;
         smallPanel.setBounds(x, y, SIDE, SIDE);

         panel.add(smallPanel);
      }

      setLayout(new BorderLayout());
      add(panel);
   }

   @Override
   public Dimension getPreferredSize() {
      return new Dimension(PREF_W, PREF_H);
   }

   private static void createAndShowGui() {
      PanelsOnCircle mainPanel = new PanelsOnCircle();

      JFrame frame = new JFrame("PanelsOnCircle");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

Пожалуйста, примите ответ X-Zero, так как он был первым.

5 голосов
/ 14 января 2012

Ваш код хорош, но вы пропустили одну очень важную информацию - тригонометрические функции рассчитывают углы в радианах не градусах .

Оберните оценку phi в Math.toRadians(double), и вы получите макет, который ожидаете.

(Кстати, я думал о том, как сделать что-то подобноеспасибо за пример)

...