How to make JPanel resize to fits its components? - java

I have a JScrollPane whose viewport is a JPanel. The JPanel contains smaller JPanels that take up the entire viewport's width, and the big JPanel is set to a FlowLayout. The user should be able to add as many JPanels as they want (well, up to 200 for my purposes), and they should be able to scroll down the JScrollPane to see everything they have added. Basically I'm just trying to make the JScrollPane grow. I'm calculating what I thought the JPanel's height should be like this:
Dimension dimension = new Dimension(width, smallPanel.height * totalPanels
+ ((FlowLayout) getLayout()).getVGap * totalPanels);
setPreferredSize(dimension);
And it mostly works, but as you add more, it starts cutting the smaller JPanels off, and the bottom panel eventually isn't shown. Is there a way that I can determine the size of the JPanel for the viewport so that I wouldn't have to calculate its dimensions with variables? Like pack() does for JFrame? Or do I need to keep guessing and checking?
Thanks

Related

JFrame & JPanel sizing issue

I am attempting to code a JFrame containing a JPanel. Within the JPanel is an array of JTextField's. So, my GUI looks like:-
I am not using a layout manager, and have set this to null for the JFrame and the JPanel. I am sizing these components by hand.
You can see that the right hand portion of the JPanel is chopped off, even though I have used the same sizing as the containing JFrame.
The code appears as below:-
I have calculated the required width of the JPanel by multiplying the number of columns in the JTextField array by the width of the JTextField. Aside from that would need to be added the width of each gap between the JTextFields (there would be (columnNumber - 1) of them), as well as the two border gaps.
I have done this, yet the right hand side border gap is chopped off, as you can see from the diagram.
If I add some random amount to the panelWidth, then you can see the right hand gap there, but my question is what am I missing here? This ought to work surely, if the JFrame side and the JPanel size are identical, which they are as I have also printed them both out, and the print outs give the same number.
Jeremy
I want for any combination of row/column values to allow a constant vertical & horizontal distance between each JTextField, and for each of those text fields to maintain default sizing.
The GridLayout allows you to specify a horizontal/vertical gap between each component and allows you to control the size of the grid.
Then you can wrap the panel using a GridLayout in a panel that respects the size of the grid.
For example you could do:
JPanel grid = new JPanel( new GridLayout(...) );
JPanel wrapper = new JPanel( new GridBagLayout() );
wrapper.add(grid, new GridBagConstraints());
frame.add(wrapper, BorderLayout.CENTER);
If you pack the frame, the grid panel will be displayed at is preferred size.
If you resize the frame the grid panel will remain centered in the wrapper panel.
The top part of that GUI is well suited to a grid layout, the bottom part with 'Go / Cancel' buttons - a flow layout. Put the grid layout in the CENTER of a border layout, the flow layout in the PAGE_END, pack the top level container (for non-cropped, 'right size') & the job is done.
It might end up looking something like this:

How to make JPanel transparent in Java

I have multiply smaller JPanels which are then added to a bigger JPanel which is the same size as JFrame. Now I want to make those smaller JPanels transparent and the image I have added to the bigger JPanel showing in the background. I tried using setOpaque(true) on the smaller JPanels but it does not show the image that I have added to the bigger JPanel. I hope you understood my problem.

AutoScroll when Shape is outside a JPanel

I have a JPanel where I draw shapes. this panel is added to a scrollPane. but the scrolling doesn't work when a shape is out of the scene. is there an easy way to autoscroll or I have to do it programmatically.
Thank you
I'm assuming you're using the JPanel as a canvas for custom drawing(i.e. you're not adding any JComponents to it). If that's case, the JScrollPane has no way of knowing how large the JPanel is and will just size it to exactly fill the scrollPane's viewport(which means you'll never actually get scroll bars).
To fix this issue you should override getPreferredSize on your JPanel.
#Override
public Dimension getPreferredSize() {
int height = calculateHeight();
int width = calculateWidth();
return new Dimension(width, height);
}
Edit:
Also, since you're doing custom drawing make sure to call revalidate whenever the shapes you want to draw change. This tells swing that it needs to re-think the layout/size of the JPanel.

Java Swing: component that resizes itself but doesn't influence the layout

I'll try to explain my problem as simply as possible but it's a tricky topic and people who haven't encountered the issue probably won't know what I'm talking about.
I want to use a BorderLayout using west, east, north, south, etc. components that are my "normal" components (JLabels, JButtons, etc.) then I want the center component to be an "image" (that is: pixels). To this end I'm using a BufferedImage and using setIcon on a JLabel that is inside a panel that is part of the "center".
However I want my image/pixels to be "fluid": whenever the user resizes the app, I want to compute the exact size of the JLabel (icon/text gap is set to 0) and then create a new image (pixels that I manipulate directly in a BufferedImage but whatever) that has exactly that size.
Now it does work fine. But only when I resize the main window ("window" as in "one of the window of the operating system) by making it bigger.
It doesn't work when I downsize my main window.
The reason, after a lot of testing, is obviously because the size of my JLabel (in which I did a setIcon( img ) is influencing the computation of the layout manager.
So here comes the billion dollar question: how should I use a BorderLayout (or any other layout) so that I can create a "fluid" rectangle of pixels in the center of my app?
Answering my own question with an answer that I will not accept even tough it does work...
The problem can be "worked around" by creating a picture a few pixels smaller than the getVisibleRect of the center area.
So in my case I create an ImageIcon from a BufferedImage that is 20 pixels smaller (both in width and height) than the area that will hold it.
What happens then is that because the picture is smaller it doesn't "block"/prevent the layout manager from putting everything at their correct place when downsizing the main window.
So by using such an hack I get the "fluid" behavior I want.
This is however an hack whose level of hackyness cannot be understated and I'm sure there's a very clean way to solve this.
The reason, after a lot of testing, is
obviously because the size of my
JLabel (in which I did a setIcon( img
) is influencing the computation of
the layout manager.
The preferred size of the JLabel is used in the preferred size of the panel, but this size is ignored when you resize the frame, since the CENTER only gets whatever space is left over after the preferred size of the other 4 components is considered.
To this end I'm using a BufferedImage
and using setIcon on a JLabel that is
inside a panel that is part of the
"center".
Sounds to me like it should work.
Create the panel with a BorderLayout. Add the JLabel to the Center of your main panel. Then add a ComponentListener to the panel. Now when the frame is resized the center panel size will be adjusted to take the space available to it. Now that you know the size of the center panel you can recreate the Icon and add it to your JLabel,
This is how you write a SSCCE:
import java.awt.*;
import javax.swing.*;
public class LabelTest2 extends JFrame
{
public LabelTest2()
{
JLabel picture = new JLabel(new ImageIcon("???.jpg"));
add(picture);
}
public static void main(String[] args)
{
LabelTest2 frame = new LabelTest2();
frame.setDefaultCloseOperation( EXIT_ON_CLOSE );
frame.pack();
frame.setLocationRelativeTo( null );
frame.setVisible(true);
}
}

Why is the setPrefferedSize() method not working for JPanel?

I have created n JPanels and in each JPanel I have added 3 components. I added these JPanels to a new JPanel as rows. The layout for the n JPanels is FlowLayout and for the main panel is BorderLayout. The setPrefferedSize() method is working fine for the components which I have added in the n JPanels but it is not working for the n JPanels.
I am trying npanels[i].setPrefferedSize(new Dimension(300,25)),
I want the height of the JPanel to be equal to height the components added in it (which is 25).
Is there any constraint that the height of a JPanel should be some minimum value?
Please help I tried a lot of things but it's not working.....
Some layout managers tend to ignore the size setting...
Read somewhere that BorderLayout might tend to ignore the width for NORTH and SOUTH components,
height for EAST and WEST,
both height and width are ignored for CENTER...
Could this be the case?
Also, can you provide a screenshot or a diagram explaining whats happening?
The setPrefferedSize() method is
working fine for the components
There is generally no need to set a preferred size for components. Swing will calculate the preferred size automatically.
layout for n JPanels is FlowLayout...
which i have added in n JPanels but it
is not working for n JPanels
Again, there is no need to set the preferred size of each panel. The size will be calculated automatically based on the preferred size of all the components.
the main panel is BorderLayout
This does not make sense since you can't add "n" panels to the BorderLayout. You can only add one component to the North,Center and South so you can have a maximum of 3 different vertically display panels. In this case if you use frame.pack() then each panel will be displayed at its preferred size. On the other hand if you use frame.setSize(300, 400) then the hieght of the Center panel will be stretched.
Since it appears you want all panels the same size maybe you should be using a GridLayout, otherwise you can try a BoxLayout. Read the Swing tutorial. It explains all about using the layout managers.
If you need more help post your SSCCE.

Categories