0
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但是,这对or不起作用RIGHT_ALIGNMENT,这是怎么回事?

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

final JPanel labelPanel = new JPanel(); 
final JLabel valueLabel = new JLabel();
valueLabel.setBorder(BorderFactory.createLineBorder(Color.BLACK));
labelPanel.add(valueLabel); 
labelPanel.setBorder(BorderFactory.createLineBorder(Color.RED));
panel.add(labelPanel); 
panel.add(slider); 

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

4

1 回答 1

1

1 为什么会反弹?

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

2 如果我输入

valueLabel.setSize(100, 100); 它完全没有任何作用。为什么?
valueLabel.setMinimumSize(100,100); 会阻止它弹跳,但实际上不会调整标签的大小。为什么?

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

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

3 我发现的最佳解决方案是使用 slider.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);
        }
    }
}
于 2012-11-19T03:25:03.687 回答