I have added a button to a frame and controlling it's text and/or minimum size with timer.
I noticed, that button does grow sometimes, and sometimes does not.
If in null
layout, then it ignores both text and minimum width changing.
If in FlowLayout
layout, then it grows if text changing, but ignores minimum width changing.
How make it grow in latter case? If minimum width changes, then why doesn't layout manager reshapes button? How to force it to reshape?
Note: code below is SSCCE, i.e. it is for investigation purposes.
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();
}
}
UPDATE
It does not work with preferred size too. Invalidation also does not help.
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();
}
}
UPDATE 2
The answer reuires 2 conditions:
1) use setPreferredSize()
as @Sage suggested, and
2) call revalidate()
(what I saw in setText()
source code).
The final working code follows:
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();
}
}