当某些组件调整大小时,BoxLayout中的组件会移动

时间:2012-11-19 03:16:29

标签: java swing resize layout-manager boxlayout

public class LabelResizing2 {

    public static JPanel createSliderPanel(
            int min, int max, int curr)
    {       
        /*outer panel*/
        final JPanel panel = new JPanel();
        panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS)); 
        panel.setBorder(BorderFactory.createRaisedBevelBorder());       

        final JLabel valueLabel = new JLabel();
        valueLabel.setBorder(BorderFactory.createLineBorder(Color.BLACK)); 

        /*set up slider*/
        final JSlider slider = new JSlider(JSlider.VERTICAL, min, max, curr);
        slider.setBorder(BorderFactory.createLineBorder(Color.BLACK)); 

        panel.add(valueLabel); 
        panel.add(slider);

        /*slider move event*/
        slider.addChangeListener(new ChangeListener() {

            public void stateChanged(ChangeEvent event) {

                valueLabel.setText(Integer.toString(slider.getValue()));
            }


        });

        valueLabel.setText(Integer.toString(curr));
        return panel; 
    }

    public static void main(String[] args) {
        JFrame gui = new JFrame("Label Resizing");
        gui.setMinimumSize(new Dimension(500, 500));
        gui.add(createSliderPanel(-100, 100, 0)); 
        gui.setVisible(true); 

    }

}

这里的问题是滑块会在整个地方移动,因为标签从'99'调整为'100',从'0'调整为'-1'等。

几个问题:

  1. 为什么它在弹跳?
  2. 如果我放入

    valueLabel.setSize(100, 100); 它什么都没做。为什么呢?

    valueLabel.setMinimumSize(100,100); 会阻止它弹跳,但实际上并没有调整标签的大小。为什么呢?

  3. 我发现的最佳解决方案是slider.setAlignmentX(Component.LEFT_ALIGNMENT); 这是一个很好的解决方案吗?但是,这不适用于CENTER_ALIGNMENT或{{1这是怎么回事?

  4. 如果我们稍微修改它并将valueLabel放在面板中。

  5. RIGHT_ALIGNMENT

    即使labelPanel未调整大小(valueLabel正在其中调整大小),滑块仍会四处移动。这里发生了什么?布局管理器是否也在查看嵌套组件?

1 个答案:

答案 0 :(得分:1)

  

1为什么它在弹跳?

这就是这个特定布局管理器的本质。随着组件preferredSize的更改,布局管理器正在更新布局。

  

2如果我放入

     

valueLabel.setSize(100,100);它什么都没做。为什么呢?
    valueLabel.setMinimumSize(100,100);会阻止它弹跳,但实际上并没有调整标签的大小。为什么呢?

在布局管理器的控制下更改组件的大小没有任何效果,因为布局管理器会在重新布局组件时重新调整组件的大小。

preferred/minimum/maximumSize是布局管理员用来确定如何最好地执行各自布局的“建议”,他们没有义务以任何方式使用它们。

  

3我找到的最佳解决方案是去slide.setAlignmentX(Component.LEFT_ALIGNMENT);.这是好事   溶液

我想是的,但“请注意,这些只是提示,可能会被某些布局管理器忽略”

  

4如果我们稍微修改它并将valueLabel放在面板中。

现在,不是组件直接由布局管理器实现,每个面板都会影响它的父布局管理器,净结果,一些问题

更新了示例

在这种情况下,你可以作弊......

public class BadLayout03 {

    public static void main(String[] args) {
        new BadLayout03();
    }

    public BadLayout03() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestLayout());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestLayout extends JPanel {

        public TestLayout() {
            setLayout(new GridBagLayout());

            final JLabel valueLabel = new JLabel("000");
            final JSlider slider = new JSlider();

            slider.addChangeListener(new ChangeListener() {
                @Override
                public void stateChanged(ChangeEvent e) {
                    StringBuilder sb = new StringBuilder(Integer.toString(slider.getValue()));
                    while (sb.length() < 3) {
                        sb.insert(0, "0");
                    }
                    valueLabel.setText(sb.toString());
                }
            });

            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridx = 0;
            gbc.gridy = 0;
            gbc.weightx = 0.75;
            gbc.anchor = GridBagConstraints.WEST;
            valueLabel.setBorder(BorderFactory.createLineBorder(Color.BLACK));
            add(valueLabel, gbc);
            gbc.gridx = 1;
            gbc.weightx = 1;
            gbc.fill = GridBagConstraints.HORIZONTAL;
            add(slider, gbc);
        }
    }
}