0

Is there any way to get the (preferred I guess) size of the components of a JLabel so I can resize it to them? My JLabel gets a size of 0,0 unless I set its Preferred Size, but setting its size to an arbitrary pixel value seems like the wrong approach, since the whole point of using Swing (as far as I understand it) is not doing that.

Things that I've already tried:

  • repaint() and refactor()
  • adding a LayoutManager to the JPanel (in this case BoxLayout)

This is basically what I am doing:

package invisiblelabel;

import java.awt.Color;
import java.awt.Dimension;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.Border;

public class InvisibleLabel {

public static JFrame frame;
public static JPanel panel;
public static JLabel visible;
public static JLabel visibleText;
public static JLabel invisible;
public static JLabel text1;
public static JLabel text2;

public static void main(String[] args) {
    createGraphics();
}

public static void createGraphics(){
    frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    panel = new JPanel();

    visible = new JLabel();
    visible.setPreferredSize(new Dimension (500,500));
    Border border = BorderFactory.createLineBorder(Color.black);
    visible.setBorder(border);
    visible.setLayout(new BoxLayout(visible, BoxLayout.Y_AXIS));

    visibleText = new JLabel ("This JLabel is visible, because it is created fitting its text.");
    visible.add(visibleText);

    invisible = new JLabel();
    text1 = new JLabel("You can't read this anyways.");
    text2 = new JLabel("You can't read this either.");
    invisible.add(text1);
    invisible.add(text2);

    visible.add(invisible);

    panel.add(visible);
    frame.add(panel);

    frame.setLocationRelativeTo(null);
    frame.setSize(800,600);
    frame.setVisible(true);

    visible.repaint();
    visible.revalidate();
}

}

}

sgf
  • 145
  • 6
  • [for example](http://stackoverflow.com/questions/8575641/how-returns-xxxsize-from-jcomponents-added-to-the-jlabel), as aside you have to programatically call repaint() from mousemotionevent (seems to missing in API) – mKorbel Mar 06 '15 at 05:56
  • That is exactly the question (and answer) I'd been looking for for at least an hour. – sgf Mar 06 '15 at 13:14

1 Answers1

3

I'm curious as to why you're using a JLabel as a container, however...

Something like, overriding the JLabel's getPreferredSize method...

@Overrride
public Dimension getPreferredSize() {
    LayoutManager lm = getLayout();
    return lm.preferredLayoutSize(this);
}

would get you started. This does not take into account the requirements of any borders, you'd need to add those in as well, if it was important to you...

This also assumes, that you've applied a layout manager to the JLabel

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • There doesn't seem to be a method getLayoutManager(). Edit: (and ninja'd) Is it getLayout()? – sgf Mar 06 '15 at 01:46
  • The reason I'm doing this is that I wanted a simple way of adding several single lines of text over an image (as a log), so I had one JLabel for the icon containing one for getting the proper position (EmptyBorder is acting up for JLabels as well) and inside that one several JLabels showing my lines of text. This actually seemed to me to be the most intuitive way of doing it but probably I'm missing something obvious. – sgf Mar 06 '15 at 01:49
  • `getLayoutManager` should be `getLayout` – MadProgrammer Mar 06 '15 at 01:50
  • Instead of using a `JLabel` to act as the background, you could use something like [this](http://stackoverflow.com/questions/28889667/create-a-form-with-a-background-image-jlayeredpane/28889883#28889883) instead, which would separate the requirements of the background from the layout of the components... – MadProgrammer Mar 06 '15 at 01:50
  • This is actually very useful for what I am trying to do. However, your solution doesn't seem to work for me. (Assuming I am to go invisible.setPreferredSize(invisible.getPreferredSize());) , but even then it won't show. However, what I really meaned to ask is 'is there a standard way of doing it' and it seems to be answered by your answer to the other question. (Basically, no.) Thanks for your help! – sgf Mar 06 '15 at 02:00
  • The strange thing is that neither setSize nor setPreferredSize+ setMinimumSize will work, although they clearly worked for the first JLabel (visible). So apparently this has less to do with the behaviour of the embedded JLabel and more with the behaviour of the embedding one, which will not use the embedded JLabel's size at all. – sgf Mar 06 '15 at 02:28
  • Seems to work ok for me...by default, `JLabel` calculates it's preferred size based on the icon and text properties... – MadProgrammer Mar 06 '15 at 02:32
  • For some reason, it works when I set the container JLabel to FlowLayout, but not when I set it to vertical BoxLayout. I have no idea why that may be. – sgf Mar 06 '15 at 13:27