Question to pack() method - java

I'm building a GUI application, and within a JFrame i have 2 jcombobox's and a JPanel to view certain data. Now when i call the pack() methode in the main class it puts the two jcombobox'es next to my JPanel, which i dont want, because I want them North. Ofcourse I've tried to hard-code it in my code, but it doesn't work after I've called the pack() method.
Are there any alternatives to this method?

Only one component can be NORTH, so if you want both ComboBoxes to be NORTH you have to add them into a separate container. This separate container can then be put NORTH.
(Post the source for more exact help.)

All pack does is resize the Window (in this case JFrame) to its preferred size and the preferred sizes of its sub-components. To control the actual location of the sub-components relative to one another you need to use an appropriate LayoutManager.
You might want to check out the Using Layout Managers tutorial.

The pack() method just causes the layouting to happen, it has abolutely nothing to do with what is put where.
Most likely you're not using layout managers correctly. Show us your code and we can tell you waht exactly you're doing wrong.

You can avoid using pack by explicitly setting the frame size with setSize and setBounds. However, using pack is usually the preferred way as it leaves the frame layout manager in charge of the frame size.
That being said, the problem you are describing appears to be related to the correct use of a layout manager rather than the sizing of the frame. Have a look at the various layout managers for Swing and how to use them: http://download.oracle.com/docs/cd/E17409_01/javase/tutorial/uiswing/layout/using.html.

Related

Java revalidate(); moves Objects that have been re-positioned, back to the original location

I'm making an application in which JLabels are created and can be re-positioned using
.setLocation(x,y)
However, whenever I invoke
.setVisible(true)
the JLabels move back to their original position. I think it has something to do with
.setVisible()'s --- revalidate() function
But I am unsure of how to override or avoid revalidate() effects.
Thanks,
You don't override or change revalidate() -- rather you use the appropriate layout manager since all revalidate does is to tell the layout managers to layout the components held by this and all nested containers. One "solution" is to use a null layout, but I strongly advise against that as this will lead to hard to debug and maintain GUI's, ones that might look good on one platform and terrible on all others. Consider nesting JPanels, each using its own layout manager, and using Borders, such as an EmptyBorder, to achieve your desired GUI layout.
If your program (not the user) is setting the location of the components then don't do this. Instead use the appropriate layout manager, or combination of nested panels with different layout managers to achieve your layout.
Read the Swing tutorial on Layout Managers for more information and working examples.
JLabels are created and can be re-positioned using setLocation(x,y)
However, if you are creating an application that allows the users to drag components around the screen then you need to use a null layout so you can control the location (and the size) of each component.
However, I would recommend you take at look at Drag Layout. This is a layout manager that implements most of the layout manager functionality, but will allow you to control the location of the component.
However, whenever I invoke setVisible(true)
Also, Swing components are visible by default so there is no need to invoke that method, except on top level containers (JFrame, JDialog etc).

Method called when layouting is done?

I'm looking for a method that I could override or some listener that is fired when a JPanel is being layouted. Checked the javadoc but couldn't find one. The situation is this:
I have a component that takes care about its contents via a Null-Layout.
The component itself is however layouted inside another JPanel (with a layout manager) and receives a certain size when layouting is done.
Now I want to use this size to calculate widths and heights of the contents of that Null-Layout JPanel.
But of course I need to know when I have to recalculate sizes. Any ideas or a good alternative approach? The required calculating in the Null-Layout is actually very simple and using a layout manager would probably require more work than the current solution - I just need to find that method or listener.
Answering myself so this can be closed.
doLayout will be called when layouting is needed, so that's the method one can override when doing layouts without a layout manager.

Auto resize swing elements to fit to the container's size

Not sure if what I need is possible.
I have a container (JPanel) that contains some internal elements.
I was wondering if it is possible to force internal elements to fit into the container's size.
I need them to be fully visible i.e., resize to fit inside the Panel's size and not cut some parts of the internal elements.
Scrolling is not an option.
Is this possible by using a Layout or something?
EDIT: Important clarification:
The thing is that I do not have access to the internal elements neither to their properties so I would say that a Layoutmanager capable of resizing child elements to fit to its size is needed. I tested BorderLayout and GridBagLayout but the result is always the same, the internal elements are cut out.
It's for exactly that reason that LayoutManagers exist. All the LayoutManagers work for simple containers directly, excluding GridBagLayout which is to able to handle most complete GUIs directly.
For most complete GUI's you have some choices as follows:
Look for a 3rd party layout such as MigLayout or here
Use GridBagLayout
Very easy way is use nested layout, where there is more than one JPanel and each has child JPanels with the same or different LayoutManager
Or custom layout, should be hard..., but same as using GridBagLayout
You could set the JPanel layout to border layout, then add the single child to the center. If there are multiple children, this approach becomes less useful since components added to the the NORTH, SOUTH, EAST, and WEST will remain statically sized while the centre resizes to fill the remainder.
In short, this isn't an ideal solution. All layouting in Swing is made all the more complex by the fact that different components behave in different ways, so you really need to provide further details of the child components you wish to add to your panel, and any behaviour that has been overridden on those components.
The best way is to try a couple of simple examples to see what mileage you get and whether subtle redesign of your child component nesting could help.
you can use a layout, like GridBagLayout, or BorderLayout depending on the situation. With proper weights it is possible.
this sounds to me like you should just peek an appropriate layout manager and use it. For example, look at BorderLayout - put your component in the CENTER and it will occupy all the area. Its up to each concrete layout manager to decide what will be the size of the components.
Mark
I was using a JInternalFrame inside JDesktopPane. I wanted the internal_frame to auto resize as desktop pane is resized, so I had to implement the AncestorResized event for the internal frame where I placed the following code:
this.setPreferredSize(this.getParent().getPreferredSize());
this.pack();

Can I get the right JComponent size before it's shown?

When is the size of the JComponent is calculated? After being shown in the screen or before that?
if I send .getSize() message before .setVisible(true), would it give me the right answer?
Thanks
I sometimes check the sizes of my components when debugging to find out why I can't see them for instance. In most cases, the sizes will be realized when the GUI has been rendered. This can occur when pack() or setVisible(true) has called on the top-level window. My usual sequence of method calls is to call pack() first as this tells the layout managers to lay out the components that they are responsible for, and sets the sizes of the components and the GUI, then call setLocationRelativeTo(null) to center my GUI, then call setVisible(true) to display it.
The layout manager is responsible for determining the size of a component, so you don't know its actual size until the component has been added to the frame and the frame has been pack()ed ore made visible.
If you use a layout manager that respects the preferred size of a component then you can use:
component.getPreferredSize();
Why do you think you need to know the size? Generally you don't worry about sizes and let the layout manager do its job.
In addition to the usual pack() > setVisible(true) > getPreferredSize() sequence, you can validate() the relevant Container to preview the geometry, as shown here.
If I understand properly, the reason why you want to know the size of a component is to reset the size of a JWindow once a user click on the "More options" button, isn't it?
I would suggest to do the following: when the user clicks on that button, update your UI adding the extra component, and the execute pack() on the JWindow. It should resize to the proper size.

Swing: Is there a simple way to make 1 component ignore the layout manager?

I have a JPanel with one component that I want to place in an absolute sense, whereas the rest of the components are placed according to a layout manager.
Is there a simple way to do this?
Are you saying you want a component painted over top of all the other components? If so then you would need to use a JLayeredPane.
Why don't you post a SSCCE that demonstrates what you want to do?
You can add components to a frame as you would do normally and make the frame visible. Then you can add this random component and use setBounds on the component. As long as you don't revalidate() the panel or resize the frame we will be able to see how you intend to position this component relative to all the other components.
You might also want to look at OverlayLayout, seen here. For some reason it's excluded from the conventional gallery, but it may be of interest.
You can do this with only needing one JPanel using MigLayout

Categories