有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

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_ALIGNMENTRIGHT_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在其内部调整大小),滑块仍会四处移动。这是怎么回事?布局管理器是否也在查看嵌套组件


共 (1) 个答案

  1. # 1 楼答案

    1 Why is it bouncing around?

    这就是这个特殊布局管理器的本质。当组件的preferredSize发生更改时,布局管理器正在更新布局

    2 If I put in

    valueLabel.setSize(100, 100); it does absolutely nothing. Why?
    valueLabel.setMinimumSize(100,100); will stop it bouncing around, but doesn't actually resize the label. Why?

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

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

    3 Best solution I've found is to go slider.setAlignmentX(Component.LEFT_ALIGNMENT);. Is this a good solution?

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

    4 If we modify it a bit and put the valueLabel inside a panel.

    现在,组件不再直接受布局管理器的影响,每个面板都会影响它的父布局管理器、最终结果和一些问题

    用示例更新

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

    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);
            }
        }
    }