JButton 如何控制它的大小?



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

我注意到,这个按钮有时会长,有时不会。

如果在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();
    }
}
  1. 不要采用第一种方法:null layout(AbsoluteLayout),即使有人威胁你生死攸关
  2. FlowLayout的第二种方法:正如您可能已经知道的那样,它是一个LayoutManager。但是,此布局管理器尊重组件的首选大小。因此,通过设置边界来提示大小: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. 如何使用FlowLayout
  2. 解决常见布局问题

相关内容

  • 没有找到相关文章

最新更新