I've got some very old code which uses a Box
to list some information. I create it like so:
Box patterns = Box.createVerticalBox();
Very (very) often, new items are added and old items are removed eg:
label = new JLabel("xyz");
patterns.add(label);
and later
patterns.remove(label);
whenever something is added ore removed I have to have it repaint, so I call:
patterns.revalidate();
patterns.repaint();
Problem is, since this happens very often it chokes up the UI. I think I need a better implementation in order to make it more efficient.
I know I could maintain a list of the active items in the background and then intermittently update the actual UI (batch update) but...
Can someone suggest a more efficient alternative approach?
Why don't you just use a JList
and implement a cell renderer?
Or more flexibility with a JTable
and implement a table cell renderer (returns a Component
instead)?
Based on this example, the following code loafs doing 16 labels at 10 Hz.
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();
}
});
}
}
来源:https://stackoverflow.com/questions/6605554/more-efficient-layout-than-box