我有一个JComboBox
填充了来自文件(XML)的信息,我希望第二个ComboBox
填充基于第一个选定项目的信息。
我的英语有点生疏所以我会给你看一个例子,这是我的XML文件:
<components>
<house id="Kitchen">
<espresso_machine>C</espresso_machine>
<coffee_machine>C</coffee_machine>
<coffee_pot>C</coffee_pot>
<kettle>C</kettle>
<toaster>C</toaster>
<microwave>C</microwave>
<oven>C</oven>
<frying_pan>C</frying_pan>
<stand_mixer>C</stand_mixer>
<extrator_fan>C</extrator_fan>
<tv>C</tv>
<compact_flurescent>C</compact_flurescent>
<flurescent_tube>C</flurescent_tube>
<dishwasher>C</dishwasher>
<freezer>C</freezer>
<blender>C</blender>
<can_opener>C</can_opener>
<cooking_range>C</cooking_range>
<popcorn_popper>C</popcorn_popper>
</house>
<house id="Laundry">
<washing_machine>C</washing_machine>
<clothes_dryer>C</clothes_dryer>
<vacuum_handler>C</vacuum_handler>
<compact_fluorescent>C</compact_fluorescent>
<iron>C</iron>
</house>
<house id="Room">
<compact_fluorescent>C</compact_fluorescent>
<ac_room>C</ac_room>
<tv>C</tv>
<cell_phone_charger>C</cell_phone_charger>
<clock_radio>C</clock_radio>
</house>
</components>
我的第一个组合框具有属性“id”内容(Kitchen,Laundry,Room)。 第一次打开我的JDialog时,选择了“Kitchen”选项(在第一个组合框中),第二个组合框具有所有子元素限定名称(expresso机器,咖啡机,咖啡壶,水壶等)
当我更改第一个选定项目时,我需要更改第二个组合框的内容。
以下是我的代码示例:
houseSpaceCombo = new JComboBox(configs.XMLreaderDOM4J.readHouseTypeID());
equipmentsCombo = new JComboBox(configs.XMLreaderDOM4J.readHouseEquipmentsID(houseSpaceCombo.getSelectedItem().toString()));
和其他两种方法:
public static String[] readHouseTypeID()
{
Element root = getDoc().getRootElement();
ArrayList<String> attributeAL = new ArrayList<>();
for (Iterator i = root.elementIterator( "house" ); i.hasNext();)
{
Element foo = (Element) i.next();
attributeAL.add(foo.attributeValue("id").toString());
}
String[] vec = convertArrayListToArray(attributeAL);
return vec;
}
public static String[] readHouseEquipmentsID(String selectedItem)
{
Element root = getDoc().getRootElement();
Element innerElement;
ArrayList<String> attributeAL = new ArrayList<>();
for ( Iterator i = root.elementIterator( "house" ); i.hasNext(); ) {
Element element = (Element) i.next();
if(element.attributeValue("id").equals(selectedItem)) {
for ( Iterator j = element.elementIterator(); j.hasNext(); ) {
innerElement = (Element) j.next();
String tmp = innerElement.getQualifiedName().replace("_", " ");
attributeAL.add(tmp);
}
}
}
String[] vec = convertArrayListToArray(attributeAL);
return vec;
}
我该怎么办?
答案 0 :(得分:2)
我会创建一个Map
键入id
属性,其中包含所有子元素的ComboBoxModel
。
当第一个组合框的选择项发生变化时,我会简单地查找Map
中的值,并将第二个组合框的模型设置为检索到的值
示例强>
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.HashMap;
import java.util.Map;
import javax.swing.ComboBoxModel;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class SwitchComboBoxModels {
public static void main(String[] args) {
new SwitchComboBoxModels();
}
public SwitchComboBoxModels() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private Map<String, ComboBoxModel> models;
private JComboBox cbMain;
private JComboBox cbSub;
public TestPane() {
models = new HashMap<>(25);
models.put("Kitchen", createComboBoxModel("espresso_machine",
"coffee_machine",
"coffee_pot",
"kettle",
"toaster",
"microwave",
"oven",
"frying_pan",
"stand_mixer",
"extrator_fan",
"tv",
"compact_flurescent",
"flurescent_tube",
"dishwasher",
"freezer",
"blender",
"can_opener",
"cooking_range",
"popcorn_popper"));
models.put("Laundry", createComboBoxModel("washing_machine",
"clothes_dryer",
"vacuum_handler",
"compact_fluorescent",
"iron"));
ComboBoxModel mainModel = createComboBoxModel("Kitchen", "Laundry");
cbMain = new JComboBox();
cbSub = new JComboBox();
cbMain.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
cbSub.setModel(models.get((String) cbMain.getSelectedItem()));
}
});
cbMain.setModel(mainModel);
cbSub.setModel(models.get((String) cbMain.getSelectedItem()));
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
add(cbMain, gbc);
add(cbSub, gbc);
}
protected ComboBoxModel createComboBoxModel(String... values) {
return new DefaultComboBoxModel(values);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.dispose();
}
}
}
附加示例
从您的示例代码中,您已在内存中拥有该模型。在这个阶段你有两个选择。
您可以通过解析内存文档来构建一系列ComboBoxModel
,或者每次更改时都会动态地从XML构建模型。
我在开始时解析模型并缓存结果,因为XML DOM是内存匮乏
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.util.Map;
import javax.swing.ComboBoxModel;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class SwitchComboBoxModels {
public static void main(String[] args) {
new SwitchComboBoxModels();
}
public SwitchComboBoxModels() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private Document xmlDoc;
private JComboBox cbMain;
private JComboBox cbSub;
private XPathFactory xFactory;
private XPath xPath;
public TestPane() {
try {
readModel();
ComboBoxModel mainModel = createComboBoxModelByID(find("/components/house[@id]"));
cbMain = new JComboBox();
cbSub = new JComboBox();
cbMain.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
updateSubModel();
}
});
cbMain.setModel(mainModel);
updateSubModel();
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
add(cbMain, gbc);
add(cbSub, gbc);
} catch (XPathExpressionException | ParserConfigurationException | SAXException | IOException exp) {
exp.printStackTrace();
}
}
protected void updateSubModel() {
try {
String key = (String) cbMain.getSelectedItem();
Node parent = findFirst("/components/house[@id='" + key + "']");
ComboBoxModel subModel = createComboBoxModel(parent.getChildNodes());
cbSub.setModel(subModel);
} catch (XPathExpressionException exp) {
exp.printStackTrace();
}
}
protected void readModel() throws ParserConfigurationException, SAXException, IOException {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
xmlDoc = factory.newDocumentBuilder().parse(getClass().getResourceAsStream("/Model.xml"));
}
protected NodeList find(String xPathQuery) throws XPathExpressionException {
XPathExpression xExpress = getXPath().compile(xPathQuery);
return (NodeList) xExpress.evaluate(xmlDoc.getDocumentElement(), XPathConstants.NODESET);
}
protected Node findFirst(String xPathQuery) throws XPathExpressionException {
XPathExpression xExpress = getXPath().compile(xPathQuery);
return (Node) xExpress.evaluate(xmlDoc.getDocumentElement(), XPathConstants.NODE);
}
public XPath getXPath() {
if (xPath == null) {
xPath = getXPathFactory().newXPath();
}
return xPath;
}
protected XPathFactory getXPathFactory() {
if (xFactory == null) {
xFactory = XPathFactory.newInstance();
}
return xFactory;
}
public String getAttributeValue(Node nNode, String sAttributeName) {
Node nAtt = nNode.getAttributes().getNamedItem(sAttributeName);
return nAtt == null ? null : nAtt.getNodeValue();
}
protected ComboBoxModel createComboBoxModelByID(NodeList nodeList) {
DefaultComboBoxModel model = new DefaultComboBoxModel();
for (int index = 0; index < nodeList.getLength(); index++) {
Node node = nodeList.item(index);
model.addElement(getAttributeValue(node, "id"));
}
return model;
}
protected ComboBoxModel createComboBoxModel(NodeList nodeList) {
DefaultComboBoxModel model = new DefaultComboBoxModel();
for (int index = 0; index < nodeList.getLength(); index++) {
Node node = nodeList.item(index);
if (node.getNodeType() == 1) {
model.addElement(node.getNodeName());
}
}
return model;
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.dispose();
}
}
}