优化一个 JPanel 中的数千个 JPanel
Optimising thousands of JPanels in a JPanel
我在将大约 4000 个新创建的 JPanel
组件添加到现有面板的优化方面遇到了问题。
问题在于,令人惊讶的是,它非常慢。将它们全部添加完需要将近 10 秒,这对我来说很慢。
public static void main(String[] args) {
JMenuItem mntmGenerateRandom = new JMenuItem("Generate random int");
mntmGenerateRandom.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
Random rand = new Random();
for(int i = 0; i < 4000; i++){
intPositions.add(rand.nextInt(4000));
System.out.println(i);
}
quicksort(0, intPositions.size()-1, intPositions);
long start = System.currentTimeMillis();
repaintPanels();
long stop = System.currentTimeMillis();
System.out.println("Done in " + (stop-start) + "ms");
}
});
}
private void repaintPanels(){
panelArray.clear();
ExecutorService service = Executors.newWorkStealingPool();
service.submit(new Runnable() {
public void run() {
for(int i = 0; i < intPositions.size(); i++){
panelArray.add(i, new JPanel());
panelArray.get(i).setBounds(intPositions.get(i), 1, 1, panelParent.getHeight()-2);
panelParent.add(panelArray.get(i), 1);
}
}
});
panelParent.repaint();
panelParent.revalidate();
}
这是简化的代码,删除了所有不必要的内容。最慢的部分是当我调用 panelParent.add(panelArray.get(i), 1);
谁能帮我让它更快(如果可能的话)?
改用 JTable。它可以使用一个 JComponent 子组件(如 JPanel)绘制所有单元格,使用 CellRenderer 和 CellEditor。
这是一个fly weight模式,您也可以自己实现:在一个JPanel中绘制所有"panels."
如果 Joop 要猜测一个解决方案,那么我也会。
正如我在评论中指出的那样,JPanel 通常用作 容器 作为包含其他组件的组件,您似乎没有将它用于此目的,但而是(在我看来——但在您为我们澄清您的问题之前我不能 100% 确定)绘制图像。如果是这样,如果你想做的是绘制块或链接的变化图像,一个随着你的排序算法(或你在模型中尝试做的任何事情)的变化而变化的图像,那么为什么不使用单个绘图 JPanel,其 paintComponent 已被覆盖,并且其 paintComponent 在模型更改时绘制模型的状态。这也 比您想要达到的重量轻很多。
我在将大约 4000 个新创建的 JPanel
组件添加到现有面板的优化方面遇到了问题。
问题在于,令人惊讶的是,它非常慢。将它们全部添加完需要将近 10 秒,这对我来说很慢。
public static void main(String[] args) {
JMenuItem mntmGenerateRandom = new JMenuItem("Generate random int");
mntmGenerateRandom.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
Random rand = new Random();
for(int i = 0; i < 4000; i++){
intPositions.add(rand.nextInt(4000));
System.out.println(i);
}
quicksort(0, intPositions.size()-1, intPositions);
long start = System.currentTimeMillis();
repaintPanels();
long stop = System.currentTimeMillis();
System.out.println("Done in " + (stop-start) + "ms");
}
});
}
private void repaintPanels(){
panelArray.clear();
ExecutorService service = Executors.newWorkStealingPool();
service.submit(new Runnable() {
public void run() {
for(int i = 0; i < intPositions.size(); i++){
panelArray.add(i, new JPanel());
panelArray.get(i).setBounds(intPositions.get(i), 1, 1, panelParent.getHeight()-2);
panelParent.add(panelArray.get(i), 1);
}
}
});
panelParent.repaint();
panelParent.revalidate();
}
这是简化的代码,删除了所有不必要的内容。最慢的部分是当我调用 panelParent.add(panelArray.get(i), 1);
谁能帮我让它更快(如果可能的话)?
改用 JTable。它可以使用一个 JComponent 子组件(如 JPanel)绘制所有单元格,使用 CellRenderer 和 CellEditor。
这是一个fly weight模式,您也可以自己实现:在一个JPanel中绘制所有"panels."
如果 Joop 要猜测一个解决方案,那么我也会。
正如我在评论中指出的那样,JPanel 通常用作 容器 作为包含其他组件的组件,您似乎没有将它用于此目的,但而是(在我看来——但在您为我们澄清您的问题之前我不能 100% 确定)绘制图像。如果是这样,如果你想做的是绘制块或链接的变化图像,一个随着你的排序算法(或你在模型中尝试做的任何事情)的变化而变化的图像,那么为什么不使用单个绘图 JPanel,其 paintComponent 已被覆盖,并且其 paintComponent 在模型更改时绘制模型的状态。这也 比您想要达到的重量轻很多。