我对 setVisible
有疑问。在我的 JFrame 类中,我有一个名为 changeMenu
的方法,它将更改 JFrame 的布局。
该方法从另一个类获取 String,并使用 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);
}}
}
假设changeMenu接收字符串“1”,控制台打印“这是添加菜单”。
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;
}
}
最后,模型类:
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");
}
}
}
最佳答案
通过使用 CardLayout 和交换 JPanel“ View ”,而不是通过设置可见或不可见组件,可以更轻松、更正确地解决您的问题。该教程可以在这里找到:The CardLayout .
此外,您还需要学习使用布局管理器,而不是设置组件大小和位置或使用空布局。否则,您将面临创建非常僵化、难以更新或改进的 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 方法。无论如何,我的测试表明问题不在于您发布的代码中,而在于其他地方。
<小时/>编辑
您行为不当的原因在于您的 Model 类中:
public class Model {
GUI gui = new GUI();
// ...
}
您正在此类中创建一个新 GUI 对象并调用该对象的方法,但猜猜看,它与原来的 GUI 对象不同显示,因此调用它的方法不会对显示的 GUI 产生任何影响。相反,将正确的对象传递到此类中:
public class Model {
private GUI gui;
public Model(GUI gui) {
this.gui = gui;
}
// ...
}
关于Java setVisible问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21217446/