我在框架中添加了一个按钮,并用计时器控制其文本和/或最小大小。
我注意到,这个按钮有时会长,有时不会。
如果在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();
}
}
- 不要采用第一种方法:
null layout(AbsoluteLayout)
,即使有人威胁你生死攸关 -
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; } };
-
正如@mKobel在下面指出的,我忘记了解决这个问题:不要将大小设置为
JFrame
。它减少了布局管理器正确布局的机会。改为在JFrame.setVisible(true)
之前调用JFrame.pack()
。
查看本教程页面了解详细信息:
- 如何使用FlowLayout
- 解决常见布局问题