首先,让我讨论一下数据模型:
我在树状对象模型中编译了 HL7 定义,具有 3 个级别:段、元素和子元素。段包含一个列表,元素包含一个列表。它们之间的关系有点像“大陆-乡村-城市”
其次,我创建了一个由 3 个组合框组成的 GUI 组件,每个组合框都有不同的 ComboBoxModel 访问前面描述的对象模型。
我在 ComboBoxModel 上应用了观察者模式,以便每个模型都知道它必须访问哪个 List<>:
- HL7DefinitionElementModel 观察 HL7DefinitionSegmentModel
- HL7DefinitionSubelementModel 观察 HL7DefinitionElementModel
当您在第一个组合框(Segment)中选择一个值时,HL7DefinitionElementModel 会更新并存储已选择的 Segment。数据已正确存储。第一个值正确显示在“关闭”的 JComboBox 中。但是当您尝试打开该 JComboBox(元素)时,如果元素的数量太大(大约 12 个),则调用的弹出菜单中的项目为空白。
我很乐意发布任何代码。如果需要,我可以发送整个项目,但无法将其简化为 SSCEE。
编辑:这是问题的说明
(http://imgur.com/AiJ8mu0)
编辑:这是一个 SSCCE:
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Observable;
import java.util.Observer;
import java.util.Vector;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.event.ListDataListener;
public class Application extends JFrame {
/**
*
*/
private static final long serialVersionUID = -2517616123689799182L;
public Application() {
add(new HL7FieldSelector());
}
public static void main(String[] args) {
Application a = new Application();
a.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
a.setSize(new Dimension(400, 100));
a.setVisible(true);
}
}
class HL7FieldSelector extends JPanel implements ActionListener {
/**
*
*/
private static final long serialVersionUID = 6135074279269049773L;
private JComboBox<HL7DefinitionSegment> segment;
private JComboBox<HL7DefinitionElement> element;
private HL7DefinitionSegmentModel segmentModel;
private HL7DefinitionElementModel elementModel;
public HL7FieldSelector() {
segment = new JComboBox<HL7DefinitionSegment>();
element = new JComboBox<HL7DefinitionElement>();
segmentModel = new HL7DefinitionSegmentModel();
elementModel = new HL7DefinitionElementModel();
segmentModel.addObserver(elementModel);
segment.setModel(segmentModel);
element.setModel(elementModel);
segment.addActionListener(this);
element.addActionListener(this);
initUI();
}
private void initUI() {
this.setLayout(new GridLayout(1, 3));
this.add(segment);
this.add(element);
this.setMinimumSize(new Dimension(500, 30));
this.setPreferredSize(new Dimension(500, 30));
this.setMaximumSize(new Dimension(500, 30));
segment.setMaximumRowCount(10);
element.setMaximumRowCount(10);
}
@Override
public void actionPerformed(ActionEvent arg0) {
setVisible(!isVisible());
setVisible(!isVisible());
}
}
class HL7DefinitionSegment implements Comparable<HL7DefinitionSegment>, Serializable {
/**
*
*/
private static final long serialVersionUID = 7922798285885405647L;
private List<HL7DefinitionElement> elements;
private String name;
public HL7DefinitionSegment(String name, ArrayList<HL7DefinitionElement> elements) {
this.name = name;
this.elements = elements;
}
public HL7DefinitionSegment() {
elements = new Vector<HL7DefinitionElement>();
}
public boolean addElement(HL7DefinitionElement element) {
return elements.add(element);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<HL7DefinitionElement> getElements() {
return elements;
}
@Override
public String toString() {
return this.name;
}
@Override
public int compareTo(HL7DefinitionSegment segment) {
return name.compareTo(segment.getName());
}
}
class HL7DefinitionElement implements Comparable<HL7DefinitionElement>, Serializable {
/**
*
*/
private static final long serialVersionUID = -5344721929162039227L;
private String name;
private String number;
public HL7DefinitionElement(String name, String number) {
this.name = name;
this.number = number;
}
public HL7DefinitionElement() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
@Override
public String toString() {
return number + " " + name;
}
@Override
public int compareTo(HL7DefinitionElement element) {
return number.compareTo(element.getNumber());
}
}
class HL7DefinitionModel implements Serializable {
/**
*
*/
private static final long serialVersionUID = -8180582371776223436L;
private List<HL7DefinitionSegment> segments;
private static HL7DefinitionModel _instance;
public HL7DefinitionModel(Vector<HL7DefinitionSegment> segments) {
this.segments = segments;
}
public HL7DefinitionModel() {
segments = new Vector<HL7DefinitionSegment>();
}
public boolean addSegment(HL7DefinitionSegment segment) {
return segments.add(segment);
}
public List<HL7DefinitionSegment> getSegments() {
return segments;
}
public void setSegments(List<HL7DefinitionSegment> segments) {
this.segments = segments;
}
public static HL7DefinitionModel getInstance() {
if (_instance == null) {
_instance = new HL7DefinitionModel();
for (int i = 0; i < 2; i++) {
HL7DefinitionSegment s = new HL7DefinitionSegment();
s.setName("SEG" + i);
for (int j = 0; j < 20; j++) {
s.addElement(new HL7DefinitionElement("" + j + j + j, "" + j));
}
_instance.addSegment(s);
}
}
return _instance;
}
}
class HL7DefinitionSegmentModel extends Observable implements javax.swing.ComboBoxModel<HL7DefinitionSegment> {
private HL7DefinitionModel model;
private HL7DefinitionSegment selectedItem;
public HL7DefinitionSegmentModel() {
this.model = HL7DefinitionModel.getInstance();
this.selectedItem = getElementAt(0);
}
public void addListDataListener(ListDataListener l) {}
public void removeListDataListener(ListDataListener l) {}
@Override
public HL7DefinitionSegment getElementAt(int index) {
return model.getSegments().get(index);
}
@Override
public int getSize() {
return model.getSegments().size();
}
@Override
public Object getSelectedItem() {
return selectedItem;
}
@Override
public void setSelectedItem(Object anItem) {
this.selectedItem = (HL7DefinitionSegment) anItem;
setChanged();
notifyObservers();
}
}
class HL7DefinitionElementModel extends Observable implements javax.swing.ComboBoxModel<HL7DefinitionElement>, Observer {
private HL7DefinitionSegment segment;
private HL7DefinitionElement selectedItem;
public HL7DefinitionElementModel() {
this.segment = null;
}
@Override
public void update(Observable o, Object arg1) {
if (o instanceof HL7DefinitionSegmentModel) {
segment = (HL7DefinitionSegment) ((HL7DefinitionSegmentModel) o).getSelectedItem();
setSelectedItem(getElementAt(0));
}
}
public void addListDataListener(ListDataListener l) {}
public void removeListDataListener(ListDataListener l) {}
@Override
public HL7DefinitionElement getElementAt(final int index) {
return segment.getElements().get(index);
}
@Override
public int getSize() {
return (segment != null ? segment.getElements().size() : 0);
}
@Override
public Object getSelectedItem() {
return selectedItem;
}
@Override
public void setSelectedItem(Object anItem) {
this.selectedItem = (HL7DefinitionElement) anItem;
setChanged();
notifyObservers();
}
}
要重现错误:
- 启动应用程序
- 单击第二个组合框
- 单击第一个,选择选项 2
- 单击第二个组合框
- 注意列表如何为空
如果您这样做:
- 启动应用程序
- 单击第一个组合框,选择选项 2
- 单击第二个组合框
- 注意列表的填充方式
编辑:这是我发现的其他内容:只有在弹出菜单中的元素多于初始“填充”时,弹出菜单才为空白。也就是说,如果组合框在第一次选择中填充了 20 个元素,那么在下一次选择中,如果元素数量为 21 或更多,则弹出菜单将为空白,如果元素数量为 20 或更少,则显示。