【问题标题】:How does JButton control it's size?JButton 如何控制它的大小?
【发布时间】:2013-12-02 20:09:31
【问题描述】:

我在框架中添加了一个按钮,并使用计时器控制它的文本和/或最小尺寸。

我注意到,那个按钮有时会变大,有时不会。

如果在null 布局中,那么它会忽略文本和最小宽度变化。

如果在FlowLayout 布局中,那么它会随着文本的变化而增长,但会忽略最小宽度的变化。

在后一种情况下如何让它成长?如果最小宽度发生变化,那么为什么布局管理器不重塑按钮?如何强制它重塑?

注意:下面的代码是 SSCCE,即用于调查目的。

public class Try_ButtonAutoresize_01 {

    private static final Logger log = LoggerFactory.getLogger(Try_ButtonAutoresize_01.class);

    private static final String text = "Very Long Text For Appear On Button ";
    private static int position = 7;

    public static void main(String[] args) {

        final JButton button = new JButton(text.substring(0, position));
        button.setBounds(10, 10, 100, 50);

        JFrame frame = new JFrame();
        //frame.setLayout(null);
        frame.setLayout(new FlowLayout(FlowLayout.LEFT));
        frame.add(button);

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocation(100,100);
        frame.setSize(640, 480);
        frame.setVisible(true);

        new Timer(1000, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {


                /*
                button.setText(button.getText() + text.charAt(position));

                position++;
                if( position >= text.length() ) {
                    position=0;
                }
                */


                button.setMinimumSize(new Dimension((int)button.getMinimumSize().getWidth()+10, (int)button.getMinimumSize().getHeight()));

                log.info("Minimum width is now = {}", button.getMinimumSize().getWidth());
            }
        }).start();

    }

}

更新

它也不适用于首选尺寸。失效也无济于事。

public class Try_ButtonAutoresize_01 {

    private static final Logger log = LoggerFactory.getLogger(Try_ButtonAutoresize_01.class);

    private static final String text = "Very Long Text For Appear On Button ";
    private static int position = 7;

    public static void main(String[] args) {

        final JButton button = new JButton(text.substring(0, position));
        button.setBounds(10, 10, 100, 50);

        final JFrame frame = new JFrame();
        //frame.setLayout(null);
        frame.setLayout(new FlowLayout(FlowLayout.LEFT));
        frame.add(button);

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocation(100,100);
        frame.setSize(640, 480);
        frame.setVisible(true);

        new Timer(1000, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {


                /*
                button.setText(button.getText() + text.charAt(position));

                position++;
                if( position >= text.length() ) {
                    position=0;
                }
                */


                //button.setMinimumSize(new Dimension((int)button.getMinimumSize().getWidth()+10, (int)button.getMinimumSize().getHeight()));
                button.setPreferredSize(new Dimension((int)button.getPreferredSize().getWidth()+10, (int)button.getPreferredSize().getHeight()));

                //frame.invalidate();
                //button.invalidate();

                log.info("Minimum width is now = {}", button.getMinimumSize().getWidth());
                log.info("Preferred width is now = {}", button.getPreferredSize().getWidth());
            }
        }).start();

    }

}

更新 2

答案需要两个条件:

1) 按照@Sage 的建议使用setPreferredSize(),并且

2) 调用revalidate()(我在setText() 源代码中看到的)。

最终的工作代码如下:

public class Try_ButtonAutoresize_02 {

    private static final Logger log = LoggerFactory.getLogger(Try_ButtonAutoresize_02.class);

    public static void main(String[] args) {

        final JButton button = new JButton("short");

        final JFrame frame = new JFrame();
        frame.setLayout(new FlowLayout(FlowLayout.LEFT));
        frame.add(button);

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocation(100,100);
        frame.setSize(640, 480);
        frame.setVisible(true);

        new Timer(1000, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {


                //button.setMinimumSize(new Dimension((int)button.getMinimumSize().getWidth()+10, (int)button.getMinimumSize().getHeight()));
                button.setPreferredSize(new Dimension((int)button.getPreferredSize().getWidth()+10, (int)button.getPreferredSize().getHeight()));

                button.revalidate();

                log.info("Preferred width is now = {}", button.getPreferredSize().getWidth());


            }
        }).start();

    }

}

【问题讨论】:

标签: java swing layout-manager preferredsize null-layout-manager


【解决方案1】:
  1. 不要采用第一种方法:null layout(AbsoluteLayout),即使有人威胁你要生死。
  2. FlowLayout 的第二种方法:您可能已经知道它是一个 LayoutManager。但是,此布局管理器尊重组件的首选大小。所以通过设置 bounds:setBounds(x, y, width, height) 来给出尺寸提示不会有效果。使用button.setPreferredSize(Dimension) 可以快速获得结果。但同样,您实际上应该扩展类并覆盖 getPreferredSize(Dimension) 和其他 getXXXSize(Dimension) 方法以调整内容大小。

     JButton button = new JButton("Press Me"){
        @Override
        public Dimension getPreferredSize() {
            Dimension size = new Dimension();
            size.width = ???; // give some thinking about it
            size.height = ???; // give some thinking about it
            return size;
        }
    
     };
    
  3. 正如@mKobel 在下面指出的,我忘记解决了:不要将大小设置为JFrame。它减少了布局管理器正确布局的机会。在JFrame.setVisible(true) 之前调用JFrame.pack()

查看本教程页面了解详情:

  1. How to use FlowLayout
  2. Solving Common Layout Problems

【讨论】:

  • @Suzan Cioc button.getMinimumSize() 可以在两种情况下返回其大小 1. 已经可见,2. JFrame.pack() 被调用,(3. 带有/基于坐标的 NullLayout 来自父母插图)
  • 它也不适用于首选尺寸。我看不到覆盖 getPreferredSize() 的原因,因为查询显示它已更新。
  • 我在您的更新中没有看到任何 setPreferredSize 代码。并从代码中删除 setBounds ,因为它不会有任何效果。删除JFrame.setSize(Dimension) 也正如mKobel 上面所建议的那样。谢谢
  • @Sage setPreferredSize 行是从底部算起的第 9 行。 setSize 存在就是因为它没有效果:不需要注释掉。
猜你喜欢
  • 2013-08-14
  • 1970-01-01
  • 2012-11-23
  • 1970-01-01
  • 1970-01-01
  • 2011-06-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多