How to have the ComboBox items sorted - java

I want to have a sorted item list in ascending manner in my vaadin combo box. I am adding items as below.
for (long i = 1; i < 11; i++) {
Long item = new Long(i);
comboBoxPriority.addItem(item);
}
I also tried it below way. Still I am getting a item list in descending order.
for (long i = 10; i > 0; i--) {
Long item = new Long(i);
comboBoxPriority.addItem(item);
}

You could simply add the values to a List and uses the Collections API to sort it.
List<Long> values = new ArrayList<Long>(10);
for (long i = 10; i > 0; i--) {
values.add(i);
}
Collections.sort(values);
DefaultComboBoxModel model = new DefaultComboBoxModel(values.toArray(new Long[values.size()]));
comboBoxPriority.setModel(model);
You could achieve the same thing using an array and Arrays.sort if that was eaiser

One way would be to put the data into an IndexedContainer, sort the data, then add the data to the ComboBox. See Charles Anthony's example in the vaadin-forum.
Here is his example:
/* Creating a container, with a property of "name". Item Id is a number, here. Can be anything (unique).
* Alternatively, you could use the IndexedContainer to generate it's own ItemId :
* cityContainer.getItem(cityContainer.addItem()).getItemProperty("name").setValue("New York");
*/
IndexedContainer cityContainer = new IndexedContainer();
cityContainer.addContainerProperty("name", String.class, null);
cityContainer.addItem(1).getItemProperty("name").setValue("New York");
cityContainer.addItem(2).getItemProperty("name").setValue("Turku");
cityContainer.addItem(3).getItemProperty("name").setValue("Paris");
cityContainer.addItem(4).getItemProperty("name").setValue("Zanzibar");
cityContainer.addItem(5).getItemProperty("name").setValue("Turin");
cityContainer.addItem(6).getItemProperty("name").setValue("London");
cityContainer.getItem(cityContainer.addItem()).getItemProperty("name").setValue("New York");
/* Lets sort the container on ascending name*/
cityContainer.sort(new Object[]{"name"}, new boolean[]{true});
/* Here's a comboBox that uses that container, where we are using the "name" property as the item caption */
ComboBox comboBox = new ComboBox("City", cityContainer);
comboBox.setItemCaptionMode(AbstractSelect.ITEM_CAPTION_MODE_PROPERTY);
comboBox.setItemCaptionPropertyId("name");

Seems to work just fine here:
import java.awt.*;
import javax.swing.*;
class ReversCombo {
public static void main(String[] args) {
Runnable r = new Runnable() {
#Override
public void run() {
JPanel gui = new JPanel(new GridLayout(1,0,5,5));
JComboBox comboBoxPriority = new JComboBox();
for (long i = 1; i < 11; i++) {
Long item = new Long(i);
comboBoxPriority.addItem(item);
}
JComboBox comboBoxPriority2 = new JComboBox();
for (long i = 10; i > 0; i--) {
Long item = new Long(i);
comboBoxPriority2.addItem(item);
}
gui.add(comboBoxPriority);
gui.add(comboBoxPriority2);
JOptionPane.showMessageDialog(null, gui);
}
};
SwingUtilities.invokeLater(r);
}
}

Related

How can I dynamically change the number of items in a JComboBox

private void dropDownMenu(JPanel jp1, String prodId){
int len = storeManager.getInv().getStockAmount(prodId);
int[] nums = new int[len];
String[] numPossible = new String[len];
for (int i=0; i<len; i++){
nums[i] = i+1;
}
for (int i=0; i<len; i++){
numPossible[i] = String.valueOf(nums[i]);
}
JComboBox<String> cb = new JComboBox<String>(numPossible);
JButton okButton = new JButton("Add To Cart");
okButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
Product p1 = storeManager.getInv().getProd(prodId);
String quan = (String) cb.getSelectedItem();
int quantity = Integer.parseInt(quan);
if (quantity > storeManager.getInv().getStockAmount(prodId)) {
System.out.println("Not Enough Stock.");
} else {
storeManager.getCart().addToCart(p1, quantity);
storeManager.getInv().removeStockAmount(prodId, quantity);
//update the dropdown menu here
}
}
});
jp1.add(cb);
jp1.add(okButton);
}
Essentially what i am looking for is that whenever i select a number from the drop down menu, i want the number of items in the menu to be reduced by the amount that was added to cart. for example if i add 5 to cart then i want the dropdown menu to go from allowing me to choose 10 to 5 only.
Image of GUI
As a thought...Instead of doing all these conversions from integer to string and string to back to integer in order to fill your combo box, why not just have a combo box of Integer? You're dealing initially with integer quantity values anyways:
JComboBox<Integer> cb = new JComboBox<>();
int len = storeManager.getInv().getStockAmount(prodId);
for (int i = 1; i <= len; i++) {
cb.addItem(i);
}
cb.setSelectedIndex(0);
Your action listener might look something like this now:
okButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
Product p1 = storeManager.getInv().getProd(prodId);
int quantity = (int) cb.getSelectedItem();
/* This 'if' statement below would be moot if the Combo-Box
is properly updated unless editing is allowed in the combo
which in this case...disable that feature. */
if (quantity > storeManager.getInv().getStockAmount(prodId)) {
System.out.println("Not Enough Stock.");
} else {
storeManager.getCart().addToCart(p1, quantity);
len = storeManager.getInv().removeStockAmount(prodId, quantity);
cb.removeAllItems();
for (int i = 1; i <= len; i++) { cb.addItem(i); }
cb.setSelectedIndex(0);
}
}
});
Possibly better yet would be to utilize the JSpinner component instead of a Combo Box. A drop-down list in this use case always seems a bit obtrusive in my opinion.

How to access items on a JMenu and work with Action Listener?

I ran into an issue with my java code where the action listener is not working. I am supposed to create a GUI that has a menu bar that performs some actions when those buttons are clicked. For example, if the user selects an option on the "Meals" menu and an option on the "Dorms" menu, it should calculate the values that each of those items has assigned and then outputted to the total cost JField.
This is what my code looks like
private class MenuActionListener implements ActionListener {
//The user has chosen a new dorm or new meal plan
//Get the choices from the dormBox and mealBox and recalculate charges
//Display the new charges in the totalField
public void actionPerformed(ActionEvent arg0) {
//Get the choices from the dormBox and mealBox
int totalCost;
int dormIndex = menu.getComponentCount();
int dormCost=dormCosts[dormIndex];
int mealIndex=dorm.getComponentCount();
int mealCost=mealCosts[mealIndex];
//Calculate the charges
totalCost=dormCost+mealCost;
//Display the new charges
totalField.setText("$"+Integer.toString(totalCost));
}
}
How should I get it working well..?
Don’t write listeners which try to guess about the right values to use. When you register a listener to a specific component, you already know which component it is, so you can register a listener doing the right thing for exactly that component.
In this case, when the costs are stored in an array, there should also be a corresponding array used for building the menu items, which allows constructing items and corresponding listeners.
E.g.
static String[] dorms = { "Allen Hall", "Pike Hall", "Farthing Hall" };
static int[] dormCosts = { 10, 20, 40 };
static String[] meals = { "7 / weak", "14 / week", "unlimited" };
static int[] mealCosts = { 5, 8, 15 };
JTextField totalField = new JTextField();
int dormCost = dormCosts[0];
int mealCost = mealCosts[0];
void updateTotalCosts() {
int totalCost = dormCost + mealCost; // really plus not multiply?
totalField.setText("$" + totalCost);
}
JMenuBar buildMenu() {
final JMenuBar mb = new JMenuBar();
JMenu menu = mb.add(new JMenu("Meals"));
for(int ix = 0; ix < meals.length; ix++) {
int currMealCosts = mealCosts[ix];
menu.add(meals[ix]).addActionListener(ev -> {
mealCost = currMealCosts;
updateTotalCosts();
});
}
menu = mb.add(new JMenu("Dorms"));
for(int ix = 0; ix < dorms.length; ix++) {
int currDormCosts = dormCosts[ix];
menu.add(dorms[ix]).addActionListener(ev -> {
dormCost = currDormCosts;
updateTotalCosts();
});
}
return mb;
}
In each loop iteration we do already know which item we’re creating and which costs are associated with it, so we register a listener using exactly those costs.
If you can’t use lambda expressions, the pre-Java 8 variant of the construction method would look like
JMenuBar buildMenu() {
final JMenuBar mb = new JMenuBar();
JMenu menu = mb.add(new JMenu("Meals"));
for(int ix = 0; ix < meals.length; ix++) {
final int currMealCosts = mealCosts[ix];
menu.add(meals[ix]).addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ev) {
mealCost = currMealCosts;
updateTotalCosts();
}
});
}
menu = mb.add(new JMenu("Dorms"));
for(int ix = 0; ix < dorms.length; ix++) {
final int currDormCosts = dormCosts[ix];
menu.add(dorms[ix]).addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ev) {
dormCost = currDormCosts;
updateTotalCosts();
}
});
}
return mb;
}
I'm afraid that this approach won't work. You cannot access your UI components from inside the ActionListener.
You might want to try to add an anonymous listener to your JMenuItems that updates attributes of you class to perform the calculation.
Edit: Check Holger's answer for a nice solution :)
This way you can access the outer components or better delegate this to a model class.
See here: https://www.codejava.net/java-core/the-java-language/java-8-lambda-listener-example

java index of selected item arraylist

In Java, I'm trying to identify which JComboBox within an ArrayList was just clicked on. Some of the code follows:
private ArrayList<JComboBox<String>> setTextBoxList;
// basic initialization
public void populateList() {
String str[] = {"one", "two"};
for(int i=0; i<2; i++) {
JComboBox<String> jcb = new JComboBox<String>(str);
setTextBoxList.add(new JComboBox<String>(str));
jcb.addActionListener(this);
}
}
public void actionPerformed(ActionEvent e) {
Object o = e.getSource();
if(o instanceof JComboBox) {
// here's where I'd like to see which box was just changed
System.out.println("change index "
+ setTextBoxList.indexOf((JComboBox)o) );
}
}
My problem is that when I click on and change one of the comboboxes, the index shown is always -1. I'd like to get the index of which box in the arraylist was just clicked on/changed. I get the same results w/o the explicit type-cast.
The problem is in this segment of code:
for(int i=0; i<2; i++) {
JComboBox<String> jcb = new JComboBox<String>(str);
setTextBoxList.add(new JComboBox<String>(str)); // <-- error!
jcb.addActionListener(this);
}
You are creating two JComboBoxes, and the one that gets the listener is not the one that is in the list. Try changing the code to:
for(int i=0; i<2; i++) {
JComboBox<String> jcb = new JComboBox<String>(str);
setTextBoxList.add(jcb); // changed line
jcb.addActionListener(this);
}

Getting value of String in Jlist

How can I get the value of an item in this case String item that has been added to a JList? What I meanV
String[] coinNames ={"Quarters","Dimes","Nickels","Pennies"};
JList coinList = new JList (coinNames);
coinList[0] == "Quarters" ???????
Since I clearly can't reference it like a normal array, how might I go about getting the string value of coinlist[0]?
This is a simple example to get just an index to your JList and display all your JList.
public static void main(String[] args) {
String[] coinNames ={"Quarters","Dimes","Nickels","Pennies"};
JList coinList = new JList (coinNames);
String myCoin = (String) coinList.getModel().getElementAt(0);
System.out.println(myCoin);
/* LIST AL YOUR COINNAMES */
System.out.println("\nCoinList\n");
for(int i =0; i < coinList.getModel().getSize(); i++){
System.out.println((String) coinList.getModel().getElementAt(i));
}
coinNames[0] = "My new Value"; // Edit your CoinNames at index 0
/* LIST AL YOUR NEW COINNAMES */
System.out.println("\nNew coinList edited\n");
for(int i =0; i < coinList.getModel().getSize(); i++){
System.out.println((String) coinList.getModel().getElementAt(i));
}
}
coinList.getModel().getElementAt(0);
pls read the manual: http://docs.oracle.com/javase/8/docs/api/javax/swing/JList.html#getModel--
EDIT: or simply take a look at the example at the op of the amnual page: http://docs.oracle.com/javase/8/docs/api/javax/swing/JList.html
// Create a JList that displays strings from an array
String[] data = {"one", "two", "three", "four"};
JList<String> myList = new JList<String>(data);
// Create a JList that displays the superclasses of JList.class, by
// creating it with a Vector populated with this data
Vector<Class<?>> superClasses = new Vector<Class<?>>();
Class<JList> rootClass = javax.swing.JList.class;
for(Class<?> cls = rootClass; cls != null; cls = cls.getSuperclass()) {
superClasses.addElement(cls);
}
JList<Class<?>> myList = new JList<Class<?>>(superClasses);
// The automatically created model is stored in JList's "model"
// property, which you can retrieve
ListModel<Class<?>> model = myList.getModel();
for(int i = 0; i < model.getSize(); i++) {
System.out.println(model.getElementAt(i));
}

Edit an object in an ArrayList (Java Swing/GUI)

I'm currently working on a simple GUI system in Java using Swing and I am trying to edit a Passenger. The passenger is an object that is stored in an arrayList. There is inheritance involved so there is also multiple classes involved. The code I currently have for the edit method is for from perfect eg If/Elses may not actually work but all I require is advice on how to get the actual method going/working.
Firstly, the Passenger inherits its details from 3 classes, Person, Date and Name. The details of the passenger are the unique ID which auto increments, the Title, Firstname, Surname, DOB (Day, month, year), number of bags and priority boarding. Here is the code where the passenger inherits the details.
public Passenger(String t, String fN, String sn, int d, int m, int y, int noB, boolean pB)
{
// Call super class constructor - Passing parameters required by Person
super(t, fN, sn, d, m, y);
// And then initialise Passengers own instance variables
noBags = noB;
priorityBoarding = pB;
}
I then have a PassengerFileHandler class that has all the methods that I will need for the GUI aspect of things eg Add/Delete passenger etc etc. Here is my edit method that I have in my PassengerFileHandler class. This is most likely where the problem starts, I believe this is the correct way to make a method for the purpose of editing an object.
public Passenger editForGUI(int id, Passenger passenger)
{
for (Passenger passengerRead : passengers)
{
if (id == passengerRead.getNumber())
{
passengers.set(id, passenger);
}
}
return null;
}
I then go into my actual frame class that I have where I make the GUI and call the methods. To call the methods I made an instance of the passengerFileHandler class by typing the following
final PassengerFileHandler pfh = new PassengerFileHandler();
Here is where I make the Edit button and do the ActionListener for the JButton.
btnEditAPassenger.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
try
{
editPanel = new JPanel();
editPanel.setLayout(new GridLayout(9, 2));
editPanel.setPreferredSize(new Dimension(280, 280));
//Add radiobutton for priority
JRadioButton yes1 = new JRadioButton();
yes1.setText("Yes");
JRadioButton no1 = new JRadioButton();
no1.setText("No");
ButtonGroup group1 = new ButtonGroup();
group1.add(yes1);
group1.add(no1);
//Make an panel for the RadioButtons to be horizontal
radioButtonPanel1 = new JPanel();
radioButtonPanel1.setLayout(new GridLayout(1, 2));
radioButtonPanel1.setPreferredSize(new Dimension(40, 40));
radioButtonPanel1.add(yes1);
radioButtonPanel1.add(no1);
//title is a comboBox that is auto filled
editPanel.add(new JLabel("Title : "));
editPanel.add(editTitleComboBox = new JComboBox<String>());
editTitleComboBox.addItem("Mr");
editTitleComboBox.addItem("Ms");
editTitleComboBox.addItem("Mrs");
editTitleComboBox.addItem("Miss");
//Add the firstName textfield
editPanel.add(new JLabel("First name : "));
editPanel.add(editFirstNameText = new JTextField(20));
//Add the surname textfield
editPanel.add(new JLabel("Surname : "));
editPanel.add(editSurNameText = new JTextField(20));
//Day is a comboBox that is auto filled
editPanel.add(new JLabel("Day : "));
editPanel.add(editDayComboBox = new JComboBox<Integer>());
int days = 0;
for(int i = 0; i < 31; i++)
{
days++;
editDayComboBox.addItem(days);
}
//Month is a comboBox that is auto filled
editPanel.add(new JLabel("Month : "));
editPanel.add(editMonthComboBox = new JComboBox<Integer>());
int months = 0;
for(int i = 0; i < 12; i++)
{
months++;
editMonthComboBox.addItem(months);
}
//Year is a comboBox that is auto filled
editPanel.add(new JLabel("Year : "));
editPanel.add(editYearComboBox = new JComboBox<Integer>());
int yearNum = 2014 + 1 ;
for(int i = 1900; i < yearNum; i++)
{
editYearComboBox.addItem(i);
}
//NumberOfBags is a comboBox that is auto filled
editPanel.add(new JLabel("Number of Bags : "));
editPanel.add(editBagsComboBox = new JComboBox<Integer>());
int bags = 0;
for(int i = 0; i < 10; i++)
{
bags++;
editBagsComboBox.addItem(bags);
}
//Priority booking is a button group
editPanel.add(new JLabel("Priority boarding : "));
editPanel.add(radioButtonPanel1);
String input1 = JOptionPane.showInputDialog(null,"Enter the ID of the passenger you wish to edit: ");
if (input1 == null)
{
JOptionPane.showMessageDialog(null,"You have decided not to edit a Passenger");
}
if (input1.length() <1)
{
JOptionPane.showMessageDialog(null,"Invalid entry");
}
if (input1 != null)
{
// Put a Border around the Panel
editPanel.setBorder(new TitledBorder("Edit Passenger Details"));
//Make custom buttons
Object[] customButtonSet1 = {"Edit Passenger", "Cancel"};
int customButtonClick1 = JOptionPane.showOptionDialog(null,editPanel,"Edit", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, customButtonSet1, customButtonSet1[1]);
if(customButtonClick1 == JOptionPane.YES_OPTION)
{
try
{
if(pfh.passengers.contains(Integer.valueOf(input1)))
{
Passenger myObj = pfh.passengers.get(Integer.valueOf(input1));
//Passenger passenger1 = pfh.list().get(String.valueOf(pfh.passengers.equals(input1))))
//JOptionPane.showMessageDialog(null, "Succesfully edited the Passenger");
String title1 = String.valueOf(editTitleComboBox.getSelectedItem());
String firstName1 = String.valueOf(editFirstNameText.getText());
String surName1 = String.valueOf(editSurNameText.getText());
int day1 = Integer.valueOf(editDayComboBox.getSelectedItem().toString());
int month1 = Integer.valueOf(editMonthComboBox.getSelectedItem().toString());
int year1 = Integer.valueOf(editYearComboBox.getSelectedItem().toString());
int numBags1 = Integer.valueOf(editBagsComboBox.getSelectedItem().toString());
boolean priority1;
//Method to get the boolean
if(yes1.isSelected())
{
priority1 = true;
}
else
{
priority1 = false;
}
myObj.setName(new Name(title1, firstName1, surName1));
myObj.setDateOfBirth(new Date(day1, month1, year1));
myObj.setNoBags(numBags1);
myObj.setPriorityBoarding(priority1);
//Makes the toString clean
String formatedString = (pfh.passengers.toString().replace("[", "").replace("]", "").trim());
//refreshes the textArea and auto fills it with the current ArrayList
textArea.setText("");
textArea.append(formatedString);
}
else
{
JOptionPane.showMessageDialog(null, "Passenger does not exist");
}
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
else
{
JOptionPane.showMessageDialog(null, "Passenger does not exist");
}
if(customButtonClick1 == JOptionPane.CANCEL_OPTION || customButtonClick1 == JOptionPane.NO_OPTION)
{
JOptionPane.showMessageDialog(null, "You have decided not to Edit a Passenger");
}
}
}
catch (Exception ex)
{
// do nothing
}
}
});
I am pretty sure that one of the bigger issues is that when I do the code where I ask the user for the ID of the passenger they wish to edit it doesn't actually check if the Passenger exists correctly. I also understand that I don't actually even call the edit method but I couldn't get it working using the method either.
Here are images to help you understand what the GUI looks like and what the code may/may not be doing. Image 1 is the GUI and how it looks with the buttons. Image 2 is when you click the "Edit" button, the ID request pops up. Image 3 is where the user attempts to set the new passenger data.
Simple enough it's with strings but I think the issue is you don't know how to really use an arraylist.
public String[] currentArray = { "temp", "temp1", "temp3"};
public void addToList(String tobeadded) {
ArrayList<String> temp = new ArrayList<String>();
for(String s: currentArray) {
temp.add(s);
}
temp.add(tobeadded);
currentArray = temp.toArray(new String[temp.size()]);
}
public void removeFromList(String toRemove) {
ArrayList<String> temp = new ArrayList<String>();
for(String s: currentArray) {
if(!toRemove.equals(s))
temp.add(s);
}
currentArray = temp.toArray(new String[temp.size()]);
}
public void edit(String orginal, String new1) {
ArrayList<String> temp = new ArrayList<String>();
for(String s: currentArray) {
if(!orginal.equals(s))
temp.add(s);
}
temp.add(new1);
currentArray = temp.toArray(new String[temp.size()]);
}
i am not sure about your editForGUI method a it is not very clear. I am assuming that when you update the passenger details and click on edit passenger, it should update list.. If that is the case then try this..
If you are using updatedPassenger and Passsenger list as parameters in your method then the following will work
`
void editForGUI(Passenger updatedObject, List passengers){
for(int i=0; i<passengers.size; i++){
Passenger p = passengers.get(i);
if( p.getId() == updatedPassenger.getId()){
passengers.set(i, updatedObject);
return;
}
}
}
`
Why don't you use HashMap in place of list? In-place update would be more efficient. id will be key and Passenger object will be the value in HashMap..
I believe your ArrayList problem is in this line:
passengers.set(id, passenger);
At this point, you have found the passenger that matches the id and you want to replace it. If you take a look at the ArrayList documentation, the method signature for set is
set(int index, E element)
The first parameter you pass is the index you want to set, not the id. However, since you used the enhanced for loop to iterate through the ArrayList, you don't know the index. You can call the indexOf() method to get the index using the passenger that you found, but that would be inefficient since you just iterated through the array and the method call would basically repeat everything you just did to get the index. Instead you can keep a counter that increments after the if check, and once you have found it, the counter is set to the index of your item. Inside your if block, you can immediately set your passenger using that index and return right after.

Categories

Resources