Is there an easy way of locking the aspect ratio of a GridLayout component in Java Swing ? Or should this be done on the JPanel containing that layout ?
Advertisement
Answer
GridLayout
effectively ignores a component’s preferred size, but you can control the aspect ratio of whatever is drawn in paintComponent()
, as shown in this example. The rendered shape remains circular (1:1 aspect), while (nearly) filling the container in the narrowest dimension. Resize the frame to see the effect.
Addendum: For example, I added N * N
instances of CirclePanel
to a GridLayout
below.
import java.awt.*; import java.awt.event.*; import java.util.Random; import javax.swing.*; /** * @see https://stackoverflow.com/a/9858355/230513 * @see https://stackoverflow.com/a/3538279/230513 */ public class SwingPaint { private static final int N = 4; public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { @Override public void run() { JFrame frame = new JFrame(); frame.setLayout(new GridLayout(N, N)); for (int i = 0; i < N * N; i++) { frame.add(new CirclePanel()); } frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.pack(); frame.setVisible(true); } }); } private static class CirclePanel extends JPanel { private static final Random r = new Random(); public CirclePanel() { this.setPreferredSize(new Dimension(80, 80)); this.setForeground(new Color(r.nextInt())); this.addMouseListener(new MouseAdapter() { @Override public void mousePressed(MouseEvent e) { CirclePanel.this.update(); } }); } public void update() { this.setForeground(new Color(r.nextInt())); } @Override public void paintComponent(Graphics g) { super.paintComponent(g); Dimension size = this.getSize(); int d = Math.min(size.width, size.height) - 10; int x = (size.width - d) / 2; int y = (size.height - d) / 2; g.fillOval(x, y, d, d); g.setColor(Color.blue); g.drawOval(x, y, d, d); } } }