2012-05-11 21 views
0

我有一個廣泛的Gui,其中包含許多組件。有一個updateEnable()方法根據某些配置更新所有組件的啓用狀態。Java Swing:防止組件更新啓用狀態,直到我告訴它們爲

我基本上第一次設置其啓動狀態爲true,然後禁用其中一些(根據配置):

private void updateEnable() { 
    enableAllRec(panel, true); 
    // disable some components 
} 

private void enableAllRec(Container root, boolean b) { 
    if (root == null) return; 
    for (Component c : root.getComponents()) { 
    c.setEnabled(b); 
    if (c instanceof Container) enableAllRec((Container) c, b); 
    } 
} 

我那樣做的原因是,一些部件不被存儲爲成員變量,我沒有訪問它們。然而,他們可以改變自己的狀態,因爲我初始化它們中的一些像這樣(例如):

final JLabel exampleLabel = new JLabel("yoink"); 
final JCheckBox exampleCheckBox = new JCheckBox("boing"); 
exampleCheckBox.addItemListener(new ItemListener() { 
    @Override 
    public void itemStateChanged(ItemEvent e) { 
    exampleLabel.setEnable(exampleCheckBox.isSelected()); 
    } 
}); 

現在我的問題是這樣的:當我打電話updateEnable(),一些(存儲)組件可能會閃爍,因爲它們是啓用並在一段時間後再次禁用。我想阻止這一點。我的想法是以某種方式防止GUI刷新,直到updateEnable()的末尾,然後執行updateUI()。但這不是很優雅,我不知道如何防止更新GUI。

我是否缺少這個問題的一個非常優雅的替代解決方案?

非常感謝, 斯特凡

+1

你可以找到你的答案[這裏](http://stackoverflow.com/questions/4065456/prevent-java-from-repainting-the-content-of-a-jpanel-while-updating)。 – Grims

+0

謝謝,那正是我正在尋找的。我想起了一種更優雅的方式。如果效果很好,我會發佈一個答案。 – brimborium

+0

好吧,我剛剛發佈我的當前解決方案,並接受它,因爲它似乎對我工作得很好。 mgarins緩存想法也是一種可能性,儘管我不喜歡創建包含我的gui的每個組件的Map。我的方法只會創建一套我認爲更好的特例。 – brimborium

回答

0

好的,我的方法似乎工作。我只是延長了​​3210包括一些例外:

private void enableAllRec(Container root, boolean defaultState, Set<Component> disableList, Set<Component> enableList) { 
    if (root == null) return; 
    for (Component c : root.getComponents()) { 
    if (disableList != null && disableList.contains(c)) { 
     c.setEnabled(false); 
     disableList.remove(c); 
    } else if (enableList != null && enableList.contains(c)) { 
     c.setEnabled(true); 
     enableList.remove(c); 
    } else c.setEnabled(defaultState); 
    if (c instanceof Container) enableAllRec((Container) c, defaultState, disableList, enableList); 
    } 
} 

這樣一來,我可以determen的一切,我希望有啓用/禁用肯定的成分,將它們添加到其相應的設置和thenn致電enableAllRec。例如:

Set<Component> enableList = new HashSet<Component>(); 
enableList.add(searchFreqButton); 
enableList.add(advMeasButton); 
enableAllRec(configPanel, false, null, enableList); 

顯然,這是不理想的大集,但它足以滿足我的需求(800個以防萬一元件及裝置包含不超過20-30以防萬一組件)。我懷疑這種方法也可以輕鬆處理更大的集合。

在上面的例子中,引入一個disableList是沒有意義的(因爲所有的組件在默認情況下都會被禁用)。因此,根據默認值,可以省略相應的設置。當然,這應該優先在enableAllRec()中完成。

1

如果您的組件可能啓用/禁用連續由於一些邏輯上的變化,並計算了幾次 - 你應聘的一些變化,以視覺之前應執行計算組件。在這種情況下,您會將組件狀態直接更改爲最終狀態。

+0

這裏的問題是,除了通過'Container.getComponents()',我沒有訪問其中的一些。 – brimborium

+1

要麼使它在兩次運行中,要麼將最終狀態緩存到像Map 之類的映射中,然後在該映射之後運行該映射,將最終值設置爲組件的setEnabled方法。 –

+0

雖然它會創建我所有組件的Map,但我認爲這並不是必需的,因爲它們大多數都使用'enableAllRec()'默認設置很好,所以緩存想法也不錯。 – brimborium

相關問題