более эффективный макет, чем Box - PullRequest
3 голосов
/ 07 июля 2011

У меня есть очень старый код, который использует Box, чтобы перечислить некоторую информацию. Я создаю это так:

Box patterns = Box.createVerticalBox();

Очень (очень) часто новые элементы добавляются, а старые элементы удаляются, например:

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

и позже

patterns.remove(label);

всякий раз, когда что-то добавляется или удаляется, я должен перекрасить его, поэтому я звоню:

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

Проблема в том, что, так как это происходит очень часто, это душит интерфейс. Я думаю, что мне нужна лучшая реализация, чтобы сделать ее более эффективной.

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

Может кто-нибудь предложить более эффективный альтернативный подход?

Ответы [ 2 ]

6 голосов
/ 07 июля 2011

Почему бы вам просто не использовать JList и реализовать средство визуализации ячеек ?

Или более гибко с JTable и реализовать средство визуализации ячеек таблицы (вместо него возвращается Component)?

3 голосов
/ 07 июля 2011

Исходя из этого примера , следующий код генерирует 16 меток при 10 Гц.

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