2012-01-13 17 views
5

Quiero colocar 10 JPanels en un círculo. Cada panel tiene el mismo tamaño y la longitud entre dos paneles debe ser la misma. Así que la forma más fácil que pensé es agarrar un nulo-Diseño y calcular el cuadro de límite con la mano a través de polarcoordiantes:posición Componentes en el círculo

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; 
} 

Pero eso no funciona! Algunos elementos están en el círculo, algunos de ellos son píxeles apagados ... tengo una bsolutly ni idea de por qué ?! Tampoco puedo encontrar un LayoutManager que pueda hacer eso por mí, ¿qué debo hacer?

+0

Considere crear y publicar un [SSCCE] (http://SSCCE.org) que muestre su intento y nos dé algún código para que lo probemos, modifiquemos y posiblemente lo corregiremos. –

Respuesta

5

Su código es bueno, pero te has perdido una pieza muy importante de información - las funciones trigonométricas esperan ángulos en radianes no grados.

Envuelva la evaluación de phi en Math.toRadians(double), y obtendrá el diseño que espera.

(En una nota lateral, he estado pensando acerca de cómo hacer algo como esto, gracias por el ejemplo)

+0

o phi * (pi/180) :) ahhhh eso, cometí este error en la mayoría de los lenguajes de programación escritos en: D – reox

6

Mientras que X-Cero estaba dando la respuesta correcta (1+ a su cargo), I creó un 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(); 
     } 
     }); 
    } 
} 

Por favor, acepte la respuesta de X-Zero ya que la suya fue la primera.

+1

encantador, me gusta! – reox

+2

'// TODO: envolver la lógica en un RadialLayout';) +1 –

+2

Véase también [' StarLayout'] (http://mindprod.com/jgloss/starlayout.html), ['CircleTest'] (http: // stackoverflow.com/a/2510048/230513). – trashgod

Cuestiones relacionadas