为什么Swing花了这么长时间来创建这个面板?

时间:2016-01-24 09:34:06

标签: java swing autocomplete swingx

我正在编写我的程序的一部分,在JPanel中插入动态数量的JComboBox,但是我注意到它的速度非常慢(需要大约10秒才能完成),并且它将整个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窗格。在选项卡式窗格中,我正在创建此“库存面板”以适应它。在清单面板中,有一个JGeboBox的“网格”(行和列),其中金额是库存的大小。每个组合框都是自动完成的(打字时),方便使用。

所以我创建了Jpanel,将其设置为MigLayout(使用debug进行可视化调试)。

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

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

WordUtils是Apache的Commons-Lang库的一部分,AutoCompleteDecorator用于JComboBoxes通过SwingX库自动完成。

GameItem只是一个表示游戏项目的对象,其中包含一些小值(短片,字节等......没有任何关于那里)。

我很难知道如何加快速度。

4 个答案:

答案 0 :(得分:2)

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

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

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

我想向Panel添加100个UI组件(类似于JPanel)。这花了很长时间。所以我决定在顶部显示另一个Panel来覆盖Panel(我正在添加内容的那个)。然后我在封面板上贴了一个标签,上面写着&#34; Loading&#34;。通过这种方式,人们会知道它正在加载并且不会吓坏。当然,在生成组件之后我隐藏了封面板

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

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

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

答案 1 :(得分: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 profilerjvisualvm通常位于JDK_HOME/bin

答案 2 :(得分:0)

所以我发现问题并不是特别是渲染问题,而是JComboBox在一定数量上对条目大小造成了荒谬的损失。我向大约50个盒子输入了约4,700件物品,所以它确实受到了性能的打击。

不幸的是,尽管我喜欢使用JComboBox,但我将切换到JTextField ..

答案 3 :(得分:0)

不要使用autocompletedecorator。而是使用此Example: Adding Autocomplete to JTextField