AutoScroll when Shape is outside a JPanel - java

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.

Related

How do I get the bounds of a JPanel centered in another JPanel?

I have a main panel with a border layout containing another panel in the center.
Because I want to paint inside the centered panel I have to get the bounds of it.
panel_main.add(panel, BorderLayout.CENTER);
I wanted to save the bounds in a rectangle like this:
Rectangle bounding = new Rectangle
(panel.getX(), panel.getY(), panel.getWidth(), panel.getHeight());
But every argument seems to be 0. So how do I get the bounds of the panel?
Could I get the bounds of the BorderLayout instead?
But every argument seems to be 0.
All Swing components have a size of (0, 0) when they are created. Components are only given a size when the frame is packed and made visible.
Because I want to paint inside the centered panel I have to get the bounds of it.
You override the paintComponent() method of the panel. Then you can use the getSize() method to control where the painting is done.
You will also need to override the getPreferredSize() method of the panel so the layout manager can pack() the frame properly.
Read the section from the Swing tutorial on Custom Painting for more information and working examples to get you started.

How to make JPanel resize to fits its components?

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

JDialog doesn't respect dimensions of child components

I have a setup that usually works, but I'm finding it a bit of a pain at the moment.
I have a JDialog (formerly a JFrame, but I've changed the UI flow recently to remove redundant JFrames) set to BorderLayout that contains three main JPanels, header, content and footer.
The header JPanel has a background image that is loading fine. However, I'm calling all manner of setMinimumSize / setPreferredSize / etc (I even tried setSize and setBounds out of desperation) and the JPanel isn't being sized correctly. The layout for that component is BoxLayout, and the children sit comfortably within it, but that shouldn't affect what I'm trying to do with the header panel itself.
The only thing that works is setting a size on the parent JDialog. But I don't want to do that / from what I've read it seems like bad design. I'd also have to maths out the potential width / height of all the children, add the margins, etc.
Advice I am not looking for: "use a different LayoutManager."
I want to understand if there's a reason for the child components not being respected.
I can provide code, but isolating a small, runnable segment is difficult given the amount of interlocked systems I'm juggling. Here is the relevant snippet to set the size of the JPanel. The image dimensions are 480 * 96.
public JPanelThemed(BufferedImage image) {
super();
this.backgroundImage = image;
setAllSimilarConstraints(new Dimension(image.getWidth(), image.getHeight()));
setOpaque(false);
}
// for use with BoxLayout as it requires explicit bounds to be set
public void setAllSimilarConstraints(Dimension dim) {
setPreferredSize(dim);
setMinimumSize(dim);
setMaximumSize(dim);
}
I would implement it a bit another way - to ensure that preferred/min/max/Size can not be changed from elsewhere:
public JPanelThemed(BufferedImage image) {
this.backgroundImage = image;
setOpaque(false);
}
public Dimension getPreferredSize() {
return new Dimension(this.backgroundImage.getWidth(), this.backgroundImage.getHeight());
}
If I don't define dimensions, how do I ensure the whole background I'm painting is displayed?
You could use a JLabel to display the ImageIcon. The size of the label will be the size of the image. You then set the layout manager of the label so you can add components to it.
Edit:
do you know why it's commonly-recommended to subclass JPanel when painting backgrounds in Java
When you use a JPanel the size of the panel is based on the components added to the panel and the layout manager you are using. Your custom painting code then needs to paint the image the way your want. That is you can paint the image from (0, 0), or you can center the image on the panel, you can scale the image to make it fit the pane, but the image in no way controls the size of the panel, unless you override the getPreferredSize() method of the panel to use custom code to base the size of the larger of the components or the image. So you are in full control.
When you use the JLabel approach suggested here, the size of the label is always the size of the image. Then components will be positioned based on the layout manager but can be truncated if the image is smaller than the space required by the components.
So based on your requirement that you want to make sure the entire image is displayed, I suggested the JLabel approach, since you don't need to write any custom code. I find this a simple approach when using popup non-resizable dialogs to display a background image and a few components and buttons to close the dialog.
You can also check out Background Panel which provides these common painting features in a reusable class.

Scroll doesn't work in JScrollPane

I have a JPanel inside a JScrollPane, where I draw some shapes with Graphics.
The problem is when I draw outside the bounds of the panel, the scroll in the scroll pane doesn't work. I have autoresize activated on the JPanel.
Any tip?
The custom painted JPanel should return a preferred size appropriate for the graphic elements it contains.

Drawing 2Dcircle in an Jinternal frame

I have a JInternal Frame and I want to draw a circle(using 2Dgraphics) in it and make it flexible. I mean when I change the size of frame the circle become smaller or in making frame larger circle also become larger. Can somebody help?
You would draw in the paintComponent method of a JPanel or JComponent that is held in the JInternalFrame's contentPane, same as you would draw in any other JPanel. I'd get the dimensions of the JPanel at the start of the paintComponent method and use those values to tell how big to draw the circle.
Also, if you add the JPanel directly to the JInternalFrame's contentPane, it will be added by default BorderLayout.CENTER, and so when the JInternalFrame changes size, the JPanel also changes size, it's paintComponent will be called by the JVM, and the new drawing will be resized automatically.
add a WindowListener to the jInteralFrame and redraw whenever the size changes

Categories