Есть ли возможность добавить ScrollPane без отключения CardLayout? - PullRequest
0 голосов
/ 04 октября 2019

У меня есть макет карты, где я переключаю панели с помощью кнопки. Однако код (переключающие панели) работает только при удалении строк:

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

. В другом случае нажатие кнопки ничего не дает. Есть ли возможность сохранить прокрутку (мне это нужно, так как в основном приложении будет много завернутого текста) без отключения опции смены карт?

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");
            }
        });

    }

}

1 Ответ

2 голосов
/ 04 октября 2019

A JFrame (панель содержимого) использует BorderLayout по умолчанию. Это означает, что вы можете иметь только 1 компонент на BorderLayout.CENTER. Когда вы frame.add(component), ограничения по умолчанию составляют BorderLayout.CENTER.

Теперь вы frame.add(mainPanel);, а затем frame.add(scrPane);. Таким образом, основная панель удалена, так как после нее добавляется scrPane.

Выполнение JScrollPane scrPane = new JScrollPane(card1); это означает, что вы добавляете панель прокрутки на card1, а не на панель содержимого. Я думаю, что вы хотите, чтобы это на панели содержимого (весь кадр). Таким образом, исправление заключается в удалении frame.add(mainPanel); и выполнении следующих действий:

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

Теперь основная панель добавляется к scrPane, а scrPane добавляется к кадру.

Однако после этого ваш GUI будет пустым, потому что вы frame.setVisible(true); до того, как закончите добавлять компоненты к нему. Посмотрите на Почему я не должен вызывать setVisible (true) перед добавлением компонентов?

В конце концов, полный код:

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);
    });
}

Несколько хороших ссылок, которые я предлагаюВам нужно прочитать Исходные потоки и Что делает .pack ()?

...