1

I've been spending some time relearning java and a peculiar logic error hit me here.

import javax.swing.*;
import java.awt.*;

class Frame
{
    public static void main (String args[])
    {

        JFrame frame = new JFrame("Tester Frame");
        frame.setSize(400, 500);

        JButton btn1 = new JButton("FOO");
        btn1.setSize(150, 50);
        btn1.setLocation(45, 0);

        JButton btn2 = new JButton("BAR");
        btn2.setSize(150, 50);
        btn2.setLocation(205, 0);

        Container content = frame.getContentPane();
        content.setBackground(Color.blue);
        content.add(btn1);
        content.add(btn2);

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }//end main                                                                                                         
}

I've created 2 JButton objects, and they should be the same size, with different location and text. This of course is not the case, the "FOO" button is exactly where and how I want it to be, but the "BAR" button is the size of the entire frame.

Help!

Kylar
  • 8,876
  • 8
  • 41
  • 75
Dane B
  • 11
  • 1

4 Answers4

4

1) You are attempting to use Absolute LayoutManager via setSize and setLocation etc, but without calling setLayout(null) on the component you are adding the JButtons to. However this is not a best practice in Swing.

When adding to JFrame contentpane default layout is BorderLayout which adds components to is default position of BorderLayout.CENTER.

Have a read on A Visual Guide to Layout Managers

2) Also when using a correct LayoutManager you would omit JFrame#setSize(..) call and replace it with JFrame#pack() before setting the JFrame visible.

3) Also have a read on Concurrency in Swing specifically on The Event Dispatch Thread which dictates all swing components be created on EDT via SwingUtillities.invokeXXX(..) block:

SwingUtilities.invokeLater(new Runnable() {
   @Override
    public void run() {
         //create and manipulate swing components here
    }
});

4) Also rather use JFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); as this will allow any other threads timers etc to carry on execution even after JFrame has been disposed.

David Kroukamp
  • 36,155
  • 13
  • 81
  • 138
1

add:

frame.getContentPane().setLayout(null);

To your code after the line:

frame.setSize(400, 500);
Kylar
  • 8,876
  • 8
  • 41
  • 75
  • 1
    this is not the correct way a proper layout manager other than Absolute should be used – David Kroukamp Jul 30 '13 at 18:01
  • 1
    That depends on your desire. He was specifically trying to size and place the buttons himself. He wasn't asking a better way to lay them out, he was asking why they weren't being placed and sized correctly. I answered his question in the way that I thought he wanted. It's fine to suggest other alternatives - he'll pick what information he found useful. – Kylar Jul 30 '13 at 18:07
  • OP can *manually* size `JButton` if needed via `setXXXSize` or overriding `getXXXSize` when using `LayoutManager` which matches his needs – David Kroukamp Jul 30 '13 at 18:15
  • 1
    Actually, most LayoutManagers will ignore your setSize(). And when using a LM, you can't specify where you want things to be - you have to build them up. Again, I was trying to answer his question in the way that I thought he wanted. If you have a different opinion - great. That's what SO is about. He'll pick what information solves his problem. – Kylar Jul 30 '13 at 18:19
  • as you can see I did not specify `setSize` method.... `setXXXSize` or overriding `getXXXSize` i.e `setPreferredSize`, `setMamximumSize` and `getPreferredSize` etc. See [this Question and its answers](http://stackoverflow.com/questions/7229226/should-i-avoid-the-use-of-setpreferredmaximumminimumsize-methods-in-java-swi/12665828#12665828) specifically [this](http://stackoverflow.com/a/7229662/1133011) and [this answer](http://stackoverflow.com/a/12665828/1133011) – David Kroukamp Jul 30 '13 at 18:23
0

Components added to a container are tracked in a list. The order of the list will define the components' front-to-back stacking order within the container. If no index is specified when adding a component to a container, it will be added to the end of the list (and hence to the bottom of the stacking order).In your code the buttons are stacked over the other.That is why you get this Error(as you think it is). This will solve your problem:-

import javax.swing.*;

import java.awt.*;

class OP3
{
    public static void main (String args[])
    {

    JFrame frame = new JFrame("Tester Frame");
    frame.setSize(400, 500);

    JButton btn1 = new JButton("FOO");
    btn1.setSize(150, 50);
    btn1.setLocation(45, 0);

        JButton btn2 = new JButton("BAR");
    btn2.setSize(150, 50);
    btn2.setLocation(205, 0);

       JPanel p  = new JPanel(new FlowLayout());
       p.add(btn1);
       p.add(btn2);
       frame.add(p);


        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }//end main                                                                                                         
}
John Snow
  • 977
  • 7
  • 12
0

Just add a panel to the frame and add the buttons to the panel.

import javax.swing.*;

import java.awt.*;

class source
{
   public static void main (String args[])
   {

   JFrame frame = new JFrame("Tester Frame");
   frame.setSize(400, 500);

   JPanel panel=new JPanel();//panel added here
   panel.setSize(frame.size());
   panel.setLocation(0, 0);

   JButton btn1 = new JButton("FOO");
   btn1.setSize(150, 50);
   btn1.setLocation(45, 0);

   JButton btn2 = new JButton("BAR");
   btn2.setSize(150, 50);
   btn2.setLocation(205, 0);

   panel.add(btn1);
   panel.add(btn2);

   Container content = frame.getContentPane();
   content.setBackground(Color.blue);
   content.add(panel);

    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible(true);
}//endmain                                                                                                         
zindarod
  • 6,328
  • 3
  • 30
  • 58