2

我认为 CardLayout 使用 HashMap 来存储它的对(面板和相关的字符串标识符),但是通过 CardLayout 类我注意到它实际上使用了一个 Vector。这就是我的理解:当show调用该方法时,它会循环检查向量的内容,equals以确定这是否是适当卡片的名称,如果是,则循环遍历容器的所有面板要找出当前可见的卡片,它会将其隐藏,然后显示相应的卡片。

如果我正在制作一个有很多不同面板的 gui 应用程序,那么翻转到所需面板不是一种缓慢的技术吗?我应该更好地使用我自己的方式来显示我的面板,比如将它们存储到一个数组中并手动使用add/removesetVisible代替使用 CardLayout 吗?这实际上是我在最终使用 CardLayout 之前开始使用的方式。

4

2 回答 2

3

永远不会成为问题:您通常不会经常在组件之间切换,当您这样做时,扫描一个包含少量组件(通常是 3-100 个?)的列表将花费的时间可以忽略不计其他必须发生的操作(例如绘制新组件)。从性能的角度来看,数据结构的选择基本上是无关紧要的——你可以使用链表而没有人会注意到。

另请注意,HashMap 不适合CardLayout,因为它需要保留卡片的顺序,以便您可以使用first/ next/previous等。

所以基本上,不用担心,也不要浪费时间滚动你自己的 CardLayout 克隆 - CardLayout 工作得很好。

于 2012-09-27T00:35:52.230 回答
1

我在 CardLayout 中没有发现任何性能问题。即使你有 1000 个子组件,它仍然感觉非常快。通过使用上一个/下一个或使用显示,它运行得非常快。

尝试发布重现您的问题的SSCCE,然后我们可以帮助您。下面是一些开始:

import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class TestCardLayout {

    protected void initUI() {
        JFrame frame = new JFrame("test");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        final CardLayout layout = new CardLayout();
        final JPanel panel = new JPanel(layout);
        for (int i = 0; i < 1000; i++) {
            panel.add(new JLabel("Label " + i), getLabelConstraint(i));
        }
        JButton next = new JButton("Next");
        next.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                layout.next(panel);
            }
        });
        JButton previous = new JButton("Previous");
        previous.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                layout.previous(panel);
            }
        });
        final JButton choose = new JButton("Choose");
        choose.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                String value = JOptionPane.showInputDialog(choose, "Enter a number between 0 and 999");
                try {
                    int i = Integer.valueOf(value);
                    if (i > -1 && i < 1000) {
                        layout.show(panel, getLabelConstraint(i));
                    }
                } catch (NumberFormatException e1) {
                    e1.printStackTrace();
                }
            }
        });
        JPanel buttonPanel = new JPanel();
        buttonPanel.add(previous);
        buttonPanel.add(next);
        buttonPanel.add(choose);

        frame.add(buttonPanel, BorderLayout.SOUTH);
        frame.add(panel);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    private String getLabelConstraint(int i) {
        return "ComponentConstraint" + i;
    }

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

            @Override
            public void run() {
                new TestCardLayout().initUI();
            }
        });
    }
}
于 2012-09-26T22:54:10.623 回答