为什么我不能将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; } } 

我应该看到“请选择合作伙伴”而我不这样做。 为什么?

我想这是因为我没有看到Thread的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:

我解决了这个问题。

  1. 在课堂上我有startshowWindow方法。 从主程序我调用了错误的方法( showWindow而不是start )。 所以,我替换了start方法(以避免与线程的开始混淆),然后我从主类调用startWindow ,它解决了问题。

您正在 invokeLater调用创建更新线程。 这不是你使用invokeLaterinvokeLater用于从单独的线程更新UI组件。 调用invokeLater单独的线程传递更新UI组件的Runnable

有关其他信息,请参阅JavaDocs

例如:

 // Start the window in the EDT. public void start() { 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() { // some long running process, I assume, but at // some point you want to update UI: SwingUtilities.invokeLater(new Runnable() { public void run() { frame.add(generatePartnerSelectionPanel()); frame.invalidate(); frame.validate(); } }); } };