studio reales proyectos programacion libro introducción incluye herramientas fundamentos fuente español código con avanzado aplicaciones java swing layout grid-layout miglayout

java - reales - libro de android studio en español pdf



¿Qué diseño puede hacer esto? (6)

Estoy tratando de diseñar algunos JLabels en mi aplicación como se muestra en este ejemplo:

Siempre tengo este JLabel en el medio y el número de los otros JLabels es variable, puede ir del 1 al 30. He intentado el diseño de cuadrícula eligiendo un buen número de columnas / filas y estableciendo JLabels vacías en el espacio en blanco, pero no se puede obtener un buen resultado, y no se puede encontrar cómo hacerlo con MigLayout , ¿alguien tiene una buena solución de diseño o cualquier otra solución?

PD : No quiero mostrar el círculo, solo para mostrar que los JLabels están dispuestos en un círculo.


  1. MigLayout puede hacer posicionamiento absoluto con "pos xy [x2] [y2]" como una restricción de componente. MigLayout realmente es el administrador de diseño para gobernarlos a todos. Echa un vistazo a la demostración webstart en su página principal, muestra bien el posicionamiento absoluto. Todavía tendría que calcular las posiciones de los componentes, como con la idea del administrador de diseño personalizado.

  2. También puedes desactivar el diseño .

  3. Y si quieres ser realmente creativo, puedes mirar JHotDraw .


Estoy usando formularios de Windows, ya que no tengo instaladas las herramientas de Java, pero la idea es la misma, solo tendrá que imaginarse que está agregando JLabel en lugar de Botones y que este es un JFrame o JWindow en lugar de un .NET Formulario.

El código debería ser algo como esto, si asumimos un área de 800 x 800 píxeles para diseñar cosas en

public partial class Form1 : Form { public Form1() { InitializeComponent(); this.Load += new EventHandler(Form1_Load); } void Form1_Load(object sender, EventArgs e) { int numberItems = 18; int centreX = 400; int centreY = 400; double offset = Math.PI; double step = Math.PI * 2 / numberItems; Button b = null; for (int i = 0; i < numberItems; i++) { b = new Button(); b.Width = 30; b.Height = 30; SetPosition(b, 370, offset, i, step); this.Controls.Add(b); } b = new Button(); b.Width = 30; b.Height = 30; b.Location = new Point(centreX, centreY); this.Controls.Add(b); } private void SetPosition(Button button, int legLength, double offset, double posOffSet, double step) { int x = (int)(legLength + Math.Sin(offset + posOffSet * step) * legLength); int y = (int)(legLength + Math.Cos(offset + posOffSet * step) * legLength); button.Location = new Point(x, y); } }


JH ClockLayout tiene un ClockLayout :

Este es un diseño muy tonto creado para un propósito especial. Simplemente establece sus componentes en un círculo, en el sentido de las agujas del reloj desde la parte superior.


Me gusta la idea de @Baqueta y @sacha:

import java.awt.*; import java.awt.event.*; import javax.swing.*; public class CircleLayoutTest { public JComponent makeUI() { JPanel panel = new JPanel() { @Override protected void paintComponent(Graphics g) { super.paintComponent(g); Insets i = getInsets(); g.translate(i.left, i.top); g.setColor(Color.RED); int w = getWidth() - i.left - i.right; int h = getHeight() - i.top - i.bottom; g.drawOval(0, 0, w, h); g.translate(-i.left, -i.top); } }; panel.setLayout(new FlowLayout() { @Override public void layoutContainer(Container target) { synchronized(target.getTreeLock()) { int nmembers = target.getComponentCount(); if(nmembers<=0) return; Insets i = target.getInsets(); double cx = .5 * target.getWidth(); double cy = .5 * target.getHeight(); Component m = target.getComponent(0); Dimension d = m.getPreferredSize(); m.setSize(d.width, d.height); m.setLocation((int)(cx+.5-.5*d.width),(int)(cy+.5-.5*d.height)); if(nmembers-1<=0) return; double rw = .5 * (target.getWidth() - i.left - i.right); double rh = .5 * (target.getHeight() - i.top - i.bottom); double x = 0, y = 0, r = 0; double radian = 2.0 * Math.PI / (nmembers-1); for(int j=1; j<nmembers; j++) { m = target.getComponent(j); if(m.isVisible()) { d = m.getPreferredSize(); m.setSize(d.width, d.height); x = cx + rw * Math.cos(r) - .5 * d.width; y = cy + rh * Math.sin(r) - .5 * d.height; m.setLocation((int)(x+.5), (int)(y+.5)); r += radian; } } } } }); JPanel p = new JPanel(new BorderLayout()); p.add(initPanel(panel)); return p; } private static JComponent initPanel(JComponent p) { p.setBorder(BorderFactory.createEmptyBorder(50,50,50,50)); for(int i=0; i<6; i++) { p.add(new JLabel("No."+i)); } return p; } public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { @Override public void run() { createAndShowGUI(); } }); } public static void createAndShowGUI() { JFrame f = new JFrame(); f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); f.getContentPane().add(new CircleLayoutTest().makeUI()); f.setSize(320 ,320); f.setLocationRelativeTo(null); f.setVisible(true); } }


Sospecho que sus requisitos son tan especializados que no existe un LayoutManager que pueda hacer lo que necesita. ¡Intenta crear el tuyo!


No necesita un administrador de diseño que lo soporte específicamente. Puede calcular las posiciones x, y con una trigonometría bastante simple, y luego usar un diseño regular como SpringLayout .

import java.awt.Point; import java.util.ArrayList; import java.util.List; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.SpringLayout; public class CircleLayout { /** * Calculate x,y positions of n labels positioned in * a circle around a central point. Assumes AWT coordinate * system where origin (0,0) is top left. * @param args */ public static void main(String[] args) { int n = 6; //Number of labels int radius = 100; Point centre = new Point(200,200); double angle = Math.toRadians(360/n); List<Point> points = new ArrayList<Point>(); points.add(centre); //Add points for (int i=0; i<n; i++) { double theta = i*angle; int dx = (int)(radius * Math.sin(theta)); int dy = (int)(-radius * Math.cos(theta)); Point p = new Point(centre.x + dx, centre.y + dy); points.add(p); } draw(points); } private static void draw(List<Point> points) { JFrame frame = new JFrame("Labels in a circle"); frame.setSize(500, 500); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JPanel panel = new JPanel();; SpringLayout layout = new SpringLayout(); int count = 0; for (Point point : points) { JLabel label = new JLabel("Point " + count); panel.add(label); count++; layout.putConstraint(SpringLayout.WEST, label, point.x, SpringLayout.WEST, panel); layout.putConstraint(SpringLayout.NORTH, label, point.y, SpringLayout.NORTH, panel); } panel.setLayout(layout); frame.add(panel); frame.setVisible(true); } }