позиционирайте компонентите в кръг

Искам да позиционирам 10 JPanels в кръг. Всеки панел има еднакъв размер и дължината между два панела трябва да е еднаква. Така че най-лесният начин, който си помислих, е да вземете null-Layout и да изчислите ръчно ограничителната кутия чрез 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, който може да направи това вместо мен, така че какво да правя?


person reox    schedule 13.01.2012    source източник
comment
Помислете за създаване и публикуване на SSCCE, който показва вашия опит и ни дава някакъв код, който да тестваме, модифицираме и евентуално да коригираме.   -  person Hovercraft Full Of Eels    schedule 14.01.2012


Отговори (2)


Кодът ви е добър, но сте пропуснали една много важна информация - тригонометричните функции очакват ъгли в радиани не градуси.

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

(От друга страна, обмислях как да направя нещо подобно, благодаря за примера)

person Clockwork-Muse    schedule 13.01.2012
comment
или phi * (pi/180) :) ахххх това, направих тази грешка в повечето езици за програмиране, на които съм писал :D - person reox; 14.01.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, тъй като неговият беше първи.

person Hovercraft Full Of Eels    schedule 13.01.2012
comment
Вижте също StarLayout, CircleTest. - person trashgod; 14.01.2012