【问题标题】:Resizing a JFrame and maintain aspect ratio?调整 JFrame 的大小并保持纵横比?
【发布时间】:2013-11-08 20:41:49
【问题描述】:

我希望用户在保持相同纵横比的同时调整窗口大小(宽度>高度的矩形。换句话说,如果高度改变,我想强制宽度改变更大的量,反之亦然.最好,我希望在调整窗口大小时发生调整大小,而不是之后。下面的代码根本不适合我..每当我尝试调整窗口大小时,它只会恢复到原来的大小。甚至当我拖动调整大小时,它不会改变宽度和高度。任何帮助将不胜感激!

public void componentResized(ComponentEvent arg0)
{
    int setHeight = arg0.getComponent().getHeight();
    int setWidth = arg0.getComponent().getWidth();
    double newWidth = 0;
    double newHeight = 0;
    {
        if(setHeight != oldHeight)
        {
            heightChanged = true;
        }
        if(setWidth != oldWidth)
        {
            widthChanged = true;
        }
    }
    {
        if(widthChanged == true && heightChanged == false)
        {
            newWidth = setWidth;
            newHeight = setWidth*HEIGHT_RATIO;
        }
        else if(widthChanged == false && heightChanged == true)
        {
            newWidth = setHeight * WIDTH_RATIO;
            newHeight = setHeight;
        }
        else if(widthChanged == true && heightChanged == true)
        {
            newWidth = setWidth;
            newHeight = setWidth*HEIGHT_RATIO;
        }
    }

    int x1 = (int) newWidth;
    int y1 = (int) newHeight;
    System.out.println("W: " + x1 + " H: " + y1);
    Rectangle r = arg0.getComponent().getBounds();
    arg0.getComponent().setBounds(r.x, r.y, x1, y1);
    widthChanged = false;
    heightChanged = false;
    oldWidth = x1;
    oldHeight = y1;
}

【问题讨论】:

  • 组件可能在布局管理器的控制之下...
  • 如果你能提供一个SSCCE 来重现问题,找到解决方案会更容易。
  • 一个简单的解决方案可能是编写一个布局管理器,其唯一职责是根据提供的比率调整子组件的大小,以便子组件始终适合父容器但保持纵横比正确

标签: java swing resize


【解决方案1】:

使用 Java 实现这一点并不容易(AWT 限制)。

可能的解决方案:

  • 在用户停止调整大小后正确的窗口大小(惹恼了用户 pov)
  • 使用不带任何修饰的不可调整大小的 JWindow/JDialog,并以编程方式重新实现窗口大小调整。 Swing/AWT 可以使用光标形状等。我已经在一个商业项目中做到了这一点(所以没有来源:-))。唯一的问题是:平台/jdk 版本非常不稳定(尽管近年来 AWT/Swing 没有太大变化)。

在用户拖动/调整大小时操作窗口大小将无法正常工作

【讨论】:

    【解决方案2】:

    我想出了一种方法来将 JPanel 的纵横比保持为学校项目的正方形。它在不同的地方使用了一些不同的元素,所以我希望我能提供足够的信息来帮助您使用您想要的任何纵横比将该方法实施到您自己的项目中。我能够将其归结为两个 java 文件。不知道如何进一步压缩它

    第一个:AspectRatio.java

    import java.awt.Color;
    import javax.swing.JFrame;
    public class AspectRatio {
        public static void main(String[] args) {
            JFrame frame = new JFrame("Stay a square");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setBackground(Color.WHITE);
            frame.getContentPane().add(new SquarePanel());
            frame.pack();
            frame.setVisible(true);
        }
    }
    

    第二个很重要:SquarePanel.java

    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.event.ComponentEvent;
    import java.awt.event.ComponentListener;
    import javax.swing.JPanel;
    @SuppressWarnings("serial")
    public class SquarePanel extends JPanel {
        //Fields
        private JPanel square;
        private int panelHeight;
        private int panelWidth;
        //Constructor
        public SquarePanel() {
            square = new JPanel();
            square.setBackground(Color.BLACK);
            square.setPreferredSize(new Dimension(800,800));
            this.addComponentListener(new FrameSizeListener());
            this.add(square);
        }
        //resizing method
        public void resizeSquare() {
            panelHeight = super.getHeight();
            panelWidth = super.getWidth();
            if(panelHeight>(panelWidth)) {
                square.setPreferredSize(new Dimension(panelWidth,panelWidth));
            }
            else if (panelHeight<(panelWidth)) {
                square.setPreferredSize(new Dimension(panelHeight,panelHeight));
            }
        }
        //Window resizing listener
        private class FrameSizeListener implements ComponentListener{
            public void componentResized(ComponentEvent e) {
                resizeSquare();
                revalidate();
            }
            public void componentMoved(ComponentEvent e) {
            }
            public void componentShown(ComponentEvent e) {
            }
            public void componentHidden(ComponentEvent e) {
            }
        }
    }
    

    希望对您有所帮助。原样的代码只会在白色背景上创建一个黑色正方形,但正方形仍然是正方形并尽可能大。

    【讨论】:

      猜你喜欢
      • 2020-06-14
      • 1970-01-01
      • 2014-01-08
      • 2012-11-15
      • 2017-11-16
      • 2013-06-26
      • 2012-04-15
      相关资源
      最近更新 更多