4

I use a JLabel to view an image in a JFrame. I load it from a file with an ImageIcon.

JFrame frame = new JFrame(String);
frame.setLocationByPlatform(true);
frame.setSize(500, 500);
frame.setResizable(false);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel cpu = new JLabel(new ImageIcon(String));
cpu.setLocation(20, 20);
cpu.setSize(20, 460);
frame.add(cpu);
frame.setVisible(true);

I can't set location and size of the JLabel because it is done automatically.

I have to manually set these values because I want to truncate the image (vertical progress bar).

spongebob
  • 8,370
  • 15
  • 50
  • 83
  • Try looking [here](http://stackoverflow.com/questions/1783793/java-difference-between-the-setpreferredsize-and-setsize-methods-in-compone). Also, if `String` is a variable, rename is to `string`. – user1803551 Sep 29 '14 at 16:00
  • @user1803551 I used `String` to represent a generic string value. – spongebob Sep 29 '14 at 16:06
  • 2
    The size of the label should be the size of the image. What is the point of trying to manually set the size of your label? The painting of the image does not stretch/shrink so you will either have empty space in the label or a truncated image. – camickr Sep 29 '14 at 16:06
  • @camickr Changing the `JFrame` will resize the `JLabel` and its image. – spongebob Sep 29 '14 at 16:20
  • I guess what @camickr is trying to say is delete `cpu.setSize(20, 460);` that line. If you manually add the size to the `JLabel` will make it truncate your image or have empty space on the borders (as camickr already said). – Frakcool Sep 29 '14 at 16:23
  • @Frakcool Same output. – spongebob Sep 29 '14 at 16:25
  • @Joiner can you post an [MCVE](http://stackoverflow.com/help/mcve) please? I mean a Complete program that we can copy-paste, compile and see the same error as you so we can help you in a better way. – Frakcool Sep 29 '14 at 16:27
  • @Frakcool I posted the relevant algorithm. But, in this particular situation, you can copy it in a `public static void main(String[] args) {}`. – spongebob Sep 29 '14 at 16:32
  • @Joiner I know, just was asking because of imports and everything 'cause I'm at school and don't have something like NetBeans or Eclipse on this lab. So... you know. Anyway I'll check it – Frakcool Sep 29 '14 at 16:35
  • @Frakcool `javax.swing.JFrame`, `javax.swing.JLabel` and `javax.swing.ImageIcon`. – spongebob Sep 29 '14 at 16:49
  • @Joiner This isn't a solution but a good workaround. Why not just use a JImagePanel? https://github.com/dberm22/DBoard/blob/master/src/com/dberm22/utils/JImagePanel.java – dberm22 Sep 29 '14 at 17:12
  • @Joiner How is it longer? It's actually shorter. Just copy that file into your project and call it with JImagePanel cpu = new JImagePanel(String); And then you're done. It's not only shorter than these other solutions, but it's shorter than your original code. – dberm22 Sep 29 '14 at 20:02
  • @dberm22 You forgot the content of the class. – spongebob Sep 30 '14 at 09:07
  • @Joiner Yes, but why do you care? Short code does not mean good code. See here: http://programmers.stackexchange.com/a/43156 . Your accepted answer even warns DO NOT USE A NULL LAYOUT MANAGER. The number one comment on that answer echos the same concern. Yes, adding a file to your project makes it longer now, but wait until you have to start maintaining your code, or adding buttons to your window. Trust me, it will be hell. Length of code is one thing, time it takes to maintain/build on the code is another thing entirely. Most would agree the latter is more important. – dberm22 Oct 22 '14 at 12:37
  • @dberm22 I think short code is more maintainable. – spongebob Oct 22 '14 at 14:01
  • @Joiner Not always. And especially not in this case. Trust me...do not use a null layout manager. If you ever have to go back and change themes, icons, add a button, remove a button, change the size, really modification at all, you will have to change EVERY COMPONENT. Do not do this unless you absolutely, positively NEED to, or if you are 1000% sure you will never have to modify the layout. But if you're like me, you're not going to listen and you're going to do what you want. Sometimes it takes getting 3rd degree burns before you learn not to put your hand on a grill. – dberm22 Oct 23 '14 at 11:42
  • @dberm22 I understood what you mean. You could add your own answer if you desire, but I abandoned this project weeks ago and I do not need to use `swing` at all while coding in Java, so I think [the answer that worked for me personally](http://stackoverflow.com/help/accepted-answer) is the one about using a null layout. – spongebob Oct 23 '14 at 12:50

3 Answers3

5

One way is to just paint the image:

final ImageIcon icon = new ImageIcon(path);
JPanel panel = new JPanel() {
    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.drawImage(icon.getImage(), 0, 0, getWidth(), getHeight(), this);
    }
    @Override
    public Dimension getPreferredSize() {
        return new Dimension(500, 500);
    }
};
frame.add(panel); 

The getWidth() and getHeight() in drawImage will force the image to stretch the size of the panel. Also the getPreferredSize() will give a size to the panel.

If want the panel to stay that size, then make sure it's parent container has a layout manager that will respect preferred sizes, like FlowLayout or GridBagLayout. If you want the panel to be stretched, the make sure it's parent container has a layout manager that disregards the preferred size, like BorderLayout or GridLayout

Community
  • 1
  • 1
Paul Samsotha
  • 205,037
  • 37
  • 486
  • 720
  • I asked about the `JLabel` control, why are you using a `JPanel`? – spongebob Sep 30 '14 at 09:21
  • If you want you can use a JLabel and do the same thing. I'd rather paint on a panel though. They're both containers and work the same way. Just JLabel has a view more features. In the code, just change the `JPanel`s to `JLabel`. It's the same result. If you use JLabel, and you want to add components to it (like you would a panel), go ahead, that's what containers are there for. You just need to set the layout manager for the label – Paul Samsotha Sep 30 '14 at 09:27
  • This is not my problem: if I use a `JLabel` or I override a `JPanel`, it doesn't matter. **I can't set size and location of the control.** – spongebob Sep 30 '14 at 09:36
  • Looking at your comment for camickr, seeing how the image is not the concern, what you are trying to do is `setSize()`. Layout managers are driven by the `preferredSize`. So for a layout manager like FlowLayout, is the preferred size is available, the size will be respected. In your case of the default BorderLayout, it won't respect preferred sizes. What you are currently seeing is the label stretched, though you cant notice it because it is _not_ opaque by default. All you see is the image. But the label actually _is_ stretched – Paul Samsotha Sep 30 '14 at 09:38
  • For setting the size (`setSize()`), yes a null layout is needed for this, but with swing (as the bottom part of my answer suggests) you should not use null layouts. Instead make use of the layout managers. Learn which ones will respect preferred sizes and which ones won't. Also use EmptyBorders if you want spacing – Paul Samsotha Sep 30 '14 at 09:40
  • So my basic point is stay away from `setSize()` and `setLocation()`. Let the layout managers do this for you. You just need to take time to learn the intricacies of each one of them. The link I provided is a good starting point. – Paul Samsotha Sep 30 '14 at 09:42
  • Also try this out. Using the code in my answer, set the layout manager of the frame to `GridBagLayout` (this will respect the preferred size of the panel). Give the size of the panel, then add the panel to the frame. By default, GridBagLayout will center the components. See the result – Paul Samsotha Sep 30 '14 at 09:44
  • Then try to set the layout manager of the frame to `new FlowLayout(FlowLayout.LEADING))`. This will also respect the preferred size of the panel. The `LEADING` will bring the panel to the left. Then you can add an EmptyBorder to the panel, like `panel.setBorder(new EmptyBorder(50, 50, 0, 0))` (top, left, bottom, center). Run it and you will see the panel is 50 pixels from the top and left – Paul Samsotha Sep 30 '14 at 09:47
4

The size of your original is (58 x 510). If you want to display the image at a fixed size of 20 x 420, then you should scale your image to that size to you don't truncate any of the image. One way to do that is to use the Image.getScaledImage(...) method. Then you just add the scaled image to the label.

If you want to position your label (20, 20) from the top left of the panel, then you can add an EmptyBorder to the panel or the label.

Use the features of Swing.

Edit:

I want to truncate the image

Read your Image into a BufferedImage. Then you can use the getSubImage(...) method to get an image any size you want. Then you can use the sub image to create your ImageIcon and add it to a label.

camickr
  • 321,443
  • 19
  • 166
  • 288
  • Image does not matter. I always can't set size and location of the control. – spongebob Sep 30 '14 at 09:30
  • @Joiner, `I always can't set size and location of the control.` Exactly, you should not be attempting to manually set the size/location of a component. Let the layout manager do this and it will work on all platforms. – camickr Sep 30 '14 at 13:56
  • **I want** to set these values. – spongebob Sep 30 '14 at 13:57
  • @Joiner, every component has a preferred size. You should NOT be attempting to set the size. If you set the size of a label incorrectly, then you can truncate the text or the image of the label. You have given us no further information other than "I want". That is not a good reason. If you tell us why you think you need to do this we can give you a better solution. We have already given you information on layout managers and how to use Borders. We can't keep guessing. – camickr Sep 30 '14 at 14:00
1

The LayoutManager is auto-sizing your components, not allowing you to resize manually.

If you want to get away from this, you can turn off the LayoutManager.

frame.setLayout(null);

Please note that you should not use the null layout.

spongebob
  • 8,370
  • 15
  • 50
  • 83
ControlAltDel
  • 33,923
  • 10
  • 53
  • 80
  • 3
    avoid the use of null Layout. Instead use Layout Managers – Frakcool Sep 29 '14 at 16:16
  • 1
    This code does not resize the image. It truncates the image. The size of your original image is (58 x 510). Therefore you are cutting off the bottom part of the image, which means you lose that color of the rainbow. Swing was not designed to be using with a null layout and there is certainly no reason to use a null layout here. – camickr Sep 29 '14 at 17:07
  • @camickr ...and we all love green. I measured the same dimensions, although if I hover with my mouse over the file I get the tooltip saying "Dimensions: 259x194" on Windows. Not sure what it actually measures. – user1803551 Sep 29 '14 at 17:09
  • @user1803551, Using IE, I just right clicked the image posted in the question and then selected the "Properties" menu item to get the Dimension. – camickr Sep 29 '14 at 17:15
  • @camickr I agree, I was just wondering why the contradiction. It's off-topic anyway. – user1803551 Sep 29 '14 at 17:17