我有一個方法,可以遞歸地啓用/禁用JPanel
內的所有組件。也有例外列表。所以,我可以做以下JSpinner與其他鞦韆組件有什麼不同?
- 禁用所有組件
panel1
除了textfield1, textfield3
誰應該被啓用。 - 啓用
panel2
中的所有組件,但應禁用button2, label3
的應用程序除外。
這裏是一個SSCCE這正是這麼做的:
import java.awt.Component;
import java.awt.Container;
import java.awt.GridLayout;
import java.util.HashSet;
import java.util.Set;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.JTextField;
import javax.swing.SpinnerNumberModel;
public class Main {
public static void main(String[] args) {
JFrame frame = new JFrame();
final JPanel panel = new JPanel(new GridLayout(3, 3));
final JTextField textfield = new JTextField("asdf");
final JButton button = new JButton("asdf");
final JCheckBox checkbox = new JCheckBox("asdf");
final JSpinner spinner = new JSpinner(new SpinnerNumberModel(1, 1, 100, 1));
final JLabel label = new JLabel("asdf");
panel.add(textfield);
panel.add(button);
panel.add(checkbox);
panel.add(spinner);
panel.add(label);
// fill in some random stuff
for (int i = 0; i < 4; i++)
panel.add(new JLabel("asdf"));
frame.setContentPane(panel);
frame.setSize(300, 100);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
new Thread(new Runnable() {
@Override
public void run() {
boolean toggle = true;
while (true) {
toggle = !toggle;
Set<Component> enableList = new HashSet<Component>();
Set<Component> disableList = new HashSet<Component>();
enableList.add(textfield);
enableList.add(spinner);
disableList.add(checkbox);
setEnableAllRec(panel, toggle, disableList, enableList);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {}
}
}
}).start();
frame.setVisible(true);
}
public static void setEnableAllRec(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) setEnableAllRec((Container) c, defaultState, disableList, enableList);
}
}
}
的SSCCE將所有組件每秒啓用/禁用交替。除了一些應始終啓用的組件以及一些始終應禁用的組件。除了JSpinner
以外,這種方法非常有效。它被檢測爲一個組件,但在列表中找不到(因此不作爲特殊情況處理)。我嘗試過的所有其他揮杆組件都按預期工作。
你能告訴我JSpinner
怎麼了?
我希望SSCCE是不是太混亂...;)
奇。如果我在「setEnableAllRec」入口處添加一個顯示'disableList'和'enableList'中的項目數的打印語句,它會在多次調用後降爲零。而且這些電話的發生頻率比每秒一次更多。我想知道是否有一些併發問題在這裏發生。 –
'setEnableAllRec'方法被多次調用,因爲它是遞歸的。但是你是對的,在線程調用完成後列表是空的。紀堯姆的回答實際上解釋了這一點。謝謝你的時間。 :) – brimborium
啊,當然。很明顯,我的大腦並沒有運作得更早。 –