2016-01-24 119 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

相關問題