How to maintain the aspect ratio of the screen after being resized by the user?

3

I need to restrict a certain proportion of a JFrame so that the layout of what I want to display on it is not distorted, but I would not want to have to block resize with setRezisable() . The minimum aspect ratio for testing is 350x500 (7:10 ratio), but I would like to keep that ratio every time the screen changes size.

I've done an example to see how it looks:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;

import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class KeepAspectRatioTest extends JFrame {

    private static final long serialVersionUID = 1L;

    private static final int WIDTH = 350;
    private static final int HEIGHT = 500;

    public static void main(String[] args) {

        SwingUtilities.invokeLater(() -> {

            KeepAspectRatioTest screen = new KeepAspectRatioTest();
            screen.setVisible(true);
        });
    }

    public KeepAspectRatioTest() {

        initUI();
    }

    private void initUI() {

        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setPreferredSize(new Dimension(WIDTH, HEIGHT));
        setTitle("Keep Aspect Ratio");

        JPanel board = new JPanel();
        board.setBorder(BorderFactory.createMatteBorder(1, 1, 1, 1, Color.black));


        JPanel sidePanel = new JPanel();
        sidePanel.setBorder(BorderFactory.createMatteBorder(1, 1, 1, 1, Color.red));
        sidePanel.setLayout(new BoxLayout(sidePanel, BoxLayout.Y_AXIS));
        sidePanel.setPreferredSize(new Dimension(WIDTH/6, HEIGHT));

        add(board, BorderLayout.CENTER);
        add(sidePanel, BorderLayout.EAST);

        pack();
        setLocationRelativeTo(null);

    }
}

How do I keep the aspect ratio of the screen after resizing?

Q: I think I need to use a ComponentListener , I just do not know how to control it with this listener, especially since, by allowing resizing, it is also enabled to maximize the screen.

    
asked by anonymous 29.09.2017 / 13:06

1 answer

0

You can use componentResized of componentListener to perform the calculation according to ratio . Remember that the ratio is 10: 7 or approximately 1.42 to stay horizontal or 7:10 = 0.7 to stay vertical. Works for conteiners and painels . Ex:

public class AspectRatio {
    static final double RATIO = 0.7;
    public static void main(String[] args) {
        final JPanel innerPanel = new JPanel();
        innerPanel.setBackground(Color.BLUE);

        final JPanel container = new JPanel(new GridBagLayout());
        container.add(innerPanel);
        container.addComponentListener(new ComponentAdapter() {
            @Override
            public void componentResized(ComponentEvent e) {
                resizePreview(innerPanel, container);
            }
        });
        final JFrame frame = new JFrame("AspectRatio");
        frame.getContentPane().add(container);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(600, 800);
        frame.setVisible(true);
    }

    private static void resizePreview(JPanel innerPanel, JPanel container) {
        int width = container.getWidth();
        int height = container.getHeight();
        float currentAspectRatio = (float) width / height;

        if (currentAspectRatio > RATIO) {
                 width = (int) (height * RATIO);
        } else {
                 height = (int) (width / RATIO);
        }
        innerPanel.setPreferredSize(new Dimension(width, height));
        container.revalidate();
    }
}

If you want to keep the Jframe aspect itself, you need to override the paint() method of JFrame , but will work only if it is resized by the corners. Remember that it is not a good approximation, since the user should have total control over the resizing of the window, which should keep the aspect is the content inside it:

public class AspectRatio {
    static final double RATIO = 1.42;
    static JFrame frame;
    public static void main(String[] args) {
        final JPanel innerPanel = new JPanel();
        innerPanel.setBackground(Color.BLUE);

        final JPanel container = new JPanel(new GridBagLayout());
        container.add(innerPanel);

        frame = new JFrame("AspectRatio") {
            public void paint(Graphics g) {
                super.paint(g);
                resizePreview(frame);
            };
        };
        frame.getContentPane().add(container);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(300, 600);
        frame.setVisible(true);
    }

    private static void resizePreview(JFrame jFrame) {
        int width = jFrame.getWidth();
        int height = jFrame.getHeight();
        float currentAspectRatio = (float) width / height;

        if (currentAspectRatio > RATIO) {
            width = (int) (height * RATIO);
        } else {
            height = (int) (width / RATIO);
        }
        jFrame.setSize(new Dimension(width, height));
        jFrame.revalidate();
        jFrame.repaint();
    }
}

I hope I have helped!

    
29.09.2017 / 15:41