2

I want to show many different labels over a map, so I'm using null layout in my panel, and calling setLocation for each label. For some reason, though, the labels don't show. If I remove the pan.setLayout(null), then the label appears in the top-center of the panel. Why isn't null layout working with setPosition?

package mapa;

import java.awt.*;
import javax.swing.*;

public class Mapa extends JFrame {
  private static JPanel pan;
  private static JLabel lab;

  public Mapa() {
  }

  private static void createAndShowGUI() {
    Mapa frame = new Mapa();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    lab = new JLabel("TEXTO");
    lab.setBackground(Color.black);
    lab.setForeground(Color.white);
    lab.setOpaque(true);
    lab.setVisible(true);

    pan = new JPanel();
    pan.setLayout(null);
    pan.setPreferredSize(new Dimension(640,480));
    pan.add(lab);
    lab.setLocation(100, 100);

    frame.getContentPane().add(pan, BorderLayout.CENTER);
    frame.pack();
    frame.setVisible(true);
  }

  public static void main(String[] args) {
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
      @Override
      public void run() {
        createAndShowGUI();
      }
    });
  }
}
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
Rodrigo
  • 4,706
  • 6
  • 51
  • 94

2 Answers2

7

This is the problem with absolute positioning (or null layout). It requires you to set the sizes of all your components, otherwise they will stay are their default zero-size and won't appear. That's why it's always better to use a layout manager.

Reimeus
  • 158,255
  • 15
  • 216
  • 276
  • My labels are scattered all around the panel in specific positions (coordinates on the map), so I guess I have no option but null layout. I found out how to get the size of labels using getFontMetrics(), so set their size will be no problem. Thanks! – Rodrigo Jan 14 '13 at 01:29
  • @Rodrigo no need for going as low-level as fontMetrics - even if you insist on doing the sizing manually: simply ask the label for its prefSize. But then: **don't** do the sizing/positioning manually, leave it to a suitable LayoutManager - which might be a highly specialized custom implementation which is aware of the coordinates which should control the location. Or do the locating yourself and at least leave the sizing to a manager, f.i. [Rob's DragLayout](http://tips4java.wordpress.com/2011/10/23/drag-layout/) – kleopatra Jan 14 '13 at 12:51
  • To summarize what kleopatra said: Don't use label.getFontMetrics(), use label.getPreferredSize(). – VGR Jan 14 '13 at 13:38
  • Thanks, GetPreferredSize worked fine too. Kleopatra, this "custom implementation" is not just what I did to put each label in its place? I read about DragLayout, but I don't need it to calculate the size of the panel, since its depending on the size of the panel that I calculate the labels' positions. – Rodrigo Jan 15 '13 at 00:25
2

You have to set the size of the label explicitly; try using setBounds instead of setLocation. For example, lab.setBounds(100,100,200,30); Also there's no need to call setVisible(true); on the label.

Unless there's a very good reason to use a null layout and you know exactly what you're doing, using a layout manager is always where you should start.

rtheunissen
  • 7,347
  • 5
  • 34
  • 65