我的代码实际上非常简单。我看到一个简单而类似的代码来自this article。
首先,我有1个组合框。我有一个名为 itemStateChanged()的监听器。我加入这个监听器的目的是: " 在用户点击(选择)其投放箱中的项目时执行某些代码"。
Cmb_ItemCategory = new javax.swing.JComboBox();
Cmb_ItemCategory.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Loading..." }));
Cmb_ItemCategory.addItemListener(new java.awt.event.ItemListener() {
public void itemStateChanged(java.awt.event.ItemEvent evt) {
Cmb_ItemCategoryItemStateChanged(evt);
}
});
private void Cmb_ItemCategoryItemStateChanged(java.awt.event.ItemEvent evt) {
if(evt.getStateChange() == java.awt.event.ItemEvent.SELECTED){
System.err.println("Sombody click or change my model content");
}
}
在代码后面,我获取一些数据,然后调用removeAllItems()的方法。 然后我将新模型(从新数据)设置到其中。
-- at another line of code ---
Cmb_ItemCategory.removeAllItems();
Cmb_ItemCategory.setModel(newModel);
当我执行 removeAllItem()方法时,我知道我的 itemStateChanged()被称为。叫了一次。
那么,如何让它只调用一次用户单击(选择)而不是当removeAllItems()调用时?
它类似于this article.但它不是removeItems的情况。 CMIIW。
答案 0 :(得分:5)
在这里检查一下这段代码,这完美无缺,可能是你在调用removeAllItems()
时做错了什么:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class ComboState
{
private void createAndDisplayGUI()
{
JFrame frame = new JFrame("Combo State Testing : ");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
final JComboBox cbox = new JComboBox();
cbox.addItem("One");
cbox.addItem("Two");
cbox.addItem("Three");
cbox.addItem("Four");
cbox.addItemListener(new ItemListener()
{
public void itemStateChanged(ItemEvent ie)
{
if (ie.getStateChange() == ItemEvent.SELECTED)
{
System.out.println("Item Selected is : " + ie.getItem());
}
/*else
{
System.out.println("I am called for other reasons.");
}*/
}
});
/*
* Click me to remove JComboBox's items.
*/
JButton removeButton = new JButton("REMOVE");
removeButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
cbox.removeAllItems();
}
});
frame.add(cbox, BorderLayout.CENTER);
frame.add(removeButton, BorderLayout.PAGE_END);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String... args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new ComboState().createAndDisplayGUI();
}
});
}
}
答案 1 :(得分:3)
正如nIcE cOw在他的例子中已经说明的那样,当你使用DefaultComboBoxModel
时它肯定会起作用(在他的示例代码中就是这种情况,尽管它发生在屏幕后面)。
我可以解释您在非DefaultComboBoxModel
案例中遇到的行为,尽管您的代码段建议您使用一个。查看JComboBox#removeAllItems
的源代码,有一个不同的代码路径,因为removeAllElements
方法不是MutableComboBoxModel
接口的一部分
public void removeAllItems() {
checkMutableComboBoxModel();
MutableComboBoxModel<E> model = (MutableComboBoxModel<E>)dataModel;
int size = model.getSize();
if ( model instanceof DefaultComboBoxModel ) {
((DefaultComboBoxModel)model).removeAllElements();
}
else {
for ( int i = 0; i < size; ++i ) {
E element = model.getElementAt( 0 );
model.removeElement( element );
}
}
selectedItemReminder = null;
if (isEditable()) {
editor.setItem(null);
}
}
因此,对于非DefaultComboBoxModel
,您将逐个删除这些项目。这意味着在某个特定时间点,您将删除所选元素。模型的可能实现可能会在此时更改所选元素。如果您在DefaultComboBoxModel
中的实现中查找示例(尽管此代码不会被触发),您可以清楚地看到它会更改选择。
public void removeElementAt(int index) {
if ( getElementAt( index ) == selectedObject ) {
if ( index == 0 ) {
setSelectedItem( getSize() == 1 ? null : getElementAt( index + 1 ) );
}
else {
setSelectedItem( getElementAt( index - 1 ) );
}
}
objects.removeElementAt(index);
fireIntervalRemoved(this, index, index);
}
也许你的模型做了类似的事情,这解释了事件。只是为了完成这个帖子,DefaultComboBoxModel#removeAllElements
后面的代码可以清楚地看到它将选择设置为null
而不选择其他对象。该代码中唯一奇怪的事情是它不会首先触发DESELECTED
事件,尽管如果您在监听intervalRemoved
事件时知道选择已更改...但这与您的实际情况并不相关问题
public void removeAllElements() {
if ( objects.size() > 0 ) {
int firstIndex = 0;
int lastIndex = objects.size() - 1;
objects.removeAllElements();
selectedObject = null;
fireIntervalRemoved(this, firstIndex, lastIndex);
} else {
selectedObject = null;
}
}
总而言之:我说你问题的解决方案位于你的模型中,而不是你发布的代码
答案 2 :(得分:2)
一种快速的方法是在调用removeAllItem()之后将bool设置为true,然后返回false。仅当bool变量为false时,才执行itemStateChanged()中的代码。
理想情况下,您可以覆盖removeAllItem()函数。
答案 3 :(得分:2)
不完全清楚,
你必须在删除所有项目之前从JComboBox中删除所有的监听器,删除项目后你可以添加监听器,
仍然不确定是否要添加&amp;动态删除项目,或者您可以为其他JComponent设置任何值,
(对于复杂的简单事情)你有没有看到删除,
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
public class ComboBoxTwo extends JFrame implements ActionListener, ItemListener {
private static final long serialVersionUID = 1L;
private JComboBox mainComboBox;
private JComboBox subComboBox;
private Hashtable<Object, Object> subItems = new Hashtable<Object, Object>();
public ComboBoxTwo() {
String[] items = {"Select Item", "Color", "Shape", "Fruit"};
mainComboBox = new JComboBox(items);
mainComboBox.addActionListener(this);
mainComboBox.addItemListener(this);
//prevent action events from being fired when the up/down arrow keys are used
//mainComboBox.putClientProperty("JComboBox.isTableCellEditor", Boolean.TRUE);
getContentPane().add(mainComboBox, BorderLayout.WEST);
subComboBox = new JComboBox();// Create sub combo box with multiple models
subComboBox.setPrototypeDisplayValue("XXXXXXXXXX"); // JDK1.4
subComboBox.addItemListener(this);
getContentPane().add(subComboBox, BorderLayout.EAST);
String[] subItems1 = {"Select Color", "Red", "Blue", "Green"};
subItems.put(items[1], subItems1);
String[] subItems2 = {"Select Shape", "Circle", "Square", "Triangle"};
subItems.put(items[2], subItems2);
String[] subItems3 = {"Select Fruit", "Apple", "Orange", "Banana"};
subItems.put(items[3], subItems3);
// mainComboBox.setSelectedIndex(1);
}
@Override
public void actionPerformed(ActionEvent e) {
String item = (String) mainComboBox.getSelectedItem();
Object o = subItems.get(item);
if (o == null) {
subComboBox.setModel(new DefaultComboBoxModel());
} else {
subComboBox.setModel(new DefaultComboBoxModel((String[]) o));
}
}
@Override
public void itemStateChanged(ItemEvent e) {
if (e.getStateChange() == ItemEvent.SELECTED) {
if (e.getSource() == mainComboBox) {
if (mainComboBox.getSelectedIndex() != 0) {
FirstDialog firstDialog = new FirstDialog(ComboBoxTwo.this,
mainComboBox.getSelectedItem().toString(), "Please wait, Searching for ..... ");
}
}
}
}
private class FirstDialog extends JDialog {
private static final long serialVersionUID = 1L;
FirstDialog(final Frame parent, String winTitle, String msgString) {
super(parent, winTitle);
setModalityType(Dialog.ModalityType.APPLICATION_MODAL);
JLabel myLabel = new JLabel(msgString);
JButton bNext = new JButton("Stop Processes");
add(myLabel, BorderLayout.CENTER);
add(bNext, BorderLayout.SOUTH);
bNext.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent evt) {
setVisible(false);
}
});
javax.swing.Timer t = new javax.swing.Timer(1000, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
setVisible(false);
}
});
t.setRepeats(false);
t.start();
setLocationRelativeTo(parent);
setSize(new Dimension(400, 100));
setVisible(true);
}
}
public static void main(String[] args) {
JFrame frame = new ComboBoxTwo();
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
答案 4 :(得分:0)
removeAllItems方法不会调用ItemStateChanged,但是会调用actionPerformed,您可以通过运行以下简单代码进行检查:
public class Tuto {
public static void main(String[] args) {
//create the main frame
JFrame frame = new JFrame();
frame.setResizable(false);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setLayout(null);
frame.setLocation(new Point(10, 10));
frame.setPreferredSize(new Dimension(400, 300));
JComboBox<String> combo = new JComboBox();
combo.addItem("item 1");
combo.addItem("item 2");
combo.addItem("item 3");
combo.setBounds(50, 30, 300, 20);
combo.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
System.out.println(" action Performed ");
}
});
frame.add(combo);
JButton button = new JButton("Remove");
button.setBounds(50, 100, 100, 30);
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
combo.removeAllItems();
}
});
frame.add(button);
frame.pack();
frame.setVisible(true);
}
}