I know that something similar has been asked before on this thread here: Access JLabel from another class However when I tried using the "this.lblNewLabel = new JLabel();" for all my JLabels in my code but it didn't work. My problem is that I am trying to get the JLabels from "MainFrame" to be accessed by "bananaBreadIngredients" and by "ServingsButtons" so that the action Listener from "ServingsButtons" can work on the components in "bananaBreadIngredients" and I need help trying to get that work. If their is anything that doesn't make sure I'll try to answer any questions about my code that I can.
Here is my main JFrame code (this is the code where I thought would be best to put the JLabels as I thought that they would be able to be accessed by other classes like the "bananaBreadIngredients" class):
package sweets;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
public class MainFrame extends JFrame implements ItemListener {
//all the foods
public int servingNumber = 0;
//ingredient Volumes
public int almondFlourVol = 0;
public int allPurposeFlourVol = 0;
public int unsaltedButterVol = 0;
public int bakingSodaVol = 0;
public int bakingPowderVol = 0;
public int vanillaExtractVol = 0;
public int cocoaPowderVol = 0;
public int saltVol = 0;
public int chocolateChipsVol = 0;
public int instantEspressoVol = 0;
public int vegetableOilVol = 0;
public int bananasVol = 0;
//sugars
public int granulatedSugarVol = 0;
public int powderedSugarVol = 0;
public int lightBrownSugarVol = 0;
//eggs
public int eggsVol = 0;
public int eggWhitesVol = 0;
JLabel granulatedSugar = new JLabel("Granulated Sugar: " + (granulatedSugarVol));
JLabel powderedSugar = new JLabel("Powdered Sugar: " + (powderedSugarVol));
JLabel lightBrownSugar = new JLabel("Light Brown Sugar: " + (lightBrownSugarVol));
JLabel eggs = new JLabel("Eggs: " + (eggsVol));
JLabel eggWhites = new JLabel("Egg Whites: " + (eggWhitesVol));
JLabel bananas = new JLabel("Bananas: " + (bananasVol));
JLabel vegetableOil = new JLabel("Vegetable Oil: " + (vegetableOilVol));
JLabel instantEspresso = new JLabel("Instant Espresso: " + (instantEspressoVol));
JLabel chocolateChips = new JLabel("Chocolate Chips: " + (chocolateChipsVol));
JLabel salt = new JLabel("Salt: " + (saltVol));
JLabel cocoaPowder = new JLabel("Cocoa Powder: " + (cocoaPowderVol));
JLabel vanillaExtract = new JLabel("Vanilla Extract: " + (vanillaExtractVol));
JLabel bakingSoda = new JLabel("Baking Soda: " + (bakingSodaVol));
JLabel unsaltedButter = new JLabel("Unsalted Butter: " + (unsaltedButterVol));
JLabel allPurposeFlour = new JLabel("All-Purpose Flour: " + (allPurposeFlourVol));
JLabel almondFlour = new JLabel("Almond Flour: " + (almondFlourVol));
JLabel bakingPowder = new JLabel("Baking Powder: " + (bakingPowderVol));
String[] food = {bananaBread, brownies, chocolateChipcookies, macarons};
final static String bananaBread = "banana bread";
final static String brownies = "brownies";
final static String chocolateChipcookies = "chocolate chip cookies";
final static String macarons = "macarons";
JPanel ingredients;
private ServingButtons servingButtonsJPanel;
private bananaBreadIngredients bananaBreadIngredientsJPanel;
JPanel browniesIngredients = new JPanel(new BorderLayout());
JPanel cookieIngredients = new JPanel(new BorderLayout());
JPanel macaronIngredients = new JPanel(new BorderLayout());
public MainFrame(){
JPanel recipeName = new JPanel(); //this will have the JComboBox with the foodList
JLabel recipe = new JLabel("Recipes: ");
recipeName.setLayout(new FlowLayout());
recipeName.add(recipe);
JComboBox foodList = new JComboBox(food);
foodList.setEditable(false);
foodList.addItemListener(this);
ingredients = new JPanel(new CardLayout());
//MainFrame.ComboBoxRenderer renderer= new MainFrame.ComboBoxRenderer();
getContentPane().add(foodList, BorderLayout.NORTH);
recipeName.add(foodList);
//Servings buttons
servingButtonsJPanel = new ServingButtons(); //<<-- method call
servingButtonsJPanel.setLayout(new GridLayout(1,1));
//sources used from this: https://stackoverflow.com/questions/29477242/jpanel-and-custom-class-extending-jpanel-not-displaying-correctly
JLabel ingredientLabel = new JLabel("Ingredients Go here: ");
bananaBreadIngredientsJPanel = new bananaBreadIngredients();
ingredients.add(ingredientLabel);
//only works if you add the cards in the same order that they are put in in the array
ingredients.add(bananaBreadIngredientsJPanel, bananaBread );
ingredients.add(browniesIngredients, brownies);
ingredients.add(cookieIngredients, chocolateChipcookies);
ingredients.add(macaronIngredients, macarons);
getContentPane().add(ingredients, BorderLayout.CENTER);
//this will have the dynamically changing ingredients (placeholder: the code for this in the mainIA class but it is not being used as I want to implement it through a class instead of having it in the constructor class like in the mainIA)
JLabel inputRecipe = new JLabel("Input Recipe"); //this will have the input recipe JTextField (placeholder)
this.setTitle("Recipe Portion Calculator");
this.setLayout(new GridLayout(4,1));
this.setSize(800,800);
this.add(recipeName);
this.add(servingButtonsJPanel); //<<-- issue is that I have a GUI in the ServingButtons class but when I call it in the MainFrame class it does not show up in the GUI
this.add(ingredients);
this.add(inputRecipe);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setVisible(true);
}
public void itemStateChanged(ItemEvent evt) {
CardLayout cl = (CardLayout)(ingredients.getLayout());
cl.show(ingredients, (String)evt.getItem());
}
}
Here is the class for ServingsButtons. This class has the increment action listener that is applied to the different JLabels:
package sweets;
import javax.swing.*;
import java.awt.*;
public class ServingButtons extends JPanel {
public int servingNumber = 0;
//ingredient Volumes
JButton incButton = new JButton("+");
JButton decButton = new JButton(("-"));
public ServingButtons() {
super();
this.setLayout(new GridLayout(1, 4));
//used this code from this Quora Link: https://www.quora.com/How-would-I-get-my-program-to-add-1-every-time-I-press-the-button-%E2%80%9Da%E2%80%9D-in-Java
this.add(new JLabel("Number of Servings: "));
JLabel counterLbl = new JLabel(Integer.toString(servingNumber));
decButton.addActionListener(l -> {
counterLbl.setText(Integer.toString(--servingNumber));
almondFlour.setText("Almound Flour: " + (--almondFlourVol));
granulatedSugar.setText("Granulated Sugar: " + (--granulatedSugarVol));
powderedSugar.setText("Powdered Sugar: " + (--powderedSugarVol));
lightBrownSugar.setText("Light Brown Sugar: " +(--lightBrownSugarVol));
eggs.setText("Eggs: " + (--eggsVol));
eggWhites.setText("Egg Whites: " + (--eggWhitesVol));
bananas.setText("Bananas: " + (--bananasVol));
vegetableOil.setText("Vegetable Oil: " + (--vegetableOilVol));
instantEspresso.setText("Instant Espresso: " + (--instantEspressoVol));
chocolateChips.setText("Chocolate Chips: " + (--chocolateChipsVol));
salt.setText("Salt: " + (--saltVol));
cocoaPowder.setText("Cocoa Powder: " + (--cocoaPowderVol));
vanillaExtract.setText("Vanilla Extract: " + (--vanillaExtractVol));
bakingSoda.setText("Baking Soda: " + (--bakingSodaVol));
unsaltedButter.setText("Unsalted Butter: " + (--unsaltedButterVol));
allPurposeFlour.setText("All-Purpose Flour: " + (--allPurposeFlourVol));
bakingPowder.setText("All-Purpose Flour: " + (--bakingPowderVol));
});
JLabel space = new JLabel("");
this.add(space);
this.add(decButton);
this.add(counterLbl);
incButton.addActionListener(l -> {
counterLbl.setText(Integer.toString(++servingNumber));
granulatedSugar.setText("Granulated Sugar: " + (++granulatedSugarVol));
powderedSugar.setText("Powdered Sugar: " + (++powderedSugarVol));
lightBrownSugar.setText("Light Brown Sugar: " + (++lightBrownSugarVol));
eggs.setText("Eggs: " + (++eggsVol));
eggWhites.setText("Egg Whites: " + (++eggWhitesVol));
bananas.setText("bananas: " + (++bananasVol));
vegetableOil.setText("Vegetable Oil: "+ (++vegetableOilVol));
instantEspresso.setText("instant Espresso: " + (++instantEspressoVol));
chocolateChips.setText("Chocolate Chips: "+ (++chocolateChipsVol));
salt.setText("Salt: " + (++saltVol));
cocoaPowder.setText("Cocoa Powder: " + (++cocoaPowderVol));
vanillaExtract.setText("Vanilla Extract: " + (++vanillaExtractVol));
bakingSoda.setText("Baking Soda: " + (++bakingSodaVol));
unsaltedButter.setText("Unsalted Buttter: " + (++unsaltedButterVol));
allPurposeFlour.setText("All-Purpose Flour: " + (++allPurposeFlourVol));
almondFlour.setText("Almound Flour: " + (++almondFlourVol));
bakingPowder.setText("All-Purpose Flour: " + (++bakingPowderVol));
});
this.add(incButton);
}
}
here is the code for the class that I want to have access to the JLabels so that the code from "ServingsButtons" applies to the code on this class:
package sweets;
import javax.swing.*;
import java.awt.*;
public class bananaBreadIngredients extends JPanel {
public bananaBreadIngredients(){
super();
this.setLayout(new GridLayout(9,1));
this.add(bananas);
this.add(unsaltedButter);
this.add(granulatedSugar);
this.add(allPurposeFlour);
this.add(bakingSoda);
this.add(salt);
this.add(vanillaExtract);
}
}
Any help would be much appreciated. Thankyou!
To answer your immediate question, you have the aforementioned labels set as package-private, meaning that they do not have an access modifier in front of them. Because of this, all of the classes in the
sweetspackage have access to the labels, because those labels are package-private.So, you can do something as simple as this.
In your
MainFrameclass, you currently have this line.bananaBreadIngredientsJPanel = new bananaBreadIngredients();Well, change the constructor to take in an instance of
MainFrame.Meaning, you currently have this constructor in your
bananaBreadIngredientsclass.public bananaBreadIngredients()Well, just change it to be like this instead.
public bananaBreadIngredients(MainFrame mainFrame)Once you have done that, then your
bananaBreadIngredientsclass now has access to everyJLabelinMainFramethat is set to package-private. In fact, it has access to every Class Variable that is also set to package-private, amongst other things (that aren't relevant right now).So, to access each desired
JLabelfromMainFrame, simply reference it using the passed in instance ofMainFramein your newly modified constructor, like this.This should do it.
But I have to say, your current class structure and organization is going to get unwieldy very quickly (even more so after the answer I gave you).
I would strongly encourage you to work on improving your use of strategies like loose-coupling and Java enums. The strategy you have now will bite you in the butt, assuming that it isn't already doing that.