Within my program, I am trying to create a toolbar within a frame. Within the toolbar, I have three buttons that are represented with a picture instead of text.
The problem is that I have found that there is a difference in how the buttons are displayed if I create the JButton objects within the constructor, compared to if I did this outside of the constructor (but still within the JFrame class).
My code when I create the buttons within the constructor :
public class Tool extends JFrame
{
public Tool()
{
JToolbar bar = new JToolBar();
JButton button1 = new JButton(img1);
JButton button2 = new JButton(img2);
JButton button3 = new JButton(img3);
bar.add(button1);
bar.add(button2);
bar.add(button3);
}
}
Then the buttons are added nicely and neatly to the toolbar.
However, if I do this:
public class Tool extends JFrame
{
JButton button1 = new JButton(img1);
JButton button2 = new JButton(img2);
JButton button3 = new JButton(img3);
public Tool()
{
JToolbar bar = new JToolBar();
bar.add(button1);
bar.add(button2);
bar.add(button3);
}
}
Then, the buttons are still added to the toolbar. BUT instead of being formatted nicely, they seem to have a border around them (similar to if you just copied an image off of google and paste it onto a powerpoint presentation, for example, and you get a square border around the image).
Why is this the case? Why does it matter where I create the JButton objects?
Thank you in advance.
Edit (complete CORRECT code): In the code below, button1 and button2 are created within the constructor, whereas button3 is created outside of the constructor. As you can see, there is a faint white border around the button with the text "Java", compared to the two other buttons.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Tool extends JFrame
{
JButton button3 = new JButton("Java");
public Tool()
{
super("Tool");
setLookAndFeel();
setSize(370, 200);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton button1 = new JButton("Help");
JButton button2 = new JButton("SOS");
//build toolbar
JToolBar bar = new JToolBar();
bar.add(button1);
bar.add(button2);
bar.add(button3);
// build text area
JTextArea edit = new JTextArea(8, 40);
JScrollPane scroll = new JScrollPane(edit);
// create frame
BorderLayout border = new BorderLayout();
setLayout(border);
add("North", bar);
add("Center", scroll);
setVisible(true);
}
private void setLookAndFeel()
{
try
{
UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
}
catch(Exception e)
{
}
}
public static void main(String[] arguments)
{
Tool loot = new Tool();
}
}
In the first case, you just have three local variables declared in the constructor.
In the second case, your Tool
class has three fields. You can then refer to those fields in other methods, and they are part of the state of the object.
That's a significant difference in itself, but shouldn't affect the behaviour in itself. However, it also affects the timing of when the JButton
instances are created - when they're fields, the initializer is being executed before you call setLookAndFeel
and before you call setSize
.
After experimenting a bit, it seems that it's the look and feel which is important here. I suggest you change your code to make setLookAndFeel
a static
method, and then call that from main
before you create any GUI components. You'll then get a consistent experience. (I would suggest only catching UnsupportedLookAndFeelException
and ReflectiveOperationException
, and at least logging any exception, instead of just continuing without any trace of what's wrong, too...)
See more on this question at Stackoverflow