我正在编写网络游戏客户端,并且在点击按钮时在帧之间进行更改时会遇到问题。
我已经在不同的框架中写了客户端的每一页,当从客户的主页点击菜单按钮时,应该显示这些框架。
以下是我所做的代码..
public class homePage extends JFrame{
public homePage () {
initComponents();
}
private void initComponents(){
// the frame and butttons are here....
GameListBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
this.setVisible(false); // to hide the current home page
new GameList().start(); // to start new frame called GameList
// basically the same thing as following code
// GameList gl = new GameList();
// gl.setVisible (true);
// gl.run();
}
}
}
public class GameList extends JFrame{
public GameList(){
//Everything about the frame is here
}
// this method is for connection
public void run(){
try{
// open socket and initialize input streams, output streams here
while (true){
//process data to and from server
}
}// end of try
} // end of run
// this method is to display GameList frame and it's connection
public static void start(){
GameList frame = new GameList();
frame.setVisible(true);
frame.run();
}
}
以下类只是运行GameList框架,它是来自main方法的连接
public static void main(String[] args) {
new GameList().start();
// basically the same thing as following code
// GameList gl = new GameList();
// gl.setVisible (true);
// gl.run();
}
当我从main方法运行它时,我的GameList框架正常工作。显示GUI,建立连接,数据传输成功。 我基本上想要做的是从主页的ActionListener调用新的GameList()。start()方法,因为我可以从main方法调用,显示GameList并隐藏主页。
当我按照第一个代码中所示执行此操作时,GameList的GUI未加载(只是变黑),但建立连接并且数据传输成功。 仅在连接终止时才显示GUI。我怀疑原因是GameList的run()方法中的while循环??
但是,当我从主要的GameList类运行它时,完全相同的东西就像一个魅力。任何人都可以告诉我为什么gui没有加载,当我从主页上调用它时,尽管我所做的一切都完全一样。
很抱歉,如果我的问题听起来很愚蠢,但任何帮助都会受到高度赞赏。
答案 0 :(得分:3)
当您从GameList.start()
拨打ActionListener
时,您就在Swing EDT,即线程是Swing处理每个事件,如鼠标或键盘输入,还有组件重新绘制。当你在Swing EDT中进行一个漫长的过程时,你实际上是在阻塞线程并阻止任何其他事件被处理,其中包括重绘事件。这就是您的框架为黑色并且GUI似乎未加载的原因。当你从main方法调用它时没有发生这种情况,因为你不是在EDT线程中,而是应用程序的主线程。
要解决此问题,您应该使用Thread.start()
和Runnable
从另一个线程调用GameList的run()方法。
一个好的经验法则是,除了GUI内容和一些标志之外,不应该放置任何事件,并且不要在其中进行任何计算,以保持应用程序的响应。
另一个规则是,为了避免一般的问题,你应该把你所有的GUI东西(包括你的帧的创作)放在线程EDT中。如果您需要从其他线程执行某些操作(如果您没有响应某个事件或您使用的是主要方法),请使用SwingUtilities.invokeLater
。