0

I have a card layout where I switch panels with a button. However, the code (switching panels) works only when lines:

    JScrollPane scrPane = new JScrollPane(card1);
    frame.add(scrPane);

are removed. In other case, clicking button achieves nothing. Is there an option to keep the scrolling (I need this, since the main application will have a lot of wrapped text) without disabling an option to switch cards?

package com.code;

import javax.swing.*;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.awt.event.*;

public class Card {

    public static void main(String[] args) {

        JFrame frame = new JFrame("App");
        frame.setVisible(true);
        frame.setSize(1200, 800);//Give it a size
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

        JPanel mainPanel = new JPanel(new CardLayout());
        frame.add(mainPanel);

        JPanel menu = new JPanel(new FlowLayout(FlowLayout.LEFT));
        JPanel card1 = new JPanel(new FlowLayout(FlowLayout.LEFT));
        JPanel card2 = new JPanel(new FlowLayout(FlowLayout.LEFT));

        mainPanel.add(menu, "menu");
        mainPanel.add(card1, "card1");
        mainPanel.add(card2, "card2");

        JLabel l1 = new JLabel("label 1");
        JLabel l2 = new JLabel("label 2");
        card1.add(l1);
        card2.add(l2);
        JButton click = new JButton("Click!");
        menu.add(click);

        JScrollPane scrPane = new JScrollPane(card1);
        frame.add(scrPane);

        click.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                CardLayout cardLayout = (CardLayout) mainPanel.getLayout();
                cardLayout.show(mainPanel, "card1");
            }
        });

    }

}
George Z.
  • 6,643
  • 4
  • 27
  • 47
Ambu
  • 174
  • 3
  • 15

1 Answers1

2

A JFrame (its content pane) uses BorderLayout by default. That means you can have only 1 component at BorderLayout.CENTER. When you frame.add(component) the default constraints is BorderLayout.CENTER.

Now, you frame.add(mainPanel); and then frame.add(scrPane);. So main panel is removed, since scrPane is being added after it.

Doing JScrollPane scrPane = new JScrollPane(card1); it means you add a scrollpane to card1, and not in content pane. I guess that you want it to the content pane (the whole frame). So the fix is to delete frame.add(mainPanel); and do the following:

JScrollPane scrPane = new JScrollPane(mainPanel);
frame.add(scrPane);

Now, the main panel is added to scrPane and scrPane is added to the frame.

However, your GUI will be empty after that, because you frame.setVisible(true); before you are finished adding components to it. Take a look at Why shouldn't I call setVisible(true) before adding components?

Eventually, full code is:

public static void main(String[] args) {
    SwingUtilities.invokeLater(() -> {
        JFrame frame = new JFrame("App");

        frame.setSize(1200, 800);//Give it a size
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

        JPanel mainPanel = new JPanel(new CardLayout());

        JPanel menu = new JPanel(new FlowLayout(FlowLayout.LEFT));
        JPanel card1 = new JPanel(new FlowLayout(FlowLayout.LEFT));
        JPanel card2 = new JPanel(new FlowLayout(FlowLayout.LEFT));

        mainPanel.add(menu, "menu");
        mainPanel.add(card1, "card1");
        mainPanel.add(card2, "card2");

        JLabel l1 = new JLabel("label 1");
        JLabel l2 = new JLabel("label 2");
        card1.add(l1);
        card2.add(l2);
        JButton click = new JButton("Click!");
        menu.add(click);

        JScrollPane scrPane = new JScrollPane(mainPanel);
        frame.add(scrPane);

        click.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                CardLayout cardLayout = (CardLayout) mainPanel.getLayout();
                cardLayout.show(mainPanel, "card1");
            }
        });
        frame.setVisible(true);
    });
}

Some good links I suggest you to read are the Initial Threads and What does .pack() do?

George Z.
  • 6,643
  • 4
  • 27
  • 47
  • 1
    Thanks for the help and thorough explanation! I'll definitely check the links and give them hopefully a successful try. – Ambu Oct 04 '19 at 18:33