Reputation: 30107
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();
}
}
Upvotes: 1
Views: 1275
Reputation: 15418
null layout(AbsoluteLayout)
even if someone threaten you to life death.Second approach with FlowLayout
: It is a LayoutManager as you might already know. However, this layout manager respects preferred size of a component. So giving size hints by setting bounds:setBounds(x, y, width, height)
won't have effect. Use button.setPreferredSize(Dimension)
to have a quick result. But again you should actually extend the class and override the getPreferredSize(Dimension)
and other getXXXSize(Dimension)
method to adjust with the content size.
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;
}
};
As @mKobel has pointed out below, which i have forgotten to address: do not set size to JFrame
. It reduce the chance for layout managers to layout properly. Call JFrame.pack()
before JFrame.setVisible(true)
instead.
Have a look in this tutorial page for details:
Upvotes: 3