0

I want to add JLabels like "granulatedSugar" or "allPurposeFlour" to multiple different JPanels like "browniesIngredients" or "banaBreadIngredients". However my issue is when I run the code the JLabels that are used in different JPanels don't show up on the JPanels when selected from the "foodList" JComboBox. For example, when I click on "Brownies" from the JComboBox all I get are JLabels that are exclusive to that JPanel (like "cocoaPowder" and "instantEspresso") and none of the other ingredients like "allPurposeFlour" or "granulatedSugar".

package sweets;

import javax.swing.*;
import java.awt.*;
import java.awt.BorderLayout;
import javax.swing.ImageIcon;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import java.awt.Component;
import java.awt.Font;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import javax.swing.JList;
import javax.swing.ListCellRenderer;

public class mainIA<l> extends JFrame implements ItemListener {

    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;

    ImageIcon[] items;
    String[] food = {bananaBread, brownies, chocolateChipcookies, macarons};
    JPanel ingredients;
    final static String bananaBread = "banana bread";
    final static String brownies = "brownies";
    final static String chocolateChipcookies = "chocolate chip cookies";
    final static String macarons = "macarons";
    JButton incButton = new JButton("+");

    JPanel bananaBreadIngredients = new JPanel(new BorderLayout());
    JPanel browniesIngredients = new JPanel(new BorderLayout());
    JPanel cookieIngredients = new JPanel(new BorderLayout());
    JPanel macaronIngredients = new JPanel(new BorderLayout());

    //ingredients JLabels
    //15 Ingredients
    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));

    JComboBox foodList;
    JLabel ingredientLabel = new JLabel("Ingredients Go here: ");

    public mainIA() {
        super("Recipe Portion Calculator");
        Container c = getContentPane();
        c.setLayout(new GridLayout(4, 1));

        JPanel recipe = new JPanel();
        recipe.setLayout(new FlowLayout());

        JLabel recipes = new JLabel("Recipes:");
        recipe.add(recipes);

        //this is my code for the comboBox
        //Links to sources used:
        //https://stackoverflow.com/questions/3958647/displaying-images-in-jcombobox
        //http://www.java2s.com/Code/Java/Swing-JFC/CustomComboBoxwithImage.htm
        items = new ImageIcon[food.length];
        Integer[] intArray = new Integer[food.length];
        for (int i = 0; i < food.length; i++) {
            intArray[i] = i;
            items[i] = createImageIcon("sweets/" + food[i] + ".jpeg");
            if (items[i] != null) {
                items[i].setDescription(food[i]);
            }
        }

        ingredients = new JPanel(new CardLayout());
        ingredients.add(ingredientLabel);
        //only works if you add the cards in the same order that they are put in in the array
        ingredients.add(bananaBreadIngredients, bananaBread );
        ingredients.add(browniesIngredients, brownies);
        ingredients.add(cookieIngredients, chocolateChipcookies);
        ingredients.add(macaronIngredients, macarons);

        foodList = new JComboBox(food);
        foodList.setEditable(false);
        foodList.addItemListener(this);
        ComboBoxRenderer renderer= new ComboBoxRenderer();
        getContentPane().add(foodList, BorderLayout.NORTH);
        getContentPane().add(ingredients, BorderLayout.CENTER);
        recipe.add(foodList);
        //end of code for JComboBox

        //bananaBread Ingredients JPanel
        bananaBreadIngredients.setLayout(new GridLayout(8,1));
        bananaBreadIngredients.add(bananas);
        bananaBreadIngredients.add(unsaltedButter);
        bananaBreadIngredients.add(granulatedSugar);
        bananaBreadIngredients.add(eggs);
        bananaBreadIngredients.add(allPurposeFlour);
        bananaBreadIngredients.add(bakingSoda);
        bananaBreadIngredients.add(salt);
        bananaBreadIngredients.add(vanillaExtract);

        //brownies ingredients JPanel
        browniesIngredients.setLayout(new GridLayout(11,2));
        browniesIngredients.add(instantEspresso);
        browniesIngredients.add(vegetableOil);
        browniesIngredients.add(cocoaPowder);
        browniesIngredients.add(bakingPowder);
        browniesIngredients.add(unsaltedButter);
        browniesIngredients.add(chocolateChips);
        browniesIngredients.add(eggs);
        browniesIngredients.add(granulatedSugar);
        browniesIngredients.add(vanillaExtract);
        browniesIngredients.add(allPurposeFlour);
        browniesIngredients.add(salt);

        //chocolate chip cookie ingredients JPanel
        cookieIngredients.setLayout(new GridLayout(9,1));
        cookieIngredients.add(unsaltedButter);
        cookieIngredients.add(granulatedSugar);
        cookieIngredients.add(lightBrownSugar);
        cookieIngredients.add(eggs);
        cookieIngredients.add(vanillaExtract);
        cookieIngredients.add(allPurposeFlour);
        cookieIngredients.add(bakingSoda);
        cookieIngredients.add(salt);
        cookieIngredients.add(chocolateChips);

        //macaron ingredients JPanel
        macaronIngredients.setLayout((new GridLayout(5,1)));
        macaronIngredients.add(eggWhites);
        macaronIngredients.add(granulatedSugar);
        macaronIngredients.add(powderedSugar);
        macaronIngredients.add(almondFlour);
        //ingredients
        ingredientLabel.setLayout(new GridLayout(1,2));

        JPanel servings = new JPanel();
        servings.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
        servings.add(new JLabel("Number of Servings: "));
        JLabel counterLbl = new JLabel(Integer.toString(servingNumber));
        JButton decButton = new JButton(("-"));
        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("");
        servings.add(space);
        servings.add(decButton);
        servings.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));
        });
        servings.add(incButton);
        //end of use of code from Quora Link

        JPanel inputRecipe = new JPanel();
        inputRecipe.setLayout(new GridLayout(2, 1));

        inputRecipe.add(new JLabel("Input Recipe From Internet: "));
        inputRecipe.add(new JTextField(" "));

        c.add(recipe);
        c.add(servings);
        c.add(ingredients);
        c.add(inputRecipe);
    }

    public static ImageIcon createImageIcon(String path) {
        java.net.URL imgURL = mainIA.class.getResource(path);
        if (imgURL != null) {
            return new ImageIcon(imgURL);
        } else {
            System.err.println("Couldn't find file: " + path);
            return null;
        }
    }
    class ComboBoxRenderer extends JLabel implements ListCellRenderer {
        private Font uhOhFont;
        public ComboBoxRenderer() {
            setOpaque(true);
            setHorizontalAlignment(CENTER);
            setVerticalAlignment(CENTER);
        }
        public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
            int selectedIndex = ((Integer)value).intValue();
            if (isSelected) {
                setBackground(list.getSelectionBackground());
                setForeground(list.getSelectionForeground());
            } else {
                setBackground(list.getBackground());
                setForeground(list.getForeground());
            }
            ImageIcon icon = items[selectedIndex];
            String foods = food[selectedIndex];
            setIcon(icon);
            if (icon != null) {
                setText(foods);
                setFont(list.getFont());
            } else {
                setUhOhText(foods + " (no image available)", list.getFont());
            }
            return this;
        }
        protected void setUhOhText(String uhOhText, Font normalFont) {
            if (uhOhFont == null) {
                uhOhFont = normalFont.deriveFont(Font.ITALIC);
            }
            setFont(uhOhFont);
            setText(uhOhText);
        }
        //I am using actionPerformed method. This is the code I plan to use to output the images for the respective options
    }

    //recipes used from Natasha's kitchen
    //https://natashaskitchen.com/

    //sources used: https://docs.oracle.com/javase/tutorial/uiswing/events/actionlistener.html
    //https://docs.oracle.com/javase/tutorial/uiswing/events/itemlistener.html
    //card layout: https://docs.oracle.com/javase/tutorial/uiswing/layout/card.html
    //item event for the JComboBox
    public void itemStateChanged(ItemEvent evt) {
        CardLayout cl = (CardLayout)(ingredients.getLayout());
        cl.show(ingredients, (String)evt.getItem());
    }

    public static void main(String[] args) {
        mainIA window = new mainIA();
        window.setVisible(true);
        window.setBounds(100, 100, 800, 800);
    }
}

Any help would be greatly appreciated!

  • 3
    *"I want to add JLabels ... to multiple different JPanels"* - you can't or at least you can't add the SAME instance of the labels to different panels. A Swing component can only reside in a single container. Instead, you need to use a "model" of some kind which contains the information you want to present and then you pass this to each of your views. This is a core concept in the "model-view-controller" workflow – MadProgrammer Jul 17 '23 at 22:01
  • 2
    Since labels are static (in the sense that they don't change), it might seem that you can use them in multiple locations. Unfortunately the `JLabel` class as a whole is not immutable, it has fields that can be set, and those fields will mess up any attempt to use a label in multiple locations. (Its mutable fields includes its "bounds", the X-Y position on the screen, and it should be obvious from that alone that you can't have one object with two X-Y positions, that a singe JLabel won't work.) – markspace Jul 18 '23 at 04:09

0 Answers0