2016-01-24 115 views
0

我目前正在编写我的程序的一部分,它将动态数量的JComboBoxes插入到JPanel中,但是我注意到它非常慢(需要约10秒才能完成),并且它冻结了整个Swing线程以执行它。我不知道有什么更好的解决方案,但我知道有一个更好的方法。为什么Swing需要花费这么长时间来创建这个面板?

private JPanel createInventoryPanel(PlayerInventory inventory) 
{ 
    JPanel panel = new JPanel(); 
    panel.setLayout(new MigLayout("debug")); 

    int columns = 4; 
    int rows = inventory.getSize()/4; 
    int index = 0; 
    for (int i = 0; i < columns; i++) 
    { 
     for (int j = 0; j < rows; j++) 
     { 
      GameItem item = inventory.getItems().get(index); 

      JComboBox box = new JComboBox(itemNames); 
      box.setEditable(true); 
      AutoCompleteDecorator.decorate(box); 
      box.setSelectedItem(WordUtils.capitalizeFully(item.getName()) + " (0x" + HexUtil.shortToHexString(item.getValue()) + ")"); 

      boolean shouldWrap = ((index + 1) % 4 == 0) && index != 0; 

      panel.add(box, "" + (shouldWrap ? "wrap" : "")); 
      itemBoxes.add(box); 

      index++; 
     } 
    } 

    return panel; 
} 

因此,要解释我的代码:

我有一个JFrame和JTabbed窗格。在标签窗格中,我正在创建这个“库存面板”以适应它。在清单面板中,JComboBoxes有一个“网格”(第&列),其中金额是清单的大小。每个组合框都可以自动完成(打字时)以方便使用。

因此,我创建Jpanel,将其设置为MigLayout(使用调试进行可视化调试)。

有4列(我选择了这个数字) 行的数量取决于库存的大小除以4列。简单的东西。

然后当然我在for循环中使用了for循环来允许我创建jcomboboxes的XY网格。这是它真的很慢的地方。我不确定循环是否缓慢(我怀疑,因为它是简单的算术),或者如果存在线程问题或者是什么......

WordUtils是Apache的Commons-Lang库的一部分,AutoCompleteDecorator用于JComboBoxes通过SwingX库自动完成。游戏项目只是一个表示游戏项目的对象,其中有一些小的值(短裤,字节等等)。

我对如何加快速度感到难以置信。

+3

任何分析器会告诉你比我们的假设更多 – AdamSkywalker

+1

[This SO on SO](http://stackoverflow.com/a/27187624/3676217)可能是你的问题。这是与JTabbedPane和MigLayout。 – lschuetze

+0

@AdamSkywalker问题是如此多的swing对象正在呈现,它非常缓慢......但我不知道另一种方式来做到这一点。 –

回答

2

我认为这是因为你在同一时间创造了太多东西。我认为JComboBox是一件非常复杂的事情。

但是,这不能在另一个线程上完成,因为您正在创建UI组件,这必须在UI线程(主线程)上完成。

我也遇到过这种情况。但那是在创建Windows Forms应用程序时,这是一种完全不同的技术。但我认为基本的想法是一样的。

我想添加100个UI组件到Panel(就像JPanel)。花了很长时间。所以我决定在顶部显示另一个Panel来覆盖Panel(我添加的东西)。然后我在盖板上贴上一个标签,上面写着“加载”。这样,人们就会知道它正在加载并且不会被吓倒。当然,在生成组件后,我隐藏了封面面板

令人惊讶的是,当我运行该程序时,封面面板只出现一小会儿!消失后,我看到所有我想要生成的东西都已经生成了!

所以我提出了一个结论,如果不需要渲染UI组件,它将显得更快。

你应该这样做。在生成组合框时,将JPanel放在另一个的顶部。完成后,再次隐藏面板,或将其完全移除。

+1

使用'CardLayout'来改变视图。 – trashgod

2

这是令人难以置信慢(需要约10秒完成)

首先测量的执行时间。衡量执行时间的一个简单方法是使用System.nanoTime()。改变你的代码是这样的:

long start = System.nanoTime(); 
try { 
    // The code you want to measure 
} finally { 
     long end = System.nanoTime(); 
     long execTime = end - start; 
     System.out.println("Execution of .... took " + execTime + "ns"; 
} 

...或者你使用一个分析器。您可以使用jvisualvm's profiler。通常位于JDK_HOME/bin

+0

我知道什么花费最长时间,但我不知道如何让它变得更快。除了速度慢以外,分析只会告诉我什么。我可以看到问题是绘制这么多的组件,但我没有解决方法。 –

0

所以我发现这个问题并不是一个特定的渲染问题,而是JComboBox对一定数量的入口大小采取了荒谬的收费。我输入了大约4700个物品到50多个箱子,所以它确实带来了性能。

不幸的是,就像我很乐意使用JComboBox时,我会切换到一个JTextField ..

+1

然后[this](https://community.oracle.com/thread/2075329?start=0&tstart=0)可让您一次添加所有项目。 – lschuetze

相关问题