【问题标题】:more efficient layout than Box比 Box 更高效的布局
【发布时间】:2011-07-07 03:41:27
【问题描述】:

我有一些非常古老的代码,它使用Box 列出一些信息。我是这样创建的:

Box patterns = Box.createVerticalBox();

非常(非常)经常,添加新项目并删除旧项目,例如:

label = new JLabel("xyz");
patterns.add(label);

以后

patterns.remove(label);

每当添加或删除某些东西时,我都必须重新粉刷,所以我打电话:

patterns.revalidate();
patterns.repaint();

问题是,由于这种情况经常发生,它会阻塞 UI。我认为我需要一个更好的实现来提高效率。

我知道我可以在后台维护一个活动项目列表,然后间歇性地更新实际的 UI(批量更新)但是......

有人可以提出更有效的替代方法吗?

【问题讨论】:

    标签: java swing layout-manager


    【解决方案1】:

    为什么不直接使用JList 并实现cell renderer

    或者更灵活地使用JTable 并实现table cell renderer(改为返回Component)?

    【讨论】:

    • 我已更改为使用JList + DefaultListModel 和扩展DefaultListCellRenderer,标记它生成的JLabel。效率约为 1000 *。谢谢。
    • @pstanton JList 和 JTable 默认返回 JLabel @Yanick Rochon +1
    • @mKorbel:default cell renderers 的优点。
    • @pstanton,确实如此! DefaultListCellRendererDefaultTableCellRenderer 类扩展 JLabel,感谢您的精确!
    • 是的,最大的性能增强可能是 JList 和 JTable 使用的“冲压”方法。在这里利用它可能是给我最大的改进。
    【解决方案2】:

    基于此example,以下代码以 10 Hz 执行 16 个标签。

    import java.awt.EventQueue;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.List;
    import javax.imageio.ImageIO;
    import javax.swing.Box;
    import javax.swing.BoxLayout;
    import javax.swing.ImageIcon;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.Timer;
    
    /** @see https://stackoverflow.com/questions/6605554 */
    public class ImageLabelPanel extends Box implements ActionListener {
    
        private static final int N = 16;
        private final List<JLabel> list = new ArrayList<JLabel>();
        private final Timer timer = new Timer(100, this);
    
        ImageLabelPanel() {
            super(BoxLayout.Y_AXIS);
            BufferedImage bi = null;
            try {
                bi = ImageIO.read(new File("image.jpg"));
            } catch (IOException e) {
                e.printStackTrace(System.err);
            }
            for (int r = 0; r < N; r++) {
                int w = bi.getWidth();
                int h = bi.getHeight() / N;
                BufferedImage b = bi.getSubimage(0, r * h, w, h);
                list.add(new JLabel(new ImageIcon(b)));
            }
            createPane();
            JFrame f = new JFrame();
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            f.add(this);
            f.pack();
            f.setVisible(true);
            timer.start();
        }
    
        private void createPane() {
            this.removeAll();
            for (JLabel label : list) {
                add(label);
            }
            this.revalidate();
        }
    
        @Override
        public void actionPerformed(ActionEvent e) {
            Collections.shuffle(list);
            createPane();
        }
    
        public static void main(String[] args) {
            EventQueue.invokeLater(new Runnable() {
    
                @Override
                public void run() {
                    new ImageLabelPanel();
                }
            });
        }
    }
    

    【讨论】:

    • 我觉得不是布局问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-06
    • 1970-01-01
    • 2020-09-12
    • 2010-10-01
    • 2021-05-16
    相关资源
    最近更新 更多