Question

I have a JPanel that contains a bunch of small icons, and a JLabel containing a bigger icon.

First of all, I need clarification on something. By not setting panel.isOpaque, the said panel would have a transparent background and would properly overlap the icons of my JPanel and JLabel. Is this true?

Now to my problem. I've been following the LayeredPanes tutorial on the Oracle website, and I can't seem to make it right on my case.

    JFrame window = new JFrame();
    ImageIcon underIcon;
    URL urlUnder = myClass.class.getResource("images/underImage.gif");
    underIcon = new ImageIcon(urlUnder);
    JLabel labelUnder = new JLabel(underIcon);

    ImageIcon panelIcon;
    URL urlAbove = myClass.class.getResource("images/aboveImage.gif");
    panelIcon = new ImageIcon(urlAbove);
    JLabel aboveIcon1 = new JLabel(panelIcon);
    JLabel aboveIcon2 = new JLabel(panelIcon);

    JPanel panelAbove = new JPanel(new BorderLayout());
    panelAbove.setOpaque(false);
    panelAbove.add(aboveIcon1, BorderLayout.WEST);
    panelAbove.add(aboveIcon2, BorderLayout.EAST);

    JLayeredPane layeredPane = new JLayeredPane();

    layeredPane.setLayout(new BorderLayout());

    layeredPane.add(labelUnder, BorderLayout.CENTER, 1);
    layeredPane.add(panelAbove, BorderLayout.CENTER, 2);

    layeredPane.setOpaque(true);

    window.setContentPane(layeredPane);

    window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    window.pack();
    window.setVisible(true);

I only see the contents of the panel. And I'm 100% sure the images are there on getResource, so that's not the issue. Please advice on how to properly use Layered Panes.

Was it helpful?

Solution

The problem is you are setting a layout manager to the JLayeredPane

layeredPane.setLayout(new BorderLayout());

In of it self, this is not a problem, but your choice of layout manager is.

BorderLayout will only a single componet to occupy any of it's 5 predefined positions. This means when you add your second component, it, effectively, replaces the first.

Try using someone like GridBagLayout instead. Providing a single GridBagConstaint set so that the weightx/y values ara equal to 1, the fill property is set to BOTH and it's gridx/y properties are set to 0

Unlike BorderLayout, GridBagLayout will allow you to layout components to the same position

OTHER TIPS

From the Java Tutorial:

layeredPane.add(dukeLabel, new Integer(2), 0);

This code uses the three-argument version of the add method. The third argument specifies the Duke label position within its depth, which determines the component's relationship with other components at the same depth.

Positions are specified with an int between -1 and (n - 1), where n is the number of components at the depth. Unlike layer numbers, the smaller the position number, the higher the component within its depth. Using -1 is the same as using n - 1; it indicates the bottom-most position. Using 0 specifies that the component should be in the top-most position within its depth. As the following figure shows, with the exception of -1, a lower position number indicates a higher position within a depth.

So your depth orders are the wrong way around, also start from 0.

I also found this in the Solving Common Component Problems Section

Problem: The components in my layered pane are not layered correctly. In fact, the layers seem to be inversed — the lower the depth the higher the component.

This can happen if you use an int instead of an Integer when adding components to a layered pane. To see what happens, in the LayeredPaneDemo class, change

layeredPane.add(label, new Integer(i));

to

layeredPane.add(label, i);.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top