简体   繁体   中英

JLayeredPane with JPanel

The problem: I have no control on implementing more into the histogram package, so I create an array of buttons and overlay them on top of the histogram using JLayeredPane. However, I cannot get both the histogram plot and the buttons panels to scale when the JFrame is enlarged or contracted. The JLayedPane is composed of 2 JPanels, see MWE.

To repeat the issue, just run program and extend JFrame.

I have read the following on SO posts; jlayeredpane-with-gridlayout , jlayeredpane-with-a-layoutmanager , jlayeredpane-not-resizing-with-jframe , resize-jframe-to-jpanels-inside-jlayeredpane , automatic-content-resizing-of-jlayeredpane , as well as the Oracle page on JLayeredPane which has some examples

As useful as these links were, I still cannot get both JPanels to extend/contract with the JFrame.

Question: Is there a way to get both JPanels in the JLayeredPane to rescale without implementing a new layout? If new layout is needed, would someone please provide a MWE on how to do such?

public class FrameDemo extends JPanel {

    private JLayeredPane layeredPane;
    private final int width = 800;
    private final int height = 800;
    private String[] layerStrings = { "Yellow (0)", "Magenta (1)", "Cyan (2)", "Red (3)", "Green (4)", "Blue (5)" };
    private Color[] layerColors = { Color.yellow, Color.magenta, Color.cyan, Color.red, Color.green, Color.blue };

    public FrameDemo() {
        setLayout(new BorderLayout());
        init();
        addPanels();
        add(layeredPane, BorderLayout.CENTER);
    }

    private void init() {
        this.layeredPane = new JLayeredPane();
        this.layeredPane.setPreferredSize(new Dimension(width, height));
        this.layeredPane.setBorder(BorderFactory.createTitledBorder("Histogram should go here"));
        this.layeredPane.setLayout(new BorderLayout());

    }

    private void addPanels() {
        this.layeredPane.add(createHistogramPanel(), BorderLayout.CENTER, new Integer(1));
        this.layeredPane.add(createButtonPanel(), BorderLayout.CENTER, new Integer(0));
        this.layeredPane.addComponentListener(new ComponentAdapter() {
        @Override
        public void componentResized(ComponentEvent e) {
            Dimension size = layeredPane.getSize(); // get size
            createHistogramPanel().setSize(size); // push size through
            createButtonPanel().setSize(size); // push size trhough
            // otherChildOfLayers.setSize(size); // push size trhough
            layeredPane.revalidate(); // revalidate to see updates
            layeredPane.repaint(); // "Always invoke repaint after
                                    // revalidate"
        }
    });
    }

    private JPanel createHistogramPanel() {

        JPanel histpanel = new JPanel();

        histpanel.setLayout(new GridLayout(2, 3));
        for (int i = 0; i < layerStrings.length; i++) {
            JLabel label = createColoredLabel(layerStrings[i], layerColors[i]);
            histpanel.add(label);
        }
        histpanel.setOpaque(false);
        histpanel.setBounds(10, 10, width, height);
        return histpanel;
    }

    private JLabel createColoredLabel(String text, Color color) {
        JLabel label = new JLabel("");
        label.setVerticalAlignment(JLabel.TOP);
        label.setHorizontalAlignment(JLabel.CENTER);
        label.setOpaque(true);
        label.setBackground(color);
        label.setForeground(Color.black);
        label.setBorder(BorderFactory.createLineBorder(Color.black));
        label.setPreferredSize(new Dimension(120, 120));
        return label;
    }

    private JPanel createButtonPanel() {
        ButtonGroup buttons = new ButtonGroup();

        JPanel buttonPanel = new JPanel();
        buttonPanel.setLayout(new GridLayout(2, 3));
        for (int i = 0; i < 6; i++) {
            final int placer = i + 1;
            JButton freshButton = new JButton();
            freshButton.addActionListener(e -> {
                System.out.println("Button " + placer + " clicked");
            });

            freshButton.setText("Button " + (i + 1));
            freshButton.setOpaque(true);
            freshButton.setContentAreaFilled(false);
            freshButton.setBorderPainted(false);
            freshButton.setBounds(new Rectangle(132, 75 + (i * 20), 40, 20));
            buttonPanel.add(freshButton, null);
            buttons.add(freshButton);

        }
        buttonPanel.setOpaque(false);

        buttonPanel.setBounds(10, 10, width, height);
        return buttonPanel;
    }

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

        JComponent newContentPane = new FrameDemo();
        newContentPane.setOpaque(true); // content panes must be opaque
        frame.setContentPane(newContentPane);
        frame.setLocationRelativeTo(null);

        frame.pack();

        frame.setVisible(true);
    }

    public static void main(String[] args) {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }

} 

Your code won't work because in componentResized you're creating new panels and applying the size to them. You need to resize the existing panels added to the layered pane. This could be done by assigning histogramPanel and buttonPanel as instance variables.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM