为什么我无法将 JPanel 添加到 JFrame?
这是代码:
import javax.swing.SwingUtilities;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JLabel;
import java.awt.event.*;
import java.awt.*;
public class GameWindow {
private String[] players;
private JFrame frame;
// Constructor.
public GameWindow(String[] players) {
this.players = players;
}
// Start the window in the EDT.
public void start() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
showWindow();
controller.start();
}
});
}
// Defines the general properties of and starts the window.
public void showWindow() {
frame = new JFrame("Game");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(600,400);
frame.setVisible(true);
}
// The thread controlling changes of panels in the main window.
private Thread controller = new Thread() {
public void run() {
frame.add(generatePartnerSelectionPanel());
frame.invalidate();
frame.validate();
}
};
// Generate the panel for the selection of a partner.
private JPanel generatePartnerSelectionPanel() {
JPanel panel = new JPanel();
panel.add(new JLabel("Pleas select a partner:"));
return panel;
}
}
我应该看到“请选择合作伙伴”,但我没有。为什么?
我想这是因为我没有从线程的 run 方法中看到框架。
添加:
可能我需要在事件调度线程中进行所有更新...我现在会检查它。
添加2:
我尝试修改控制器的代码。它没有帮助:
private Thread controller = new Thread() {
public void run() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
frame.getContentPane().add(generatePartnerSelectionPanel());
frame.invalidate();
frame.validate();
}
});
}
};
添加3:
好的。这是代码的完整版本(不起作用):
import javax.swing.SwingUtilities;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JLabel;
import java.awt.event.*;
import java.awt.*;
public class GameWindow {
private String[] players;
private JFrame frame;
// Constructor.
public GameWindow(String[] players) {
this.players = players;
}
// Start the window in the EDT.
public void start() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
showWindow();
controller.start();
}
});
}
// Defines the general properties of and starts the window.
public void showWindow() {
frame = new JFrame("Game");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(600,400);
frame.setVisible(true);
}
// The thread controlling changes of panels in the main window.
private Thread controller = new Thread() {
public void run() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
frame.getContentPane().add(generatePartnerSelectionPanel());
frame.invalidate();
frame.validate();
}
});
}
};
// Generate the panel for the selection of a partner.
private JPanel generatePartnerSelectionPanel() {
JPanel panel = new JPanel();
panel.add(new JLabel("Pleas select a partner:"));
return panel;
}
}
添加4:
以下代码也不起作用。顺便问一下,为什么我应该从 start
中删除 invokeLater
?我确实需要在事件分派线程中启动 GUI,invokelater
会执行此操作。
import javax.swing.SwingUtilities;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JLabel;
import java.awt.event.*;
import java.awt.*;
public class GameWindow {
private String[] players;
private JFrame frame;
// Constructor.
public GameWindow(String[] players) {
this.players = players;
}
// Start the window in the EDT.
public void start() {
// SwingUtilities.invokeLater(new Runnable() {
// public void run() {
showWindow();
controller.start();
// }
// });
}
// Defines the general properties of and starts the window.
public void showWindow() {
frame = new JFrame("Game");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(600,400);
frame.setVisible(true);
}
// The thread controlling changes of panels in the main window.
private Thread controller = new Thread() {
public void run() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
frame.getContentPane().add(generatePartnerSelectionPanel());
frame.invalidate();
frame.validate();
}
});
}
};
// Generate the panel for the selection of a partner.
private JPanel generatePartnerSelectionPanel() {
JPanel panel = new JPanel();
panel.add(new JLabel("Pleas select a partner:"));
return panel;
}
}
添加5:
我解决了这个问题。
- 在课程中,我有
start
和showWindow
方法。我在主程序中调用了错误的方法(showWindow
而不是start
)。因此,我替换了start
方法(以避免与线程启动混淆),然后从主类调用startWindow
,它解决了问题。
Here is the code:
import javax.swing.SwingUtilities;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JLabel;
import java.awt.event.*;
import java.awt.*;
public class GameWindow {
private String[] players;
private JFrame frame;
// Constructor.
public GameWindow(String[] players) {
this.players = players;
}
// Start the window in the EDT.
public void start() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
showWindow();
controller.start();
}
});
}
// Defines the general properties of and starts the window.
public void showWindow() {
frame = new JFrame("Game");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(600,400);
frame.setVisible(true);
}
// The thread controlling changes of panels in the main window.
private Thread controller = new Thread() {
public void run() {
frame.add(generatePartnerSelectionPanel());
frame.invalidate();
frame.validate();
}
};
// Generate the panel for the selection of a partner.
private JPanel generatePartnerSelectionPanel() {
JPanel panel = new JPanel();
panel.add(new JLabel("Pleas select a partner:"));
return panel;
}
}
I should see "Pleas select the partner" and I don't. Why?
I suppose that it's because I do not see frame from the run method of the Thread.
ADDED:
May be I need to do all updates in the event dispatch thread... I will check it right now.
ADDED 2:
I tried to modify the code for the controller. It did not help:
private Thread controller = new Thread() {
public void run() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
frame.getContentPane().add(generatePartnerSelectionPanel());
frame.invalidate();
frame.validate();
}
});
}
};
ADDED 3:
OK. Here is the complete version of the code (which does not work):
import javax.swing.SwingUtilities;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JLabel;
import java.awt.event.*;
import java.awt.*;
public class GameWindow {
private String[] players;
private JFrame frame;
// Constructor.
public GameWindow(String[] players) {
this.players = players;
}
// Start the window in the EDT.
public void start() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
showWindow();
controller.start();
}
});
}
// Defines the general properties of and starts the window.
public void showWindow() {
frame = new JFrame("Game");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(600,400);
frame.setVisible(true);
}
// The thread controlling changes of panels in the main window.
private Thread controller = new Thread() {
public void run() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
frame.getContentPane().add(generatePartnerSelectionPanel());
frame.invalidate();
frame.validate();
}
});
}
};
// Generate the panel for the selection of a partner.
private JPanel generatePartnerSelectionPanel() {
JPanel panel = new JPanel();
panel.add(new JLabel("Pleas select a partner:"));
return panel;
}
}
ADDED 4:
The following code also does not work. By the way, why should I remove invokeLater
from the start
? I do need to start the GUI in the event dispatch thread and invokelater
does it.
import javax.swing.SwingUtilities;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JLabel;
import java.awt.event.*;
import java.awt.*;
public class GameWindow {
private String[] players;
private JFrame frame;
// Constructor.
public GameWindow(String[] players) {
this.players = players;
}
// Start the window in the EDT.
public void start() {
// SwingUtilities.invokeLater(new Runnable() {
// public void run() {
showWindow();
controller.start();
// }
// });
}
// Defines the general properties of and starts the window.
public void showWindow() {
frame = new JFrame("Game");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(600,400);
frame.setVisible(true);
}
// The thread controlling changes of panels in the main window.
private Thread controller = new Thread() {
public void run() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
frame.getContentPane().add(generatePartnerSelectionPanel());
frame.invalidate();
frame.validate();
}
});
}
};
// Generate the panel for the selection of a partner.
private JPanel generatePartnerSelectionPanel() {
JPanel panel = new JPanel();
panel.add(new JLabel("Pleas select a partner:"));
return panel;
}
}
ADDED 5:
I solved the problem.
- In the class I had
start
andshowWindow
methods. From the main program I called the wrong method (showWindow
instead of thestart
). So, I replaces thestart
method (to avoid confusions with the start of thread) and then I calledstartWindow
from the main class and it solved the problem.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您正在从
invokeLater
调用创建更新线程。这不是您使用invokeLater
的方式。invokeLater
用于从单独的线程更新 UI 组件。调用invokeLater
,传递一个Runnable
来更新您的 UI 组件,从您的单独线程。有关其他信息,请参阅 JavaDocs
例如:
You are creating your update thread from the
invokeLater
call. This is not how you useinvokeLater
.invokeLater
is for updating UI components from a separate thread. CallinvokeLater
, passing aRunnable
that updates your UI components, from your separate thread.For additional information, see the JavaDocs
For example: