2

Hi Im using the setBounds method to open a window whith a certain size. But the size that I pass in the argument is the size of the window including the bars of the frame. How can I set the dimensions only for the content?

Pablo Ajo
  • 43
  • 1
  • 4

2 Answers2

2

Set the size of the content, then call pack() on the JFrame.

Edit: Because Guillaume Polet will not stop griefing me, here is a complete working example. Notice how you don't need to (mis)use inheritance at all, and it gets the job done in much fewer lines:

import java.awt.Dimension;
import javax.swing.JFrame;

public class Main  {

    public static void main(String... args) {
        JFrame frame = new JFrame("Test");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().setPreferredSize(new Dimension(500, 500));
        frame.pack();
        frame.setVisible(true);
    }
}
Kevin Workman
  • 41,537
  • 9
  • 68
  • 107
  • this would resize the `JFrame` to the size of the components inside. I don't think this answers the question – Blip May 11 '15 at 14:23
  • @Blip And I'm pretty sure that's exactly what the question is asking. Without more info, we're both just guessing. – Kevin Workman May 11 '15 at 14:24
  • Setting the size of the content and then calling `pack()` is the same as calling `pack()` only. Calling `pack()` forces the content pane to its preferred size, hence the call to set the size will be immediately overridden by the call to `pack()`. – Guillaume Polet May 11 '15 at 18:21
  • @GuillaumePolet That doesn't make any sense. The content pane **is** the content. Setting the size (min, max, and preferred) and then calling pack() on the JFrame will cause the JFrame to fit to its content, which is what the OP is asking. In fact, your answer is simply restating my answer, using an unnecessary override instead of simply setting it. – Kevin Workman May 11 '15 at 18:24
  • 1
    @KevinWorkman no, if you call setSize(12000,12000), and then call pack() on your JFrame, you will most likely observe that your content pane does not have bounds of 12000x12000 but the preferred size of the content pane instead. It makes a lot of sense. pack() adjust the frame to the preferred size of the content pane, not to its current size. – Guillaume Polet May 11 '15 at 20:38
  • @GuillaumePolet I'm talking about setting the size of the content pane, not the JFrame. – Kevin Workman May 11 '15 at 21:03
  • Have you tried `frame.getContentPane().setSize(12000, 12000); frame.pack();`? I can assure you that the `frame.getContentPane().setSize()` call will be useless. – Guillaume Polet May 12 '15 at 07:39
  • @GuillaumePolet Please see the code I've added to my answer that proves you wrong, and please leave me alone now. Your approach misuses inheritance, yet you won't stop incorrectly criticizing my approach, which I'm pretty sure you simply aren't understanding. Happy coding. – Kevin Workman May 12 '15 at 13:22
  • @KevinWorkman You don't prove me wrong, you used another method which is called `setPreferredSize()` and not `setSize()`(setting the preferred size is a very different thing from setting the size). I understand very well your approach and [I have provided a good link explaining why such approach should not be taken](http://stackoverflow.com/a/7229519/928711). Answers provided in that link have received over 150 up-votes, so it's not just me that disencourages the use of such method. Happy coding too :-) – Guillaume Polet May 12 '15 at 15:48
  • @GuillaumePolet Sigh. I was keeping my answer as generic as possible- set the size on the content, then pack the frame. I wasn't specifically referring to only using the setSize() function. That's the part you aren't understanding. – Kevin Workman May 12 '15 at 15:56
  • Sorry, but when you say _Set the size of the content_, any developer understands call `setSize(w, h)` on the component. So your intention might be correct, but the wording wasn't, at least it wasn't obvious to me. Yet, I can only keep on repeating myself, you should avoid using `set(Prefered|Maximum|Minimum)Size()` methods as explained the link in my previous comment. – Guillaume Polet May 12 '15 at 16:28
  • @GuillaumePolet And I disagree with you. Goodbye. – Kevin Workman May 12 '15 at 16:41
1

There are 2 ways to fix this:

  • Take into account the border of the frame when setting the bounds of the frame
  • Override getPreferredSize() of the content pane of the JFrame and then call pack() on the frame.

Here is a demo of the two techniques:

import java.awt.Dimension;
import java.awt.Insets;
import java.awt.Rectangle;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class Test {

    protected void initUI() {
        JFrame frame = new JFrame("Insets technique");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
        Insets i = frame.getInsets();
        System.out.println(i);
        Rectangle bounds = new Rectangle(50, 100, 400, 500);
        bounds.width += i.right + i.left;
        bounds.height += i.bottom + i.top;
        frame.setBounds(bounds);
    }

    protected void initUI2() {
        JFrame frame = new JFrame("Preferred size technique");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setContentPane(new JPanel() {
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(400, 500);
            }
        });
        frame.pack();
        frame.setLocation(50, 100);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                Test test = new Test();
                test.initUI();
                test.initUI2();
            }
        });
    }
}
Guillaume Polet
  • 47,259
  • 4
  • 83
  • 117
  • How is overriding getPreferredSize() better than simply setting it? – Kevin Workman May 11 '15 at 18:24
  • 1
    @KevinWorkman Most of the time the result is identical. Yet, if some external were to call setPreferredSize as well, all your effort in making your component take a specific size would be lost. Check also [this question with multiple answer on the same topic](http://stackoverflow.com/a/7229519/928711) – Guillaume Polet May 11 '15 at 20:35
  • That doesn't make sense. Why don't you then extend JFrame and override getLocation() instead of calling setLocation()? Or override getTitle() instead of calling the constructor? – Kevin Workman May 11 '15 at 21:05