How to add price on an item from a binded ComboBox? - java

I'm trying to learn the difference between Hashtable and HashMap and I'm trying to add specific prices to these items here. The goal is to print the price of the item selected from comboItem into txtPrice.
String[] items = {"Select Item","Betta Fish","Snail","Supplies","Food"};
comboGroup = new JComboBox<String>(items);
comboGroup.addActionListener(this);
comboGroup.setBounds(130,35,150,40);
comboItem = new JComboBox<>();
comboItem.setPrototypeDisplayValue("XXXXXXXXXXX");
comboItem.setBounds(130,85,150,40);
String[] subItems1 = {"Select Betta","Plakat","Halfmoon","Double Tail","Crown Tail"};
subItems.put(items[1], subItems1);
String[] subItems2 = {"Select Snail","Pond Snail","Ramshorn","Apple Snail","Assassin Snail"};
subItems.put(items[2], subItems2);
String[] subItems3 = {"Select Supply","Small Fine Net","Large Fine Net","Flaring Mirror","Aquarium Hose (1meter)"};
subItems.put(items[3], subItems3);
String[] subItems4 = {"Select Food","Daphnia","Tubifex","Mosquito Larvae","Optimum Pellets"};
subItems.put(items[4], subItems4);
comboGroup.setSelectedIndex(1);
//TextFields <- this is the attempt to add price to subItems value but commented out
/*int[] items1price = {0,150,350,200,200};
subItems.put(items[1], items1price);
int[] items2price = {0,15,25,80,120};
subItems.put(items[2], items2price);
int[] items3price = {0,50,80,25,15};
subItems.put(items[3], items3price);
int[] items4price = {0,50,100,50,50};
subItems.put(items[4], items4price);
comboGroup.setSelectedIndex(1);
*/
txtPrice = new JTextField();
txtPrice.setBounds(130,135,150,40);
So far with my understanding from HashMap applying it to CLi and not in GUI, If I try HashMap<String,Integer> I can only print it altogether in a single line.
eg.
HashMap<String,Integer> item = new HashMap<String,Integer>();
item.put("Plakat",50);
CLi Prints:
Plakat=50
What I want is to print Plakat from selected comboItem then print 50 to txtPrice but I don't know how to do that.
The whole code is here: https://github.com/kontext66/GuwiPos
GUI and Main.
Additional note: I am a beginner and I'm trying to understand Layout Manager for now, so the code here is a bit messy and literal.

Below is an example using JComboBox and HashMap to get the corresponding "prices" to specific items in the combo box. I would suggest going through the tutorial on How to Use Various Layout Managers and choose the ones that suit you best. As for the difference between HashMap and HashTable, please have a look at this answer. The main difference is that HashTable is synchronized, whereas HashMap is not, and since synchronization is not an issue for you, I'd suggest HashMap. Also, another option would be to add instances of a custom object to a JComboBox, as described here. Thus, there would be no need to use HashMap.
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.util.*;
public class App {
Map<String, String> map;
JTextField tf;
public App() {
map = new HashMap<String, String>();
map.put("Plakat", "50");
map.put("Halfmoon", "25");
map.put("Double Tail", "80");
}
private void addComponentsToPane(Container pane) {
String[] items = { "Select Item", "Plakat", "Halfmoon", "Double Tail" };
JComboBox<String> comboBox = new JComboBox<String>(items);
comboBox.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent event) {
if (event.getStateChange() == ItemEvent.SELECTED) {
String item = (String) event.getItem();
System.out.println(item);
tf.setText(map.get(item));
}
}
});
tf = new JTextField();
JPanel p = new JPanel();
pane.add(comboBox, BorderLayout.NORTH);
pane.add(tf, BorderLayout.SOUTH);
}
private void createAndShowGUI() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
addComponentsToPane(frame.getContentPane());
// frame.setSize(640, 480);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
new App().createAndShowGUI();
}
});
}
}
Update
Below is the implementation of the second approach described earlier, where a custom object is used for adding items to a JComboBox, and hence, there is no need to use a HashMap.
P.S. I should also add that if the user shouldn't be allowed to edit the "price" in the text field, then you should use tf.setEditable(false);, or even use a JLabel instead.
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class App {
JTextField tf;
class ComboItem {
private String key;
private String value;
public ComboItem(String key, String value) {
this.key = key;
this.value = value;
}
#Override
public String toString() {
return key;
}
public String getKey() {
return key;
}
public String getValue() {
return value;
}
}
private void addComponentsToPane(Container pane) {
JComboBox<ComboItem> comboBox = new JComboBox<ComboItem>();
comboBox.addItem(new ComboItem("Select Item", ""));
comboBox.addItem(new ComboItem("Plakat", "50"));
comboBox.addItem(new ComboItem("Halfmoon", "25"));
comboBox.addItem(new ComboItem("Double Tail", "80"));
comboBox.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent event) {
if (event.getStateChange() == ItemEvent.SELECTED) {
Object item = comboBox.getSelectedItem();
String value = ((ComboItem) item).getValue();
tf.setText(value);
}
}
});
tf = new JTextField();
JPanel p = new JPanel();
pane.add(comboBox, BorderLayout.NORTH);
pane.add(tf, BorderLayout.SOUTH);
}
private void createAndShowGUI() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
addComponentsToPane(frame.getContentPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
new App().createAndShowGUI();
}
});
}
}
Update 2
To convert the string from the text field into double, you can use Double.parseDouble(String), as shown below (again, make sure to use tf.setEditable(false);, so that the value cannot be modified by the user).
double price = 0;
if (tf.getText() != null && !tf.getText().trim().isEmpty())
price = Double.parseDouble(tf.getText());
System.out.println(price);

Related

Is possible that a JCombobox has 2 ItemListeners?

I have 3 JComboBoxes. The first shows the school year of a kid. The second shows the class of the kid and the third shows the children of that school year and of that class. I want that when I select an option of the first JComboBox, at the second JComboBox appears one option or another (depending of the selection of the first JComboBox). The problem is that also, I want select an option in the second JComboBox and in the third appears one option or another (depending of the selection of the second JComboBox). I have tried it a lot and I don't know how to do it. I have tried actionlisteners too, but it didn't work. Please, I'd appreciate any help.
Here is an example that shows how you can populate a second combo box based on the selection in the first combo box:
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
public class ComboBoxTwo extends JPanel implements ActionListener
{
private JComboBox<String> mainComboBox;
private JComboBox<String> subComboBox;
private Hashtable<String, String[]> subItems = new Hashtable<String, String[]>();
public ComboBoxTwo()
{
String[] items = { "Select Item", "Color", "Shape", "Fruit" };
mainComboBox = new JComboBox<String>( items );
mainComboBox.addActionListener( this );
// prevent action events from being fired when the up/down arrow keys are used
mainComboBox.putClientProperty("JComboBox.isTableCellEditor", Boolean.TRUE);
add( mainComboBox );
// Create sub combo box with multiple models
subComboBox = new JComboBox<String>();
subComboBox.setPrototypeDisplayValue("XXXXXXXXXX"); // JDK1.4
add( subComboBox );
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);
}
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 ) );
}
}
private static void createAndShowUI()
{
JFrame frame = new JFrame("SSCCE");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add( new ComboBoxTwo() );
frame.setLocationByPlatform( true );
frame.pack();
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowUI();
}
});
}
}
I'm going to try to explain a little my code. I receive for another class a JSon object, because the information is in a database. The other classes are ClasInf and StudentsInf. It's a JSon object so I have to get the object and then change it to a String, for put it on the jcombobox. All the JCombobox are in the same class. Please if you don't understand something tell me it. I have tried to translate the whole answer
This is my first JCombobox.
for(int c=0;c<arrayClassroom.size();c++){
JsonObject clas = arrayClassroom.getJsonObject(c);
comboBoxYear.addItem(clas.getString("name"));
}
And this is the second and the third
ItemListener itemlistener= new ItemListener() {
public void itemStateChanged(ItemEvent eventCombo){
comboBoxYear.removeAllItems();
comboBoxYear.addItem("Class");
clase = new ClasInf();
String cursoPru = comboBoxYear.getSelectedItem().toString();
arrayClas = clase.getclase(cursoPru);
for(int c=0;c<arrayClas.size();c++){
JsonObject curso = arrayClas.getJsonObject(c);
comboBoxYear.addItem(curso.getString("name_class"));
}
comboBoxStudents.removeAllItems();
comboBoxStudents.addItem("Students");
students= new StudentsInf();
String clases = comboBoxClase.getSelectedItem().toString();
arrayStudent = student.getStudent(clases);
for(int j=0;j<arrayStudent.size();j++){
JsonObject clase = arrayStudent.getJsonObject(j);
comboBoxStudents.addItem(clase.getString("nombre"));
}
}
};
comboBoxYear.addItemListener(itemlistener);

JComboBox not populating from Hashtable and ArrayList

I'm creating a Fruit and Vedg application that allows users to pick from drop down boxes. My JComboBox subComboBox will populate if I use an String[] rather than ArrayList. Any thoughts or documents I could view? With the code below the subComboBox is empty.
public class FruitAndVedg extends JFrame implements ActionListener, ItemListener {
private static final long serialVersionUID = 4L;
private JComboBox mainComboBox;
private JComboBox subComboBox;
private ArrayList item;
private Hashtable<ArrayList<Object>, Object> subItems = new Hashtable<>();
public FruitAndVedg() {
item = new ArrayList();
item.add("Select Item");
item.add("Fruit");
item.add("Vedg");
mainComboBox = new JComboBox(item.toArray());
mainComboBox.addActionListener(this);
mainComboBox.addItemListener(this);
getContentPane().add(mainComboBox, BorderLayout.WEST);
subComboBox = new JComboBox();
subComboBox.setPrototypeDisplayValue("XXXXXXXXXX");
getContentPane().add(subComboBox, BorderLayout.CENTER);
String[] subItems1 = {"Select Fruit", "Apple", "Plum"};
subItems.put(item, subItems1);
String[] subItems2 = {"Select Vedg", "Carrot", "Peas"};
subItems.put(item, subItems2);
}
#Override
public void actionPerformed(ActionEvent ae) {
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 ie) {
if (ie.getStateChange() == ItemEvent.SELECTED) {
if (ie.getSource() == mainComboBox) {
if (mainComboBox.getSelectedIndex() != 0) {
}
}
}
}
public static void main(String[] args) {
JFrame frame = new FruitAndVedg();
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
No error messages reported.
My JComboBox subComboBox will populate if I use an String[] rather than ArrayList.
The default ComboBoxModel doesn't support ArrayList.
You can use a Vector.
If you really want to use an ArrayList then you need to create a custom model. Or create a loop to add the items from the ArrayList to the model one at a time. Creating a custom model isn't that hard, just copy the code for the DefaultComboBoxModel and change the code to use a List instead of a Vector.

JComboBox show value

Need help with JComboBox component. I've load data from MySQL database and write this data into combo. I use four combo boxes with ItemListener. When one combo box change all children combo boxes reload data from database. First and two works fine but third and four don't show value normal, but good value is there. Only I don't show it. When I select empty field in combo box after then I see good result.
Source code:
public class Vyhladat extends Okno {
private static final long serialVersionUID = 1L;
JComboBox nominalBOX,statBOX,podpisBOX,tlacDoskaBOX;
Font sherif = new Font("Sherif",Font.BOLD,20);
Font normal = new Font("Sherif",Font.PLAIN,20);
JFrame uh = new JFrame();
private String adresa="jdbc:mysql://localhost:3306/jarodb";
private String meno="JKARAK";
private String heslo="bankovka";
String nominal,stat,podpis,tlacDoska,statH;
private String nominalSQL = "SELECT DISTINCT(nominal) FROM prehlad";
private String statSQL = "SELECT DISTINCT(concat(stat,'/',seria)) FROM prehlad WHERE nominal=? ORDER BY stat";
private String podpisSQL = "SELECT DISTINCT(podpis) FROM prehlad WHERE nominal=? AND stat=? ";
private String tlacDoskaSQL = "SELECT DISTINCT(doska) FROM prehlad WHERE nominal=? AND stat=? AND podpis=? ";
Vector nominalV=new Vector();
Vector statV=new Vector();
Vector podpisV=new Vector();
Vector tlacDoskaV=new Vector();
Vyhladat()
{
vlozPopis(nominalLAB,"NOMIN\u00C1L EUROBANKOVKY: ",0,0,sherif);
vlozPopis(statLAB,"\u0160T\u00C1T/S\u00C9RIA:",0,1,sherif);
vlozPopis(podpisLAB,"PODPIS:",0,2,sherif);
vlozPopis(tlacDoskaLAB,"TLA\u010COV\u00C1 DOSKA:",0,3,sherif);
gbc.gridx=1;
gbc.gridy=0;
nacitajVyber(nominalSQL,nominalBOX,nominalV,false,false,false);
nominalBOX = new JComboBox(nominalV);
nominalBOX.addItemListener(new ItemListener()
{
public void itemStateChanged(ItemEvent e)
{
nominal = (String)nominalBOX.getSelectedItem();
if(nominal!=" ")
{
nacitajVyber(statSQL,statBOX,statV,true,false,false);
}
else{
statBOX.removeAllItems();
podpisBOX.removeAllItems();
tlacDoskaBOX.removeAllItems();
}
}
});
nominalBOX.setPrototypeDisplayValue("500");
nominalBOX.setFont(normal);
nominalBOX.setSelectedIndex(0);
nominalBOX.setToolTipText("Vyber z mo\u017Enost\u00ED nomin\u00E1lu bankoviek 5,10,20,50.");
add(nominalBOX,gbc);
gbc.gridx=1;
gbc.gridy=1;
statV.add(" ");
statBOX= new JComboBox(statV);
statBOX.addItemListener(new ItemListener()
{
public void itemStateChanged(ItemEvent e)
{
stat = (String)statBOX.getSelectedItem();
if(stat!=null)
{
String [] statM= stat.split("/");
statH = statM[0];
}
if(stat!=" " & stat!=null)
{
nacitajVyber(podpisSQL,podpisBOX,podpisV,false,true,false);
}
else{
podpisBOX.removeAllItems();
tlacDoskaBOX.removeAllItems();
}
}
});
statBOX.setPrototypeDisplayValue("Portugalsko/E");
statBOX.setFont(normal);
statBOX.setSelectedIndex(0);
statBOX.setToolTipText("Vyber z mo\u017Enost\u00ED \u0161t\u00E1t/s\u00E9riu.");
add(statBOX,gbc);
gbc.gridx=1;
gbc.gridy=2;
podpisV.add(" ");
podpisBOX = new JComboBox(podpisV);
podpisBOX.addItemListener(new ItemListener()
{
public void itemStateChanged(ItemEvent e)
{
podpis = (String)podpisBOX.getSelectedItem();
if(podpis!=" " & podpis!=null)
{
nacitajVyber(tlacDoskaSQL,tlacDoskaBOX,tlacDoskaV,false,false,true);
}
else{
tlacDoskaBOX.removeAllItems();
}
}
});
podpisBOX.setPrototypeDisplayValue("Jean-Claude Trichet ");
podpisBOX.setFont(normal);
podpisBOX.setSelectedIndex(0);
podpisBOX.setToolTipText("Vyber z mo\u017Enost\u00ED troch podpisov.");
add(podpisBOX,gbc);
gbc.gridx=1;
gbc.gridy=3;
tlacDoskaV.add(" ");
tlacDoskaBOX = new JComboBox(tlacDoskaV);
tlacDoskaBOX.addItemListener(new ItemListener()
{
public void itemStateChanged(ItemEvent e)
{
tlacDoska = (String)tlacDoskaBOX.getSelectedItem();
if((nominal!=" " & nominal!=null) & (statH!=" " & statH!=null) & (podpis!=" " & podpis!=null) & (tlacDoska!=" " & tlacDoska!=null))
{
zobraz.setEnabled(true);
}
}
});
tlacDoskaBOX.setPrototypeDisplayValue("E010");
tlacDoskaBOX.setFont(normal);
tlacDoskaBOX.setSelectedIndex(0);
tlacDoskaBOX.setToolTipText("Vyber z mo\u017Enost\u00ED tla\u010Dov\u00FDch dosiek.");
add(tlacDoskaBOX,gbc);
}
private void nacitajVyber(String sqlDotaz, JComboBox chr,Vector v,
boolean jedna,boolean dva, boolean tri)
{
try
{
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection(adresa,meno,heslo);
PreparedStatement stmt = conn.prepareStatement(sqlDotaz);
if(jedna==true)
{
chr.removeAllItems();
stmt.setString(1, nominal);
}
if(dva==true)
{
chr.removeAllItems();
stmt.setString(1, nominal);
stmt.setString(2, statH);
}
if(tri==true)
{
chr.removeAllItems();
stmt.setString(1, nominal);
stmt.setString(2, statH);
stmt.setString(3, podpis);
}
ResultSet rs = stmt.executeQuery();
v.addElement(" ");
while (rs.next())
{v.addElement(rs.getString(1).trim());
System.out.println(rs.getString(1));}
validate();
rs.close();
stmt.close();
conn.close();
}
catch(Exception e){
JOptionPane.showMessageDialog(uh,e.toString(),
"Chyba pripojenia",
JOptionPane.ERROR_MESSAGE);
}
}
}
JComboBox doesn't know somehow then underlaying Vector is changed, have to reinitialize this array for JComboBox on the fly, but this is wrong way,
for any changes on the runtime to use XxxComboBoxModel for storing Items for JComboBox
for JDBC or FileIO there could be Concurency issue, Swing JComponents required to all updates (in this case JComboBox and its XxxComboBoxModel) must be done on EDT
invoke Database event from the Runnable#Thread or SwingWorker, redirect this (potentionally) hard and long running task to the Workers Thread, otherwise Swing GUi will be freeze or unresponsive (for mouse and key events) untill JDBC ended
SwingWorkers methods publish(), process() and done() quite good quaranteed that all output wil be done on EDT
for example
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 { //sipmle simulation of JDBC events, by using Swing Timer
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);
}
}
The GUI probably can't redraw properly. You are doing all of your hard work on the Event Dispatch Thread. This thread calls your itemStateChanged. But this thread is also responsible for redrawing the GUI. You are stopping it from doing that, because you are making it do your hard work in the database.
Instead, you can use a different thread to do your hard work.
public void itemStateChanged(ItemEvent e)
{
new Thread(new Runnable() {
public void run() {
.... your code...
}
}).start();
}
Or take a look at SwingWorker, which does this in a nicer way.
Also, itemStateChanged could be called twice for each selection - this might be causing you problems. Use "e.getStateChange()" to check what TYPE of event you just received. You should receive a selected and an unselected (from the old item).

Java Swing Combobox removeAllItems calling ItemStateChanged also?

My code is quite simple actually. I saw a simple and similar code was from this article.
At first, I have 1 combobox. I have a listener on it called itemStateChanged(). My purpose to add into this listener is that; "to execute some code when user click (select) an item from its dropbox".
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");
}
}
Behind the code, I grab some data, and then calling a method of removeAllItems() .
And then I set a new Model (from new data) into it.
-- at another line of code ---
Cmb_ItemCategory.removeAllItems();
Cmb_ItemCategory.setModel(newModel);
I juz realized that my itemStateChanged() is called when i do the removeAllItem() method. called once.
So, How to make it only called once user Click (select) only AND not when removeAllItems() called?
it similar to this article. But it's not removingItems case. CMIIW.
Here check this code out, this works flawlessly, might be you doing something wrong where you calling 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();
}
});
}
}
As nIcE cOw already illustrated in his example, it should certainly work when you use a DefaultComboBoxModel (which is the case in his sample code, although it happens behind the screens).
I could explain the behavior you encounter for the non-DefaultComboBoxModel case, although your code snippet suggests you use one. Looking at the source code for JComboBox#removeAllItems there is a different code path since the removeAllElements method is not part of the MutableComboBoxModel interface
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);
}
}
So with a non-DefaultComboBoxModel you are going to remove the items one by one. This means that at a certain point in time, you will remove the selected element. A possible implementation of your model might change the selected element at that point. If you look for example at the implementation in DefaultComboBoxModel (although this code will not be triggered) you can clearly see it changes the selection.
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);
}
Perhaps your model does something similar, which explains the event. Just for making this post complete, the code behind the DefaultComboBoxModel#removeAllElements where you can clearly see it sets the selection to null and does not select another object. Only weird thing in that code is that it does not fire a DESELECTED event first, although you know the selection has changed if you listen for the intervalRemoved event ... but that is not really relevant to your problem
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;
}
}
So to conclude: I say the solution for your problem is located in your model, and not in the code you posted
One quick way to do is to have a bool set to true before you call removeAllItem() and back false after. Execute the code in your itemStateChanged() only if the bool variable is false.
Ideally you could override the removeAllItem() function.
not clear from whole discusion,
you have to remove all Listener(s) from JComboBox before removing all Items, after Items are removed you can add Listener(s) back,
still not sure if you want to add & remove Items dynamically, or you can set whatever value for another JComponent(s),
(against complicating simple things) did you see there remove,
.
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);
}
}
The method removeAllItems does not call ItemStateChanged, but it call actionPerformed, you can check it by running this simple code:
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);
}
}

drop down list within JTextField

I wnt that when i enter some letter in the textfield then the related items should be picked up from my database and should appear as a drop down list.
For Example:
I typed 'J' in text Field, in my database is having names such as {"Juby','Jaz','Jasmine','Joggy'....}
Theses names should appear as a list. So that i could select one from them.and so on for other leters as well.
Is there any predefined control in awt??
Thnx
Why not just use a JComboBox? By default, when the user types a keystroke in a read-only combobox and an item in the combobox starts with the typed keystroke, the combobox will select that item.
Or you could set the JComboBox to be editable using setEditable(true), and use a KeySelectionManager. The link explains selecting an item in a JComboBox component with multiple keystrokes.
This is a small example implementing what ( i think) you asked for.. the database in this example is a vector of strings.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Answer extends JFrame {
public static final int MAXITEMS = 100;
JPanel panel = new JPanel();
JTextField textField = new JTextField(10);
String[] myDataBase = { "Juby", "Jaz", "Jasmine", "Joggy", "one", "dog","cat", "parot" };
String[] listItems;
JList theList = new JList();
public Answer() {
this.add(panel);
panel.setPreferredSize(new Dimension(500, 300));
panel.add(textField);
panel.add(theList);
textField.addKeyListener(new KeyAdapter() {
public void keyTyped(KeyEvent ke) {
String compareString = ("" + textField.getText() + ke.getKeyChar());
listItems = new String[MAXITEMS];
if (compareString.trim().length() > 0 ){
int counter = 0;
for (int i = 0; i < myDataBase.length; i++) {
if (counter < MAXITEMS) {
if (myDataBase[i].length() >= compareString.length() &&
myDataBase[i].substring(0, compareString.length()).equalsIgnoreCase(compareString)) {
listItems[counter] = myDataBase[i];
counter++;
}
}
}
}
theList.setListData(listItems);
}
});
}
public static void main(String[] args) {
final Answer answer = new Answer();
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
answer.pack();
answer.setVisible(true);
}
});
}
}
One option is to use GlazedLists, as it has some support for auto-completion.

Categories