【问题标题】:CardLayout performance?CardLayout 性能?
【发布时间】:2012-09-26 21:42:23
【问题描述】:

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

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

【问题讨论】:

  • 如果您随机获取组件,则与散列相比相对慢,但如果您按顺序获取它们,则速度很快。话虽如此,它的性能仍然非常快。您确定通过使用分析这会导致您的 GUI 的实际和感知性能出现重大瓶颈吗?如果没有,那么我们只是在讨论可以在针头上跳舞的天使的数量。
  • 不,我没有尝试测量它,但它似乎比手动方式慢很多,反正也没那么复杂。如果我们按顺序获取组件,为什么会很快?如果我目前在第 18 张牌,我想拿到第 19 张牌,show 方法还是会从头开始循环(两次),还是不循环?
  • 好吧,我明白你的意思了,你可能在谈论 next() 但这也会遍历组件,直到找到合适的组件。它只循环一次而不是两次。
  • 如果你真的担心CardLayout 的性能,你可以自己动手,使用Map<String, Component>BorderLayout,就像气垫船指出的那样,除非你'真的看到开关之间的速度大幅下降(这与重绘问题无关),为什么还要麻烦:P
  • 嗯,我还没有为我的应用程序使用 50 个面板,但是当我这样做时,也许我会回到我自己的方式来展示它们。我只是认为 CardLayout 有一个重要的好处(除了简单性)我在这里错过了,这就是我问的原因......

标签: java swing vector jpanel cardlayout


【解决方案1】:

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

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

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

【讨论】:

  • 我明白了...由于解释清楚,我将接受的答案更改为这个答案。
【解决方案2】:

我在 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();
            }
        });
    }
}

【讨论】:

  • 我实际上没有问题...我只是在制作一个将使用大量面板的应用程序,当我看到时我正在考虑回到我显示面板的旧方式CardLayout 如何管理卡片之间的翻转。在我看来,这很慢,仅此而已......就像我在评论中所说的那样,我认为 CardLayout 还有其他好处,除了简单之外,我错过了。根据 cmets 和您的回答,我猜即使(理论上)速度较慢,也无法察觉。
猜你喜欢
  • 1970-01-01
  • 2014-04-17
  • 1970-01-01
  • 1970-01-01
  • 2014-02-16
  • 1970-01-01
  • 1970-01-01
  • 2013-12-09
  • 1970-01-01
相关资源
最近更新 更多