GridLayout内容未显示

时间:2016-09-12 10:28:08

标签: java swing layout-manager grid-layout cardlayout

我有Jpanel,它会在两个视图中显示组件。网格视图和卡片视图。

卡片视图工作正常。但是当选择gridView时,不会显示组件。

enter image description here

MCVE

SourceContainer.java

import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.Box.Filler;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JToolBar;

public class SourceContainer extends JPanel implements ActionListener {

    JPanel sourceMainPanel;

    SourceCardPanel sourceCardPanel;
    SourceGridPanel sourceGridPanel;

    List<JComponent> components;

    Boolean cardView = true;

    public SourceContainer() {
        init();
        components = new ArrayList<>();
    }

    private void init() {
        setLayout(new BorderLayout());
        loadTitleComp();
        loadBodyPanel();
    }

    private void loadTitleComp() {
        JToolBar toolBar = new JToolBar();
        toolBar.setFloatable(false);
        toolBar.add(new Filler(new Dimension(), new Dimension(), new Dimension(10000, 10000)));
        toolBar.add(new Filler(new Dimension(35, 0), new Dimension(35, 0), new Dimension(10000, 10000)));

        JLabel label = new JLabel("Source");
        label.setFont(label.getFont().deriveFont(Font.BOLD, 14));
        toolBar.add(label);

        toolBar.add(new Filler(new Dimension(), new Dimension(), new Dimension(10000, 10000)));

        JButton button = new JButton("Switch");
        button.setActionCommand("SwitchView");
        button.addActionListener(this);
        toolBar.add(button);
        add(toolBar, BorderLayout.NORTH);
    }

    private void loadBodyPanel() {
        sourceMainPanel = new JPanel(new CardLayout());

        sourceCardPanel = new SourceCardPanel();
        sourceGridPanel = new SourceGridPanel();

        sourceMainPanel.add(sourceCardPanel, "Card");
        sourceMainPanel.add(sourceGridPanel, "Grid");

        add(sourceMainPanel, BorderLayout.CENTER);
    }

    public void addSourceComp(String name, JComponent comp) {
        JScrollPane scrollPane = new JScrollPane(comp);
        scrollPane.setName(name);
        components.add(scrollPane);
    }

    public void load() {
        switchView();
    }

    @Override
    public void actionPerformed(ActionEvent ae) {
        switch (ae.getActionCommand()) {
            case "SwitchView":
                cardView = !cardView;
                switchView();
                break;
            default:
                throw new UnsupportedOperationException();
        }
    }

    private void switchView() {
        CardLayout layout = (CardLayout) sourceMainPanel.getLayout();
        String cardName;
        if (cardView) {
            cardName = "Card";
            sourceCardPanel.loadCards();
        } else {
            sourceGridPanel.loadGrid();
            cardName = "Grid";
        }
        layout.show(sourceMainPanel, cardName);
    }

    class SourceCardPanel extends JPanel implements ActionListener {

        JPanel sourcePanel;
        CardLayout cardLayout;

        JLabel sourceLabel;

        public SourceCardPanel() {
            setLayout(new BorderLayout());
            cardLayout = new CardLayout();
            sourcePanel = new JPanel(cardLayout);
            sourceLabel = new JLabel("Soruce Project");
            init();
        }

        private void init() {
            JToolBar toolBar = new JToolBar();
            toolBar.setFloatable(false);

            toolBar.add(new Filler(new Dimension(), new Dimension(), new Dimension(10000, 10000)));

            JButton lbutton = new JButton("<<<");
//                    IconUtils.getIconByResourceName("goPrevious"));
            lbutton.setActionCommand("GoToLeft");
            lbutton.addActionListener(this);
            toolBar.add(lbutton);

            toolBar.add(sourceLabel);

            JButton rbutton = new JButton(">>>");
//                    IconUtils.getIconByResourceName("goNext"));
            rbutton.setActionCommand("GoToRight");
            rbutton.addActionListener(this);
            toolBar.add(rbutton);

            toolBar.add(new Filler(new Dimension(), new Dimension(), new Dimension(10000, 10000)));

            add(toolBar, BorderLayout.NORTH);
            add(sourcePanel, BorderLayout.CENTER);
        }

        public void addCard(JComponent comp) {
            sourcePanel.add(comp, comp.getName());
        }

        private JComponent getCurrentCard() {
            for (Component comp : sourcePanel.getComponents()) {
                if (comp.isVisible()) {
                    return (JComponent) comp;
                }
            }
            return null;
        }

        public void loadCards() {
            sourcePanel.removeAll();
            for (JComponent component : components) {
                addCard(component);
            }
            sourceLabel.setText(components.get(0).getName());
        }

        @Override
        public void actionPerformed(ActionEvent ae) {
            switch (ae.getActionCommand()) {
                case "GoToLeft":
                    cardLayout.previous(sourcePanel);
                    break;
                case "GoToRight":
                    cardLayout.next(sourcePanel);
                    break;
            }
            sourceLabel.setText(getCurrentCard().getName());
        }

    }

    class SourceGridPanel extends JPanel {

        JPanel gridpanel;

        public SourceGridPanel() {
            setLayout(new BorderLayout());
            gridpanel = new JPanel(new GridLayout());
            add(new JScrollPane(gridpanel), BorderLayout.CENTER);
        }

        public void loadGrid() {
            gridpanel.removeAll();
            for (int i = 0; i < components.size(); i++) {
                create(components.get(i), i);
            }
        }

        private void create(JComponent comp, int index) {
            JPanel panel = new JPanel(new BorderLayout());
            JToolBar toolBar = new JToolBar();
            toolBar.setFloatable(false);
            toolBar.add(new JLabel(comp.getName()));
            panel.add(toolBar, BorderLayout.NORTH);
            panel.add(comp, BorderLayout.CENTER);
            gridpanel.add(panel, index);
        }
    }
}

Test.java

import java.awt.BorderLayout;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.JTree;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import merge.container.SourceContainer;

public class Test extends JFrame {

    public Test() {
        init();
    }

    private void init() {
        SourceContainer sc = new SourceContainer();
        for (int i = 0; i < 5; i++) {
            sc.addSourceComp("Sample " + i, new JTree(new Object[]{i}));
        }
        sc.load();
        add(sc, BorderLayout.CENTER);
    }

    public static void main(String[] args) {
        setUpUI("Nimbus");
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                Test samp = new Test();
                samp.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                samp.setTitle("Tree Test");
                samp.setSize(600, 500);
                samp.setLocationRelativeTo(null);
                samp.setVisible(true);
            }
        });
    }

    private static void setUpUI(String ui) {
        try {
            for (UIManager.LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
                if (ui.equals(info.getName())) {
                    UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
            Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

}

2 个答案:

答案 0 :(得分:2)

在loadGrid()中将循环更改为:

for (int i = 0; i < components.size(); i++) {
    create(components.get(i), i);
    components.get(i).setVisible(true);
}

编辑:我意识到我提供了一个解决方案而没有提供完整的答案,所以为了完整起见:

CardLayout通过修改其管理的组件的可见性,一次显示1个组件。文档说明了这一点,虽然它并没有真正强调它(在大多数文档中它使用像&#34; Flip&#34;这样的术语):

https://docs.oracle.com/javase/8/docs/api/java/awt/CardLayout.html

  

Java 8 - CardLayout

     

一次只能看到一张卡片,而容器则充当一叠卡片。添加到CardLayout对象的第一个组件是首次显示容器时的可见组件。

以下是显示此行为的示例:

public static void main(String[] args){
    ArrayList<JComponent> components = new ArrayList<>();
    components.add(new JPanel());
    components.add(new JPanel());
    components.add(new JPanel());

    System.out.println("Component Visibility Prior to Card Layout:");
    showVisibilityStatus(components);

    JPanel cardPane = new JPanel(new CardLayout());
    for (JComponent component : components){
        cardPane.add(component);
    }

    System.out.println("\nComponent Visibility After Card Layout:");
    showVisibilityStatus(components);
}

public static void showVisibilityStatus(ArrayList<JComponent> components){
    for (JComponent component : components){
        System.out.println(component.isVisible());
    }
}

控制台输出为:

Component Visibility Prior to Card Layout:
true
true
true

Component Visibility After Card Layout:
true
false
false

因此,当使用CardLayout将已放置在面板中的组件移动到使用不同布局的另一个面板(例如GridLayout)时,可能需要明确设置这些组件的可见性。

答案 1 :(得分:0)

过去在打包和显示所有内容后删除和添加组件时遇到了麻烦。重新加载循环中的组件后,您尝试了

gridpanel.revalidate();
gridpanel.repaint();