Reputation: 161
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
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