0

I have a JFrame with a single JPanel inside. The panel displays images that are received from the network at runtime. These images are usually big, but can have any size. Considering this and given that I might add a menu bar to the frame in the future, I'd like to do the following:

  • For each received image, the panel resizes to its exact size.
  • If the image (and hence the resized panel) exceeds a certain maximum value in width or height (e.g.: the screen size - 100px), then the frame should resize to the maximum allowed value and enable scrollbars.
  • Otherwise, the frame should adjust its size to display the entire panel without any padding. So the frame size is the content panel size plus the borders and the title bar (and the menu bar if I finally add it).

Is there a way to do this? If not, what would be the best alternative?

Thanks in advance

EDIT:

The problem, to summarize, is how to resize the parent frame to adjust to its child content panel. This is the opposite of what most people do (resize panel to fit frame).

For point #3, I already have the content panel dimension, so the problem is reduced to calc the size of the frame's frame (top title bar height, borders width). With that, I could resize the frame to a size such as the content pane fits exactly inside.

Mister Smith
  • 27,417
  • 21
  • 110
  • 193
  • sounds pretty standard behaviour, what's wrong with pack()? – kleopatra Mar 29 '12 at 12:01
  • @kleopatra dunno the reason, but doesn't work. Launch the frame with minimum size, then when the images are received, I resize the panel. At that point, if I call pack, the frame doesn't change its size. – Mister Smith Mar 29 '12 at 12:03
  • it's not _your_ job to resize anything, it's the LayoutManager's job: let the panel decide its prefSize based on the image size, let it revalidate itself on receiving a new image, then call pack on the frame - worksformealways (from the top of my head, don't have a IDE handy) – kleopatra Mar 29 '12 at 12:21
  • @kleopatra There's only a frame with a custom pane (where I have overridden `paintComponent`) inside. Calling `pack` doesn't work. I tried calling also validate on itself and on the contentPane, without success. I tried also commenting the `frame.setMinimumSize` line, no luck. The custom pane is called `setSize` after every update. – Mister Smith Mar 29 '12 at 13:18
  • the way you are describing is the wrong thingy to do - read my last comment and implement that in an sscce. Then we'll see if/how/what isn't working :-) – kleopatra Mar 29 '12 at 15:04
  • @kleopatra Ok, I did a major modification and went to the recommended way of using an ImageIcon and a Label. Now `pack` works, but the icon doesn't refresh after calling setImage. I called validate and invalidate on panels but no luck here. I also have an additional problem and it is that for pack to work I had to remove my ScrollPane and add the things directly to the frame, so now when the icon is larger than the frame max size, theres no scroll. – Mister Smith Mar 29 '12 at 16:06
  • -1 for still not showing an sscce. Descriptions of your trials (which sound unusual) are not useful. – kleopatra Mar 30 '12 at 09:24
  • @kleopatra Thanks, I've no time for that. The ImageIcon approach is not suitable for my needs. I've seen a number of answers in other questions recommending my initial panel approach, as it is more efficient for high frequency updates. The problem of using panel with only `paintComponent` overriden is that it doesn't provide size info to its parent container, so calling `pack` simply and plain doesn't work. – Mister Smith Mar 30 '12 at 10:05
  • _I've no time for that_ shaking head in disbelieve ;-) Seems like you also didn't have time to read my comments carefully (one last hint: you are erring on _**only** paintComponent overriden_) – kleopatra Mar 30 '12 at 10:18
  • I know XD. I took the idea from here http://stackoverflow.com/a/299555/813951 but seems that I should also override other methods to get the thing working. I'll take on that soon. Thanks anyway. – Mister Smith Mar 30 '12 at 10:22

1 Answers1

2

EDIT

put images as Icon to the JLabel

but

pictures = new ImageIcon("Xxxxx");
pictures.getImage().flush();
myLabel.setIcon(pictures);
  • this code should be better to call from SwingWorker, or from Runnable#Thread, but in this case you have to wrap the code line myLabel.setIcon(pictures); into invokeLater(),

  • more about SwingWorker and invokeLater() in the tutorial Concurency in Swing, bunch of answers about concurency on this forum

mKorbel
  • 109,525
  • 20
  • 134
  • 319
  • Thanks for your advice, but I don't want to resize the images. These should be displayed in full size. What I need is to enable scrolling or not depending on the image size and the total display size. – Mister Smith Mar 29 '12 at 09:00
  • It is interesting how Swing is not so well designed as to allow this easily, and instead a lot of people choose to use the image icon hack. – Mister Smith Mar 29 '12 at 10:25