Oliver Bak
Oliver Bak

Reputation: 161

Java setVisible issue

I have an issue with setVisible. In my JFrame class I have a method called changeMenu, which will change the layout of the JFrame.

The method gets a String from another class, and uses an if statement to figure out what it should change the JFrame to. In the if statements there are several setVisible calls, but they are simply not working.

I'm sure the if-statement works, because there's a println in the method, which works when it receives the String. I guess it is because I use setVisible from another method.

Here's the code:

public class GUI extends JFrame{


    private JTextField song;
    private JList jl;
    private JButton add;
    private JButton edit;
    private JButton test;
    private JPanel jp;
    private JScrollPane sp;
    private JTextField artist;
    private JButton save;
    private JButton back;
    private JPopupMenu jpo;
    private JMenuItem ite;
    private JButton editsave;
    private JButton editback;
    private JTextField youtube;
    public JLabel ytl;
    public JLabel artl;
    public JLabel songl;

    DefaultListModel<String> m = new DefaultListModel<String>();

    public GUI(){
        super("MusicList - Alpha");
        setLayout(null);

        jl = new JList(m);
        add(jl);
        //creates a scrollpane, "implements jlist"
        sp = new JScrollPane(jl);
        sp.setBounds(30,30,195,200);
        add(sp);
        //creates the textfield to contain songname
        song = new JTextField(12);
        String afs = song.getText();
        song.setBounds(20,30,210,20);
        add(song);
        song.setVisible(false);
        //opens the add menu
        add = new JButton("add song");
        add.setBounds(20,250,100,20);
        add(add);
        //opens the edit menu
        edit = new JButton("edit song");
        edit.setBounds(135,250,100,20);
        add(edit);
        //this button checks if art and fl(arraylists) match to the index.
        test = new JButton("test");
        test.setBounds(300, 40, 80, 20);
        add(test);
        //the textfield which will pass the artist string.. used in add and edit
        artist = new JTextField();
        artist.setBounds(20,70,210,20);
        add(artist);
        artist.setVisible(false);
        //adds back button in "add" menu
        back = new JButton("back");
        back.setBounds(135,250,100,20);
        add(back);
        back.setVisible(false);
        //adds save button on "add" menu
        save = new JButton("save");
        save.setBounds(20,250,100,20);
        add(save);
        save.setVisible(false);
        //adds the back button on "edit" menu
        editback = new JButton("back");
        editback.setBounds(135, 250, 100, 20);
        add(editback);
        editback.setVisible(false);
        //adds the save button on "edit" menu
        editsave = new JButton ("save");
        editsave.setBounds(20,250,100,20);
        add(editsave);
        editsave.setVisible(false);
        //adds the youtube textfield
        youtube = new JTextField();
        youtube.setBounds(20,110,120,20);
        add(youtube);
        youtube.setVisible(false);
        //adds jlabel
        ytl = new JLabel("https://www.youtube.com/watch");
        ytl.setBounds(20,90,200,20);
        add(ytl);
        ytl.setVisible(false);

        artl = new JLabel("Artist");
        artl.setBounds(20,50,170,20);
        add(artl);
        artl.setVisible(false);

        songl = new JLabel("Song");
        songl.setBounds(20,10,170,20);
        add(songl);
        songl.setVisible(false);

    }

    public void addAL(){
        ActionListeners al = new ActionListeners();
        add.addActionListener(al);
        al.passObject(add);
        }
    public void changeMenu(String x){
        //0 is the "list" menu
        if(x.equals("0")){
            System.out.println("so far, so good...");
            jl.setVisible(true);
            sp.setVisible(true);
            add.setVisible(true);
            edit.setVisible(true);
            editback.setVisible(false);
            editsave.setVisible(false);
            youtube.setVisible(false);
            ytl.setVisible(false);
            song.setVisible(false);
            artist.setVisible(false);
            songl.setVisible(false);
            artl.setVisible(false);
            youtube.setText(null);
            song.setText(null);
            artist.setText(null);
        }
        //1 is the "add" menu
        if(x.equals("1")){
            System.out.println("this is the add menu");
            jl.setVisible(false);
            sp.setVisible(false);
            add.setVisible(false);
            edit.setVisible(false);
            back.setVisible(true);
            save.setVisible(true);
            song.setVisible(true);  
            artist.setVisible(true);
            youtube.setVisible(true);
            ytl.setVisible(true);
            songl.setVisible(true);
            artl.setVisible(true);

        }
        //2 is the "edit" menu
        if(x.equals("2")){
            jl.setVisible(false);
            sp.setVisible(false);
            add.setVisible(false);
            edit.setVisible(false);
            editback.setVisible(true);
            editsave.setVisible(true);
            song.setVisible(true);  
            artist.setVisible(true);
            youtube.setVisible(true);
            ytl.setVisible(true);
            songl.setVisible(true);
            artl.setVisible(true);
        }}
}

Lets say changeMenu recieve string "1", the console are println "this is the add menu".

public class ActionListeners extends MouseAdapter implements ActionListener{


private JList jl;
private JButton add;
private JButton edit;
private JButton save;
private JButton back;
private JPopupMenu jpo;
private JMenuItem ite;
private JButton editsave;
private JButton editback;

public void actionPerformed(ActionEvent e){
GUI gui = new GUI();
    if(e.getSource()==add){
        Model Model = new Model();
        Model.changeMenu("1");
        System.out.println("hey");
    }
}
public void passObject( JList jl, JButton add, JButton edit, JButton save, JButton back, JMenuItem ite, JButton editsave, JButton editback){
    this.add = add;
}
}

And last, model class:

public class Model {

GUI gui = new GUI();

public void changeMenu(String x){
    if(x.equals("0")){
        gui.changeMenu("0");
    }
    if(x.equals("1")){
        gui.changeMenu("1");

    }
    if(x.equals("2")){
        gui.changeMenu("2");
    }
}

}

Upvotes: 1

Views: 1415

Answers (1)

Hovercraft Full Of Eels
Hovercraft Full Of Eels

Reputation: 285405

Your problem is solved much more easily and correctly by using a CardLayout and swapping JPanel "views" rather than by setting visible or invisible components. The tutorial can be found here: The CardLayout.

Also you will want to learn to use layout managers and not set component size and location or use null layouts. Otherwise you risk creating very rigid hard to update or improve GUI's.


Note that your code is not complete, that you've not posted any ActionListener code, and so we are unable to reproduce your problem.


Note: when I call your changeMenu method from within a timer, it seems to work for me:

// your constructor:
public GUI() {
  super("MusicList - Alpha");
  setLayout(null);  // **** ugh, don't do this ****
  setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  // **** added ****

  jl = new JList(m);
  add(jl);
  // creates a scrollpane, "implements jlist"
  sp = new JScrollPane(jl);
  sp.setBounds(30, 30, 195, 200);
  add(sp);
  // creates the textfield to contain songname


  // ...... etc ...... code abbreviated for sake of clarity


  songl = new JLabel("Song");
  songl.setBounds(20, 10, 170, 20);
  add(songl);
  songl.setVisible(false);

  //  ****** I've added this code below *****
  int timerDelay = 2000;
  new Timer(timerDelay, new ActionListener() {
     private String[] menuValues = {"0", "1", "2"};
     private int index = 0;

     @Override
     public void actionPerformed(ActionEvent evt) {
        changeMenu(menuValues[index]);
        System.out.println("Index: " + index);
        index++;
        index %= menuValues.length;
     }
  }).start();
}

So your problem is not due to "setVisible not working" but rather due to something else, perhaps you're calling your changeMenu method on the wrong GUI object, on one not shown. Regardless, my test shows me that the problem does not lie within the code you've posted but instead lies elsewhere.


Edit
The reason for your misbehavior is in your Model class:

public class Model {

  GUI gui = new GUI();

  // ...

}

You're creating a new GUI object inside of this class and calling methods off of this object, but guess what, it's not the same GUI object as the one displayed, and so calling methods on it will have no effect on the displayed GUI. Instead pass in the correct object into this class:

public class Model {

  private GUI gui;

  public Model(GUI gui) {
    this.gui = gui;
  }
  // ...    
}

Upvotes: 2

Related Questions