为什么我不能将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:
我解决了这个问题。
- 在课堂上我有
start
和showWindow
方法。 从主程序我调用了错误的方法(showWindow
而不是start
)。 所以,我替换了start
方法(以避免与线程的开始混淆),然后我从主类调用startWindow
,它解决了问题。
您正在从 invokeLater
调用创建更新线程。 这不是你使用invokeLater
。 invokeLater
用于从单独的线程更新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(); } }); } };
- Junit4 + Spring 2.5:断言抛出“NoClassDefFoundError”
- Apache FileUtils.isSymlink和Java7的Files.isSymbolicLink()之间是否存在已知的差异?
- Spring root应用程序上下文和servlet上下文混淆
- twitter4j是否提供在2个日期之间搜索推文的function
- Java:显示客户端IP和端口号
- 如何使用Maven使用Selenium 3.4.0启动FireFoxDriver?
- 支持Java的矢量机?
- JavaFX ListView中的图像
- Websocket在playframework 2中发送所有客户端的数据