Java 摆动时按宽度将组件安装在容器中

Java 摆动时按宽度将组件安装在容器中,java,swing,layout-manager,Java,Swing,Layout Manager,我在创建自己的swing组件时遇到问题。我想创建一个组件,该组件将渲染一些图像,并且它将按比例适合当前窗口(或容器)的大小 问题是我无法知道容器中组件的实际可用空间(没有插入、边框,可能是其他东西…) 此示例显示了问题: public class Main { static class MyComponent extends JComponent { @Override public Dimension getPreferredSize()

我在创建自己的swing组件时遇到问题。我想创建一个组件,该组件将渲染一些图像,并且它将按比例适合当前窗口(或容器)的大小

问题是我无法知道容器中组件的实际可用空间(没有插入、边框,可能是其他东西…)

此示例显示了问题:

public class Main
{
    static class MyComponent extends JComponent
    {
        @Override
        public Dimension getPreferredSize()
        {
            if(isShowing())
            {
                int width = getParent().getSize().width - 4;
                Dimension dimension = new Dimension(width, (int)(width / 0.8));
                System.out.println(dimension);
                return dimension;
            }
            return super.getPreferredSize();
        }

        @Override
        protected void paintComponent(Graphics g)
        {
            super.paintComponent(g);

            g.setColor(Color.WHITE);
            g.fillRect(0, 0, getWidth(), getHeight());
            g.setColor(Color.RED);
            g.fillOval(0, 0, getWidth(), getHeight());
        }
    }

    public static void main(String... args)
    {
        JFrame frame = new JFrame("Test");
        JPanel panel = new JPanel(new GridBagLayout());
        panel.setBackground(Color.DARK_GRAY);
        GridBagConstraints c = new GridBagConstraints();
        c.insets = new Insets(2, 2, 2, 2);
        c.gridx = c.gridy = 0;
        panel.add(new MyComponent(), c);
        c.gridy++;
        panel.add(new MyComponent(), c);
        frame.add(new JScrollPane(panel));
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.setSize(800, 600);
        frame.setVisible(true);
    }
}
如果从
getParent().getSize().width-4
表达式中删除4(插图中的左和右),然后启动,您将看到组件将无限增大其大小

在上面的代码中,我得到了容器的全宽,但我需要可用的宽度,这样组件就不会触发容器一次又一次地调整大小


或者是否有其他方法可以正常匹配组件?

这不是您希望保持比例的组件,而是图像,允许愤怒组件达到父级希望的大小,并将图像缩放到合适的范围内。您的组件应该只返回合适的大小提示请参见和examples@MadProgrammer如何做这些提示?正如我在JScrollPane中看到的,问题在于它试图通过宽度容纳组件。若我允许按父级调整组件的大小,则组件的大小将不包含源图像的比例,并且只渲染图像的一部分。不是很好的解决方案。。。但我通过获取布局管理器,并从宽度中减去插图(如果它是GridBagLayout)。将图像缩放到组件本身的比例范围内。如果组件位于
JScrollPane
中,那么再多的“黑客行为”也无济于事,因为容器本身将被设置为其首选大小