Search code examples
javaswingjpaneljscrollpanejlayeredpane

java, swing - Adding a JlayeredPane in JScrollPane only shows a blank background


I have already searched for a solution for this but they did not work. Maybe because mine is set-up differently. I'm trying to make an elevator simulator and i have this diagram: diagram and i have this code:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

@SuppressWarnings("serial")
public class Test extends JFrame {

    public Test() {

        Container contentPane = getContentPane();
        GridBagConstraints constraints = new GridBagConstraints();
        JButton floor = new JButton();
        JLabel cab = new JLabel();
        JPanel floorPanel = new JPanel();
        JPanel cabPanel = new JPanel();
        JLayeredPane layeredPane = new JLayeredPane();
        JScrollPane scroll = new JScrollPane();

        setResizable(false);
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        contentPane.setBackground(Color.BLUE);
        contentPane.setLayout(new GridBagLayout());

        constraints.insets = new Insets(20, 92, 20, 92);

        floorPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
        floorPanel.setPreferredSize(new Dimension(165, 165));

        floor.setPreferredSize(new Dimension(165, 165));
        floor.setBackground(Color.WHITE);
        floor.setText("1");

        cab.setPreferredSize(new Dimension(165, 165));
        cab.setText("Cab");
        cab.setBackground(Color.BLACK);
        cab.setLocation(0, 0);

        cabPanel.setLayout(null);
        cabPanel.setPreferredSize(new Dimension(165, 165));
        cabPanel.setOpaque(false);
        cabPanel.add(cab);

        layeredPane.setLayout(new BorderLayout());
        layeredPane.setPreferredSize(new Dimension(165, 165));
        layeredPane.add(floorPanel, 0);
        layeredPane.add(cabPanel, 1);

        scroll.setMinimumSize(new Dimension(183, 660));
        scroll.setMaximumSize(new Dimension(183, 660));
        scroll.setViewportView(layeredPane);

        contentPane.add(scroll, constraints);

        pack();
        setVisible(true);
    }

}

It wont display the two JPanels added to the JLayeredPane and only displays a blank background. I tried the setOpaque(false) on the JPanel in the second layer of the JLayeredPane but it still didn't work.

If by chance you have already found a solution somewhere please send a link. Ps. sorry for the wrong grammars


Solution

  • Again with a JLayeredPane you will need to set the location and position of any component added to the JLayeredPane since it acts as if it has a null layout, but with layers.

    For example, check out and run this code:

    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.Container;
    import java.awt.Dimension;
    import java.awt.Font;
    import java.awt.GridBagLayout;
    import java.awt.GridLayout;
    import java.awt.Point;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
    
    import javax.swing.*;
    import javax.swing.border.Border;
    
    @SuppressWarnings("serial")
    public class LayeredExample extends JPanel {
    
        public LayeredExample() {
            int gridRows = 20;
            int gridCols = 10;
            JPanel panelA = new JPanel(new GridLayout(gridRows, gridCols));
            for (int i = 0; i < gridRows; i++) {
                for (int j = 0; j < gridCols; j++) {
                    String labelText = String.format("[%d, %d]", j + 1, i + 1);
                    JLabel label = new JLabel(labelText);
    
                    Border outsideBorder = BorderFactory.createLineBorder(Color.BLUE);
                    Border insideBorder = BorderFactory.createEmptyBorder(3, 3, 3, 3);
                    label.setBorder(BorderFactory.createCompoundBorder(outsideBorder, insideBorder));
                    panelA.add(label);
                }
            }
            panelA.setBorder(BorderFactory.createTitledBorder("Panel A"));
            panelA.setSize(panelA.getPreferredSize());
            panelA.setLocation(0, 0);
    
            JLabel dragMeLabel = new JLabel("Drag Me!");
            dragMeLabel.setFont(dragMeLabel.getFont().deriveFont(Font.BOLD, 54f));
            JPanel panelB = new JPanel(new GridBagLayout());
            panelB.add(dragMeLabel);
            panelB.setBorder(BorderFactory.createTitledBorder("Panel B"));
            panelB.setPreferredSize(new Dimension(800, 500));
            panelB.setSize(panelB.getPreferredSize());
            panelB.setLocation(200, 200);
    
            MouseAdapter myMouse = new MouseAdapter() {
                private Point p0;
                private Point loc0;
    
                @Override
                public void mousePressed(MouseEvent e) {
                    p0 = e.getLocationOnScreen();
                    loc0 = ((JComponent) e.getSource()).getLocation();
                }
    
                private void moveComponent(MouseEvent e) {
                    if (p0 == null || loc0 == null) {
                        return;
                    }
                    Point p1 = e.getLocationOnScreen();
                    JComponent comp = (JComponent)e.getSource();
                    Container cont = comp.getParent();
                    int x = loc0.x + p1.x - p0.x;
                    int y = loc0.y + p1.y - p0.y;
                    Point loc1 = new Point(x, y);
                    comp.setLocation(loc1);
                    cont.repaint();
                }
    
                @Override
                public void mouseDragged(MouseEvent e) {
                    moveComponent(e);
                }
    
                @Override
                public void mouseReleased(MouseEvent e) {
                    moveComponent(e);
                    p0 = null;
                    loc0 = null;
                }
            };
    
            panelB.addMouseListener(myMouse);
            panelB.addMouseMotionListener(myMouse);
    
            JLayeredPane layeredPane = new JLayeredPane();
            layeredPane.add(panelA, JLayeredPane.DEFAULT_LAYER);
            layeredPane.add(panelB, JLayeredPane.PALETTE_LAYER);
            layeredPane.setPreferredSize(new Dimension(1600, 1200));
    
            JScrollPane scrollPane = new JScrollPane(layeredPane);
            scrollPane.getViewport().setPreferredSize(new Dimension(800, 650));
    
            setLayout(new BorderLayout());
            add(scrollPane);
        }
    
        private static void createAndShowGui() {
            JFrame frame = new JFrame("LayeredExample");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.getContentPane().add(new LayeredExample());
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        }
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(() -> createAndShowGui());
        }
    }