Java setVisible问题
我对Java setVisible问题,java,swing,jframe,Java,Swing,Jframe,我对setVisible有问题。在我的JFrame类中,我有一个名为changeMenu的方法,它将更改JFrame的布局 该方法从另一个类获取一个字符串,并使用if语句来确定应该将JFrame更改为什么。在if语句中有几个setVisible调用,但它们根本不起作用 我确信if-语句是有效的,因为方法中有一个println,它在接收字符串时起作用。我想这是因为我使用了另一种方法的setVisible 代码如下: public class GUI extends JFrame{ pr
setVisible
有问题。在我的JFrame类中,我有一个名为changeMenu
的方法,它将更改JFrame的布局
该方法从另一个类获取一个字符串,并使用if
语句来确定应该将JFrame更改为什么。在if
语句中有几个setVisible
调用,但它们根本不起作用
我确信if
-语句是有效的,因为方法中有一个println,它在接收字符串时起作用。我想这是因为我使用了另一种方法的setVisible
代码如下:
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);
}}
}
最后,模型类:
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");
}
}
}
public class Model {
GUI gui = new GUI();
// ...
}
通过使用CardLayout和交换JPanel“视图”,而不是通过设置可见或不可见的组件,您的问题可以更容易、更正确地解决。可以在以下位置找到教程: 此外,您还需要学习使用布局管理器,而不是设置组件大小和位置或使用空布局。否则,您将面临创建非常僵硬、难以更新或改进GUI的风险
请注意,您的代码不完整,您没有发布任何ActionListener代码,因此我们无法重现您的问题
注意:当我在计时器内调用changeMenu方法时,它似乎对我有效:
// 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();
}
因此,您的问题不是由于“setVisible不工作”,而是由于其他原因,可能您在一个未显示的GUI对象上调用了错误的changeMenu方法。无论如何,我的测试告诉我问题不在你发布的代码中,而是在其他地方
编辑
您行为不端的原因在于您的模型类:
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");
}
}
}
public class Model {
GUI gui = new GUI();
// ...
}
您正在该类中创建一个新的GUI对象,并调用该对象的方法,但是猜猜看,它与显示的GUI对象不同,因此对其调用方法对显示的GUI没有影响。而是将正确的对象传入此类:
public class Model {
private GUI gui;
public Model(GUI gui) {
this.gui = gui;
}
// ...
}
MHM,我会考虑使用布局管理器,以前做过,但我喜欢的结果(空)布局。我会发布我所有的代码,这样你就可以重现我的场景。谢谢你的帮助!:-)@OliverBak:请参见编辑以回答。事实上,您在错误的GUI对象上调用方法。哦,这并不像我想的那么复杂。。谢谢你的帮助,我很感激:-)@OliverBak:不客气,但最好的解决方案还是用CardLayout交换视图,并使用布局管理器。相信我,做出这样的改变你不会后悔的。呵呵,我以后再看。。但我听说MIGLayout更好,不确定:-)你的主要方法是什么?