So I have a JComboBox, which contains recipe names. I want, when the recipe name is changed, for the label that is an icon of the rating (1 to 5) stars, based on my recipe object, to change as well.

My code seems like it should work perfect but it doesn't. Any help please?

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;

import javax.swing.BoxLayout;
import javax.swing.DefaultComboBoxModel;
import javax.swing.ImageIcon;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.WindowConstants;

// GUI Class
// Will contain all the code that will display my GUI
// Will use the recipe class.

public class gui {
	
	recipe test = new recipe();	
	
	DefaultComboBoxModel recipeNames = new DefaultComboBoxModel();
	ArrayList<recipe> recipes = new ArrayList<recipe>();
	ArrayList<String> recipeNamesArray = new ArrayList<String>();
	
	ImageIcon stars0 = createImageIcon("amazonstar0C.gif");
	ImageIcon stars1 = createImageIcon("amazonstar1C.gif");
	ImageIcon stars2 = createImageIcon("amazonstar2C.gif");
	ImageIcon stars3 = createImageIcon("amazonstar3C.gif");
	ImageIcon stars4 = createImageIcon("amazonstar4C.gif");
	ImageIcon stars5 = createImageIcon("amazonstar5C.gif");
	
	JLabel ratingImage = new JLabel();
	JComboBox recipeList = new JComboBox(recipeNames);
	
	// Constructor will initialize everything.
	public gui() {
		
	test.setName("test");
	test.setRating(3);
	test.addIngredient("1/4 cup milk");
	test.addDirection("Get milk.");
	test.setNote("testNote");
	test.setPeople(4);
	test.setTime("00:01");
	
	recipes.add(test);
	recipeNamesArray.add(test.getName());
	recipeNames.addElement(test.getName());
	
	// The main JFrame that will hold my whole GUI.
	JFrame main = new JFrame("E-Chef");
	
	// The main tabbed pane that will run my program.
	// Everything is done from this.
	JTabbedPane menu = new JTabbedPane();
	
	// All 3 panels for each tab.
	JPanel mainMenu = new JPanel();
	mainMenu.setLayout(new BoxLayout(mainMenu, BoxLayout.X_AXIS));
	
	JPanel add = new JPanel();
	JPanel search = new JPanel();
	
	// All 3 tabbed icons.
	ImageIcon icon1 = createImageIcon("menucooking.png");
	ImageIcon icon2 = createImageIcon("addcooking.png");
	ImageIcon icon3 = createImageIcon("searchcooking.png");
	
	// Each tab.
	menu.addTab("Main", icon1, mainMenu, "The Main Menu");
	menu.addTab("Add", icon2, add, "Add a Recipe");
	menu.addTab("Search", icon3, search, "Search for Recipe");
	
	// Panel 1 -- mainMenu
	// Creating two more panels.
	// One to store recipe info, the other to store 3 navigation buttons.
	JPanel recipeInfo = new JPanel();
	recipeInfo.setLayout(new BoxLayout(recipeInfo, BoxLayout.Y_AXIS));
	JPanel navigation = new JPanel();
	navigation.setLayout(new BoxLayout(navigation, BoxLayout.X_AXIS));
	// Add things to each panel.
	JLabel title = new JLabel("Recipe List");
	recipeList.setEditable(true);
	MyActionListener recipeChange = new MyActionListener();
	recipeList.addActionListener(recipeChange);
	JLabel rating = new JLabel("Rating");
	// Add things to recipeInfo
	recipeInfo.add(title);
	recipeInfo.add(recipeList);
	recipeInfo.add(rating);
	recipeInfo.add(ratingImage);
	// Add panels to mainMenu panel.
	mainMenu.add(recipeInfo);
	mainMenu.add(navigation);
	
	// Add tabbed pane to the frame.
	main.add(menu);
	
	// Setting the frame visible and displaying it.
	main.pack();
	main.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
	main.setVisible(true);
	}
	
	protected static ImageIcon createImageIcon(String path) {
        java.net.URL imgURL = gui.class.getResource(path);
        if (imgURL != null) {
            return new ImageIcon(imgURL);
        } else {
            System.err.println("Couldn't find file: " + path);
            return null;
        }
    }
	
	class MyActionListener implements ActionListener {
		  Object oldItem;

		  public void actionPerformed(ActionEvent evt) {
		    JComboBox cb = (JComboBox) evt.getSource();
		    String newItem = (String)cb.getSelectedItem();

		    int position = recipeNamesArray.indexOf(newItem);
		    int rating = recipes.get(position).getRating();
		    
		    switch (rating) {
            case 0:  ratingImage.setIcon(stars0); break;
            case 1:  ratingImage.setIcon(stars1); break;
            case 2:  ratingImage.setIcon(stars2); break;
            case 3:  ratingImage.setIcon(stars3); break;
            case 4:  ratingImage.setIcon(stars4); break;
            case 5:  ratingImage.setIcon(stars5); break;
            default: ratingImage.setIcon(stars0);break;
        }

		    
		  }
		}

}

Here is the code of my recipe class just in case you need to look at it. All my main class does is it creates a new instance of my gui class, that's it.

import java.util.ArrayList;

// Recipe Class
// Will contain code for recipe objects.
// These are the main objects that my system will implement.

public class recipe {
	
	// Each recipe has a name, which is a String.
	private String name = "";
	
	// Each recipe contains a list of ingredients.
	// Will use an ArrayList because of their functionality.
	private ArrayList<String> ingredients = new ArrayList<String>();
	
	// Another ArrayList will be used to contain each direction for making that recipe.
	private ArrayList<String> directions = new ArrayList<String>();
	
	// A String of notes for the recipe.
	// Things you should know that might not directly affect its outcome.
	private String notes = "";
	
	// Three Strings for the filename of each picture for the recipe.
	// A beginning picture of the ingredients, middle of the process, and finished recipe.
	// This will be optional.
	private String picFile1 = "";
	private String picFile2 = "";
	private String picFile3 = "";
	
	// Difficulty rating as an integer.
	private int difficulty = 0;
	
	// Time it takes to prepare the entire dish from beginning to end.
	// Usually an estimate.
	// Using a String for this because it should be in HH:MM format.
	private String time = "";
	
	// How many people does it serve on average?
	private int peopleServed = 0;
	
	// Recipe rating.
	private int rating = 0;
	
	// Class Functions //
	
	// The constructor will do nothing in this case.
	// All the attributes default values are set already.
	// Everything else will be set and retrieved through getters and setters.
	public recipe() {
		
	}
	
	// Getters and Setters //
	
	public String getName() {
		return name;
	}
	
	public void setName(String recipeName) {
		name = recipeName;
	}
	
	public void addIngredient(String newIngredient) {
		ingredients.add(newIngredient);
	}
	
	public void deleteIngredient(String removeIngredient) {
		int position = ingredients.indexOf(removeIngredient);
		ingredients.remove(position);
	}
	
	public int numIngredients() {
		return ingredients.size();
	}
	
	public String getIngredient(int number) {
		int index = number - 1;
		return ingredients.get(index);
	}
	
	public boolean hasIngredient(String thisIngredient) {
		return ingredients.contains(thisIngredient);
	}
	
	public void addDirection(String newDirection) {
		directions.add(newDirection);
	}
	
	public void deleteDirection(String removeDirection) {
		int position = directions.indexOf(removeDirection);
		directions.remove(position);
	}
	
	public int numDirections() {
		return directions.size();
	}
	
	public String getDirection(int number) {
		int index = number - 1;
		return directions.get(index);
	}
	
	public void setNote(String note) {
		notes = note;
	}
	
	public String getNote() {
		return notes;
	}
	
	public void setBeginningPic(String filename) {
		picFile1 = filename;
	}
	
	public void setMiddlePic(String filename) {
		picFile2 = filename;
	}
	
	public void setEndPic(String filename) {
		picFile3 = filename;
	}
	
	public String getBeginningPic() {
		return picFile1;
	}
	
	public String getMiddlePic() {
		return picFile2;
	}
	
	public String getEndPic() {
		return picFile3;
	}
	
	public void setDifficulty(int number) {
		difficulty = number;
	}
	
	public int getDifficulty() {
		return difficulty;
	}
	
	public void setTime(String length) {
		time = length;
	}
	
	public String getTimeDefault() {
		return time;
	}
	
	public int getTimeMinutes() {
		String hours = time.substring(0, 2);
		int intHours = Integer.valueOf( hours ).intValue();
		String minutes = time.substring(3, 5);
		int intMinutes = Integer.valueOf( minutes ).intValue();
		return ((intHours * 60) + intMinutes);
	}
	
	public void setPeople(int amount) {
		peopleServed = amount;
	}
	
	public int getPeople() {
		return peopleServed;
	}
	
	public void setRating(int number) {
		rating = number;
	}
	
	public int getRating() {
		return rating;
	}
}

? You only have one recipe entered. It won't change because there's nothing to change it to! Code in another recipe, with a different rating, and try then.

? You only have one recipe entered. It won't change because there's nothing to change it to! Code in another recipe, with a different rating, and try then.

But that one recipe that is in there has a rating of 3/5 stars. The initial rating picture the label uses is the 0/5 stars one. Shouldn't it load with the 3/5 stars picture from that code? Even if I go into the drop down list again, and click the same recipe, it should load the 3/5 stars picture shouldn't it?

But that one recipe that is in there has a rating of 3/5 stars. The initial rating picture the label uses is the 0/5 stars one. Shouldn't it load with the 3/5 stars picture from that code? Even if I go into the drop down list again, and click the same recipe, it should load the 3/5 stars picture shouldn't it?

It DOES change to three stars when you pull down the combo box and change it (I downloaded some PNG files. I assume GIF would work too). Your code is sort of hard to follow due to rating being a local variable of type int and also a JLabel or something somewhere else. And you also have a JLabel called ratingImage, where you do a switch on rating in actionPerformed. So some more descriptive variable names would be helpful. It's pretty confusing looking at a switch statement based on rating when I thought rating was a JLabel. That said, I don't think you are INITIALIZING any JLabels to contain stars, so they don't until you do the drop-down. I did have to RESIZE the frame in order to see the stars, but my PNG's were pretty big.

Also, I had to add a main () function.

It DOES change to three stars when you pull down the combo box and change it (I downloaded some PNG files. I assume GIF would work too). Your code is sort of hard to follow due to rating being a local variable of type int and also a JLabel or something somewhere else. And you also have a JLabel called ratingImage, where you do a switch on rating in actionPerformed. So some more descriptive variable names would be helpful. It's pretty confusing looking at a switch statement based on rating when I thought rating was a JLabel. That said, I don't think you are INITIALIZING any JLabels to contain stars, so they don't until you do the drop-down. I did have to RESIZE the frame in order to see the stars, but my PNG's were pretty big.

Also, I had to add a main () function.

yours changes? lol mine doesn't i dont know what you are doing differently,

you might want to try getting rid of the call to pack(), and use the setSize(int, int) method, there might not be enough room to see them

My changes were these. Changed this line:

ImageIcon stars3 = createImageIcon("amazonstar3C.gif");

to this:

ImageIcon stars3 = createImageIcon("amazonstar3C.png");

I did this because mine was a PNG image, not a GIF image. I would imagine you woulnd't need to if yours is a GIF.

I added this function in the gui class:

public static void main (String args[])
{
    new gui ();
}

I ran the code. I then resized the JFrame with a mouse drag to make it much bigger. I then pulled down the combo box, selected the one and only option, and clicked it. After doing so, the three stars came up.

ok I had a seperate main class that just ran my gui(). would that have anything to do with it?

ok I had a seperate main class that just ran my gui(). would that have anything to do with it?

Depends on what's in the main function. If it's the same as the main I have, I wouldn't imagine it would make a difference.

I assume you have no messages like this:

nope no errors it just doesnt change

When I first ran your program, before I realized what I had to do, I stuck this line at the top of actionPerformed:

System.out.println ("Inside actionPerformed");

so it would display every time I selected from the Drop-Down. Have you done this, and does it display?

Okay, here's what I've found.

1) DON'T USE PACK()!
JFrame.pack() is good some times, but NOT here. Use JFrame.setSize(int, int) (I set it to 250 x 135, and it looks great). using pack here makes it look squished (which it is!).

2) Set the default recipe
In your constructor (after creating the test recipe, and adding it to the JComboBox), set the selected index/item to 0 or test respectively. (that will ensure that the ratings show up at creation)

3) Don't use 2 JLabels for the rating!
Find a way to use one, and show the word "Rating: ", and the stars, or create a class that can display them horizontaly:

class RatingLabel extends JPanel{
    ImageIcon stars;

    RatingLabel(int stars){
        switch(stars){
            // Go through cases to load images...
        }
        this.add(new JLabel("Rating"));
        this.add(nww JLabel(stars));
    }
    public void setRating(int stars){
        //same as switch above
    }
    // Other methods to add/remove stars, ect
}

I'm pretty sure that should get things working. =)

This article has been dead for over six months. Start a new discussion instead.