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

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.

Related

Changing a String array for a JComboBox depending on another value in another ComboBox

I'm trying to create a Combobox, where, when a value is changed in the first Combobox, in this case which is "FlightNumber", to change the String array in another Combobox in the same window, which is "Baggage" depending on which value is selected in the FlightNumber Combobox.
Every time I try to do this, the program hangs after selecting a Flight number from the drop down menu.
private void jComboBox_flightNumberActionPerformed(java.awt.event.ActionEvent evt) {
int number = Integer.parseInt((String)jComboBox_flightNumber.getSelectedItem());
boolean found = false;
int baggageSize = 0;
int counter;
System.out.println(this.flightList.size());
System.out.println(number);
for(counter = 0; counter < this.flightList.size() || !found; counter++){
Flight flight = this.flightList.get(counter);
if(flight.getFlightID() == number) {
found = true;
baggageSize = flight.getBaggage();
System.out.println(baggageSize);
}else{
found = false;
}
}
String [] baggageLength = new String[baggageSize];
for(int x = 0;counter < baggageLength.length; x++) {
baggageLength[counter] = Integer.toString((x+1));
}
this.baggageSize = baggageLength;
jComboBox_baggage.setModel(new javax.swing.DefaultComboBoxModel<>(this.baggageSize));
jComboBox_baggage.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jComboBox_baggageActionPerformed(evt);
}
});
}

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

How to hide Selection in JList

I create several JLists by using DefaultListmModel, so I can add, edit and delete items in those JLists.
How can I hide the selection the user made?
So like the user clicks in JList 1 to edit the value with index 2 by double clicking on the item. So now the item with index value 2 is selected in the UI and it's blue.
My Question is: How can I hide this, so after editing/adding items in the JList, what do I have to do that the item which was selected isn't blue, so that you can't see what you selected before.
clearSelection() isn't working.
My code is the following (I shortened the JOptionPane stuff and the if else part):
for (int i=0; i < StringArray.length; i++) {
DefaultListModel<String> model = new DefaultListModel<String>();
for (int j=0; j < StringArray[i].length; j++) {
model.addElement(StringArray[i][j]);
if((StringArray[i].length -1)== j) {
listbox = new JList<String>(model);
Panel.add(listbox);
listbox.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2) {
int index = listbox.locationToIndex(e.getPoint());
Object[] options = {"Add", "Edit", "Delete"};
//.... JOptionPane
if (ADDING) {
String tmpAddValue = JOptionPane...
model.addElement(tmpAddValue);
}
else if (EDITING) {
String tmpValue = JOptionPane...
model.setElementAt(tmpValue, index);
}
else if (DELETING) {
model.removeElementAt(index);
}
else {
System.out.println("No Button pushed");
}
listbox.clearSelection();
}
}
});
}
}
Thanks

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.

Best way to have a JTable populate with objects?

Let's say I have an array of People. These people have a bunch of fields like name, position, title, salary.
I've seen most questions be about filling a JTable with 2D arrays which, unless I'm wrong, isn't exactly what I'm trying to do.
I would like to be able to click a button and have the JTable look at the array of People and display that table.
Thanks!
Edit: I'm hoping to be able to just change the setModel arguments here to update using certain values.
JButton btnRefresh = new JButton("Refresh");
btnRefresh.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent arg0) {
table_1.setModel(new DefaultTableModel(new Object[][] {}, new String[] {
"#", "Song", "Artist", "Time" }));
table_1.getColumnModel().getColumn(0).setPreferredWidth(22);
table_1.getColumnModel().getColumn(1).setPreferredWidth(191);
table_1.getColumnModel().getColumn(2).setPreferredWidth(179);
panel_3.revalidate();
}
});
So I'm able to change the column headers by changing these string values but what can I change the new Object[][]{} to?
This code fragment does exactly what I needed it to do.
JButton btnRefresh = new JButton("Refresh");
btnRefresh.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent arg0) {
table.setModel(new DefaultTableModel(dataArray(),
new String[] { "first", "second", "third", "fourth" }));//Changes the column headers
panel.revalidate();
}
private Object[][] dataArray() {
Object[][] table = new Object[5][4];//5 = rows 4 = columns
for (int i = 0; i < 5; i++) {
for(int j = 0; j< 4; j++){
if(j == 0){
table[i][j] = i+1;
}else if(j== 1){
table[i][j] = "Second Row";//Change these strings to whatever variable you want to fill the second row with, same with the other 3.
}else if(j== 2){
table[i][j] = "Third Row";
}else{
table[i][j] = "Fourth Row";
}
}
}
return table;
}
});

Categories

Resources