Search code examples
javajcombobox

How can I access other class just to get info and then change in main?


I have a function called getCrop() in order to change an label's img depending on the settings window but when i call the function in another class the img doesn't change why?

private JLabel label_9 = new JLabel("");

//This is inside class Normal(main).
public void getCrop(String str) {
    switch(str) {
    case "4446" : label_9.setIcon(new ImageIcon(Normal.class.getResource("/TryBot/Resources/4446.jpg")));
        break;
    case "3339" : label_9.setIcon(new ImageIcon(Normal.class.getResource("/TryBot/Resources/3339.jpg")));
        break;
    case "3446" : label_9.setIcon(new ImageIcon(Normal.class.getResource("/TryBot/Resources/3446.jpg")));
        break;
    case "4536" : label_9.setIcon(new ImageIcon(Normal.class.getResource("/TryBot/Resources/4536.jpg")));
        break;
    case "5346" : label_9.setIcon(new ImageIcon(Normal.class.getResource("/TryBot/Resources/5346.jpg")));
        break;
    case "11115" : label_9.setIcon(new ImageIcon(Normal.class.getResource("/TryBot/Resources/11115.jpg")));
        break;
    case "4437" : label_9.setIcon(new ImageIcon(Normal.class.getResource("/TryBot/Resources/4437.jpg")));
        break;
    case "3447" : label_9.setIcon(new ImageIcon(Normal.class.getResource("/TryBot/Resources/3447.jpg")));
        break;
    case "4347" : label_9.setIcon(new ImageIcon(Normal.class.getResource("/TryBot/Resources/4347.jpg")));
        break;
    case "3546" : label_9.setIcon(new ImageIcon(Normal.class.getResource("/TryBot/Resources/3546.jpg")));
        break;
    case "4356" : label_9.setIcon(new ImageIcon(Normal.class.getResource("/TryBot/Resources/4356.jpg")));
        break;
    case "5436" : label_9.setIcon(new ImageIcon(Normal.class.getResource("/TryBot/Resources/5436.jpg")));
            break;
    default : label_9.setIcon(new ImageIcon(Normal.class.getResource("/TryBot/Resources/4446.jpg")));
        break;
    }
}

My Goal is to be able to change the img through my Settings window Here is the code for when someone changes the comboBox the img should change too.

//City is an array of Strings
public JComboBox comboBox = new JComboBox(City);

comboBox.addActionListener(new ActionListener() {
//this is inside Settings
        public void actionPerformed(ActionEvent e) {
            Normal cb = new  Normal();
            System.out.println(comboBox.getSelectedItem());
            cb.getCrop(comboBox.getSelectedItem().toString());
        }
    });

EDIT 1:

I replaced getcrop for setVillageImg tanks for the tip

public static void setVillageImg(String str) {
    label_9.setIcon(new ImageIcon(Normal.class.getResource("/TryBot/Resources/" + str + ".jpg")));
}

EDIT 2:

It is now possible to access thank you all. But when i change the first time it works but i have to close the settings and open again in order to change the img again because if i try to change again it gives me an error

at java.awt.EventDispatchThread.run(Unknown Source)

Solution

  • It appears your problem is the fact you create a new instance of the Normal class which is then changing the images of a label different than the one you see. You could remedy this by passing things around or making the method static; but that would add needless dependencies to the code when you could use other mechanisms.

    If you have two classes (one for each of your settings and main views) why not add a controller in between them and have it as a listener of the JComboBox and an Observable to the main view? For example (code includes simulation methods and statements to be removed):

    MainView:

    public class MainView extends JPanel implements Observer {
    
        private JLabel label = new JLabel("");
    
        public void setVillageImg(String path) {
            // set the image
        }
    
        @Override
        public void update(Observable o, Object arg) {
            String path = (String)arg;
            System.out.println(path);
            setVillageImg(path);
        }
    }
    

    Controller:

    public class ViewController extends Observable implements ActionListener {
    
        public ViewController(Observer observer) {
            addObserver(observer);
        }
    
        @Override
        public void actionPerformed(ActionEvent e) {
            System.out.println("Action Performed");
            setChanged();
            JComboBox comboBox = (JComboBox) e.getSource();
            notifyObservers(comboBox.getSelectedItem().toString());
        }
    }
    

    SettingsView:

    public class SettingsView extends JPanel {
    
        private JComboBox<String> comboBox;
        private static final String[] strings = {"Hello", "World"};
    
        public SettingsView(ActionListener listener) {
            comboBox = new JComboBox<>(strings);
            comboBox.addActionListener(listener);
        }
    
        public void simComboChange(int selected) {
            System.out.println("Simulating combo change");
            comboBox.setSelectedIndex(selected);
            comboBox.actionPerformed(new ActionEvent(comboBox, 0, "SimAction"));
        }
    }
    

    Simulation main:

    public static void main(String[] args) {
        MainView mainView = new MainView();
        ViewController viewController = new ViewController(mainView);
        SettingsView settingsView = new SettingsView(viewController);
        settingsView.simComboChange(0);
        settingsView.simComboChange(1);
    }
    


    Background information:

    An Observer is a class which wants to observe another class for changes and act upon those changes.

    The class that changes is said to be Observable. The two together are mechanisms of the Model-View-Controller pattern.

    setChanged() changes the state of the observable to changed. If you call notifyObservers() the observable should be checked for changes with hasChanged(). clearChanged() sets the state back to unchanged. Both effect the return value of hasChanged(). Note that clearChanged() is automatically called by notifyObservers() and redundant in the code; therefore it's now removed.