Java Swing Combobox removeAllItems calling ItemStateChanged also? - java

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);
}
}

Related

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

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);

A button in my app should only get the text in 8 text fields and send it to a table IF all fields are filled in

A button in my app gets all the text you enter in 8 text fields and sends it to a table. I need code so that you need to fill in ALL fields before you can send the info. How do I write the if statement?
This is the code for the add info button:
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
DefaultTableModel model = (DefaultTableModel) jTable1.getModel();
model.addRow(new Object[]{jTextField1.getText(), jTextField2.getText(),
jTextField3.getText(), jTextField4.getText(), jTextField5.getText(),
jTextField6.getText(), jTextField7.getText(), jTextField8.getText()});
}
You use the AND boolean operator; &&
if(!textfield1.getText().equals("") && !textfield2.getText().equals("") && !textfield3.getText().equals("") && so on){
//fill table in
}
In case you didn't know, ! means NOT, so we're saying
'if text field 1 is not empty and textfield 2 is not empty and ...'
A different approach is to disable the button until data is entered in all the text fields. The you can enable the button:
import java.awt.*;
import java.awt.event.*;
import java.util.List;
import java.util.ArrayList;
import javax.swing.*;
import javax.swing.event.*;
public class DataEntered implements DocumentListener
{
private JButton button;
private List<JTextField> textFields = new ArrayList<JTextField>();
public DataEntered(JButton button)
{
this.button = button;
}
public void addTextField(JTextField textField)
{
textFields.add( textField );
textField.getDocument().addDocumentListener( this );
}
public boolean isDataEntered()
{
for (JTextField textField : textFields)
{
if (textField.getText().trim().length() == 0)
return false;
}
return true;
}
#Override
public void insertUpdate(DocumentEvent e)
{
checkData();
}
#Override
public void removeUpdate(DocumentEvent e)
{
checkData();
}
#Override
public void changedUpdate(DocumentEvent e) {}
private void checkData()
{
button.setEnabled( isDataEntered() );
}
private static void createAndShowUI()
{
JButton submit = new JButton( "Submit" );
submit.setEnabled( false );
JTextField textField1 = new JTextField(10);
JTextField textField2 = new JTextField(10);
DataEntered de = new DataEntered( submit );
de.addTextField( textField1 );
de.addTextField( textField2 );
JFrame frame = new JFrame("SSCCE");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(textField1, BorderLayout.WEST);
frame.add(textField2, BorderLayout.EAST);
frame.add(submit, BorderLayout.SOUTH);
frame.pack();
frame.setLocationByPlatform( true );
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowUI();
}
});
}
}
A benefit of this approach is you don't worry about if statements which is a good thing as the code is easily changed.
You can check, if a field is empty by getting the text length and comparing it to zero.
If you don't want to check every text field in one single if-statement, you could check them separately and return, if one field has an invalid value.
if (jTextField1.getText().length() == 0)
{
//Tell the user, that the first field has to be filled in.
return;
}
if (jTextField2.getText().length() == 0)
{
//Tell the user, that the second field has to be filled in.
return;
}
//...
Otherwise, you could check them all in one if-statement:
if (jTextField1.getText().length() != 0
&& jTextField2.getText().length() != 0
&& ...)
{
//Fill in the table
}
else
{
//Tell the user, that the all fields have to be filled in.
}

How to bind different listener to different ScrollPane

I have a class that defines a graphical interface with two JList. For each JList I would like to associate a method public void valueChanged(ListSelectionEvent s) but I can't do it (obviously). So how can I fix it?
This is my code:
public class Inbox implements ListSelectionListener {
public static void main(String[] args) {
Inbox inbox = new Inbox();
}
JFrame frame = new JFrame();
JPanel panel = new JPanel();
JPanel titlePanel = new JPanel();
JPanel centerPanel = new JPanel();
JPanel listPanel = new JPanel();
JPanel listRicPanel = new JPanel();
JPanel listInvPanel = new JPanel();
JPanel messPanel = new JPanel();
JPanel buttonPanel = new JPanel();
GridBagConstraints c;
JButton indietro = new JButton("Indietro");
JButton ok = new JButton("Ok");
String ricevuti[] = {"1", "2", "3", "4", "5", "6", "7", "8", "9"};
JList ricList = new JList(ricevuti);
String inviati[] = {"A", "B", "C", "D", "E"};
JList invList = new JList(inviati);
Inbox() {
frame.setTitle("Inbox"); //nome della finestra (frame)
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(panel);
frame.setVisible(true);
panel.setLayout(new BorderLayout());
centerPanel.setLayout(new BorderLayout());
listPanel.setLayout(new GridLayout(2, 0));
panel.add(titlePanel, BorderLayout.NORTH);
panel.add(buttonPanel, BorderLayout.SOUTH);
panel.add(centerPanel, BorderLayout.CENTER);
buttonPanel.add(indietro);
buttonPanel.add(ok);
centerPanel.add(listPanel, BorderLayout.WEST);
centerPanel.add(messPanel, BorderLayout.CENTER);
listPanel.add(listRicPanel);
listPanel.add(listInvPanel);
/** ScrollPane containing the first list **/
ricList.setVisibleRowCount(10);
ricList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
listRicPanel.add(new JScrollPane(ricList));
ricList.addListSelectionListener(this);
/** ScrollPane containing the second list **/
invList.setVisibleRowCount(10);
invList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
listInvPanel.add(new JScrollPane(invList));
invList.addListSelectionListener(this);
frame.pack();
}
/**
* First listener.
*/
public void valueChanged(ListSelectionEvent e) {
String str = (String) ricList.getSelectedValue();
if(str.equals("Alex"))
System.out.println("Alex");
else if(str.equals("John"))
System.out.println("John");
else
System.out.println("Other name");
}
/**
* Second listener.
*/
public void valueChanged(ListSelectionEvent e) {
String str = (String) invList.getSelectedValue();
if(str.equals("Alex"))
System.out.println("Alex");
else if(str.equals("John"))
System.out.println("John");
else
System.out.println("Other name");
}
}
I wish the program would combine different listeners to different scroolPane, as I do that?
Thank you very much!
It must be one method but you can use e.getSource() method to get JList instance which fires the event. Then you can use it like this
public void valueChanged(ListSelectionEvent e) {
String str = (String) ((JList)e.getSource()).getSelectedValue();
if(str.equals("Alex"))
System.out.println("Alex");
else if(str.equals("John"))
System.out.println("John");
else
System.out.println("Other name");
}
Of course the listener must be added to both list instances
You Could
Determine the source of the event and branch your logic based on the result...
public void valueChanged(ListSelectionEvent e) {
if (e.getSource() == ricList) {
//...
else if (e.getSource() == invList) {
//...
}
}
This assumes that you want to perform different logic for each source. This can become a little cumbersome if you have more than a few possible sources...
Instead of "implementing" ListSelectionListener at the class level...
You Could...
Define a completely external class that does the specific job you want...
public class MyListSelectionListener implements ListSelectionListener {
public void valueChanged(ListSelectionEvent s) {
// Custom job here...
}
}
This can be a good and bad thing depending on your needs...One problem with this is you may be required to provide additional context to the class in order for it to perform it's operations, as the event object may not provide enough context alone
You Could
Create inner classes that do a specific job, in particular for the class they've been defined within...
public class Inbox {
//...
Inbox() {
//...
ricList.addListSelectionListener(new RicListSelectionListener());
//...
invList.addListSelectionListener(new InvListSelectionListener());
}
//...
public class RicListSelectionListener implements ListSelectionListener {
public void valueChanged(ListSelectionEvent s) {
String str = (String) ricList.getSelectedValue();
if(str.equals("Alex"))
System.out.println("Alex");
else if(str.equals("John"))
System.out.println("John");
else
System.out.println("Other name");
}
}
public class InvListSelectionListener implements ListSelectionListener {
public void valueChanged(ListSelectionEvent s) {
String str = (String) invList.getSelectedValue();
if(str.equals("Alex"))
System.out.println("Alex");
else if(str.equals("John"))
System.out.println("John");
else
System.out.println("Other name");
}
}
}
The nice thing about this is the classes have access to all the instance variables and methods within the parent class and are neat and tidy and easy to find when you need...
Take a look at Inner Class Example for more details
You Could...
Use anonymous classes. These are a little like inner classes, except they are defined in line...
public class Inbox {
//...
Inbox() {
//...
ricList.addListSelectionListener(new ListSelectionListener {
public void valueChanged(ListSelectionEvent s) {
String str = (String) ricList.getSelectedValue();
if(str.equals("Alex"))
System.out.println("Alex");
else if(str.equals("John"))
System.out.println("John");
else
System.out.println("Other name");
}
});
//...
invList.addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent s) {
String str = (String) invList.getSelectedValue();
if(str.equals("Alex"))
System.out.println("Alex");
else if(str.equals("John"))
System.out.println("John");
else
System.out.println("Other name");
}
});
}
}
These can clutter the code if they are too long and should be used sparingly for that reason, but are really good for plumbing together existing functionality.
Take a look at Anonymous Classes for more details

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).

ComboBox - printing out the selected item

I am a little stuck. I can't figure out a much bigger problem than this, so I am going to the roots to eventually build my way up!
I can't print the selected item in the combo box, currently I have an ActionListener for it:
box.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent evt) {
myBox(evt);
}
});
...
protected void myBox(ActionEvent evt)
{
if(myBoxName.getSelectedItem().toString() != null)
System.out.println(myBoxName.getSelectedItem().toString());
}
I would expect this to print out to the console every time I change the selected item, but it doesn't. This should be so easy though!
Thanks
I just tried your code and it works fine. Whenever I change selection, the selected text is written to System.out.
The only thing I changed was the check for myBoxName.getSelectedItem().toString() != null, I check for myBoxName.getSelectedItem() != null instead. This should not be related to your problems though.
public class ComboBoxTest {
private JComboBox comboBox = new JComboBox(
new DefaultComboBoxModel(new String[] { "Test1", "Test2", "Test3" }));
public ComboBoxTest() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setSize(200, 100);
comboBox.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
myBox(evt);
}
});
frame.getContentPane().add(comboBox);
frame.setVisible(true);
}
protected void myBox(ActionEvent evt) {
if (comboBox.getSelectedItem() != null) {
System.out.println(comboBox.getSelectedItem().toString());
}
}
}

Categories