Java GUI - JButton 从另一个 class 打开另一个框架
Java GUI - JButton opens another frame from another class
我无法让第二帧显示 GUI 组件。我使用第一帧中的 JButton
打开了框架。
这是屏幕截图
这是第一帧 - ClientModule.java
第 2 帧 - ClientMenu.java
这是我试过的代码
ClientModule.java
import java.net.*;
import java.util.*;
import java.io.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class ClientModule extends JFrame implements Runnable{
private JPanel panel;
private JFrame frame;
private JLabel titleLbl, userLbl, passLbl, hostLbl, portLbl, ipLbl;
private JTextField userTxt, hostTxt, portTxt, ipTxt;
private JPasswordField passTxt;
private JButton loginBtn;
public static void main(String[] args)
{
new ClientModule().run();
}
public ClientModule()
{
frame = new JFrame("DMS(Drawing Message System)");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
panel = new JPanel();
panel.setPreferredSize(new Dimension(500,500));
panel.setLayout(new FlowLayout());
titleLbl = new JLabel("LogIn to Drawing Message System(DMS)");
titleLbl.setFont(new Font("Rockwell Condensed",Font.BOLD,28));
userLbl = new JLabel("Username:");
passLbl = new JLabel("Password:");
hostLbl = new JLabel("Hostname:");
portLbl = new JLabel("Port No.:");
ipLbl = new JLabel("IP Address:");
userTxt = new JTextField();
userTxt.setPreferredSize(new Dimension(100,30));
passTxt = new JPasswordField();
passTxt.setEchoChar('*');
passTxt.setPreferredSize(new Dimension(100,30));
portTxt = new JTextField();
portTxt.setPreferredSize(new Dimension(100,30));
ipTxt = new JTextField();
ipTxt.setPreferredSize(new Dimension(100,30));
hostTxt = new JTextField();
hostTxt.setPreferredSize(new Dimension(100,30));
loginBtn = new JButton("Login!");
loginBtn.setPreferredSize(new Dimension(90,30));
loginBtn.addActionListener(new LoginBtnListener());
panel.add(titleLbl);
panel.add(userLbl);
panel.add(userTxt);
panel.add(passLbl);
panel.add(passTxt);
panel.add(hostLbl);
panel.add(hostTxt);
panel.add(portLbl);
panel.add(portTxt);
panel.add(ipLbl);
panel.add(ipTxt);
panel.add(loginBtn);
frame.add(panel);
}
private class LoginBtnListener implements ActionListener
{
@SuppressWarnings("deprecation")
public void actionPerformed(ActionEvent action)
{
//thinking this frame will close after ClientMenu's frame is open
ClientModule client = new ClientModule();
client.setVisible(false);
ClientMenu menu = new ClientMenu();
menu.setVisible(true);
}
}
public void run()
{
frame.pack();
frame.setVisible(true);
}
}
ClientMenu.java
import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
import java.io.*;
import java.util.*;
public class ClientMenu extends JFrame{
JFrame frame;
JPanel panel;
JLabel titleLbl;
JButton sendBtn,receiveBtn,logoutBtn;
public ClientMenu()
{
frame = new JFrame("Drawing Message System(DMS)");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
panel = new JPanel();
panel.setLayout(new FlowLayout());
panel.setPreferredSize(new Dimension(500,500));
titleLbl = new JLabel("Main Menu");
titleLbl.setFont(new Font("Rockwell Condensed",Font.BOLD,28));
sendBtn = new JButton("Send a Drawing");
sendBtn.setPreferredSize(new Dimension(100,30));
receiveBtn = new JButton("Receive a Drawing");
receiveBtn.setPreferredSize(new Dimension(100,30));
logoutBtn = new JButton("Logout");
logoutBtn.setPreferredSize(new Dimension(100,30));
logoutBtn.addActionListener(new LogoutBtnListener());
panel.add(titleLbl);
panel.add(sendBtn);
panel.add(receiveBtn);
panel.add(logoutBtn);
frame.add(panel);
}
private class LogoutBtnListener implements ActionListener
{
//@SuppressWarnings("deprecation")
public void actionPerformed(ActionEvent action)
{
ClientModule client = new ClientModule();
client.setVisible(true);
ClientMenu menu = new ClientMenu();
menu.setVisible(false);
}
}
public static void main(String[] args)
{
new ClientMenu().run();
}
public void run()
{
frame.pack();
frame.setVisible(true);
}
}
我不确定我是否遗漏了什么,或者编码有误,还是其他什么。我已经搜索并尝试过..
感谢您的帮助和理解 (:
我设法通过添加对 run()
方法的调用来显示第二个框架(包括其内容):
ClientMenu menu = new ClientMenu();
menu.setVisible(true);
menu.run();
话虽这么说,但您的代码存在很多问题:
您的每个 class 中都有一个 main
方法。每个应用程序应该 只有 1 个主方法。由于 ClientModule
似乎是您想要打开的第一个框架,您可能希望将主要方法保留在那里并删除另一个 class.
中的方法
每个 class 中都有一个 run()
方法。就个人而言,我倾向于避免这样命名方法,因为它可能会与 run()
方法混淆,在处理线程时需要重写该方法。您显然正在尝试在 ClientModule
中执行一些多线程操作,但不会起作用。请查看 this 并发教程以更好地理解线程。您还应该明白,您永远不应该 自己给 run()
打电话。教程应该说清楚了。
Swing 应用程序的启动方式与其他应用程序略有不同。详情请参考this教程。
您有两个 class 和 extend
JFrame,但是请提供您自己的。这会导致创建其他 JFrames,这就是我的情况(每个实例化我得到 2 个 JFrames)。如果你想让你的 class 表现得像 JFrame,考虑扩展它,如果你想使用 JFrame,那么将你的 class 组合成一个,而不是两者(至少在这种情况下不是)。
最后,要摆脱以前的 JFrame,您 可以 对其调用 dispose()
。也就是说,该方法通常是使用 Card Layout
。这将允许您拥有包含多个内容的 1 帧。
抱歉这么长 post,但请在继续之前考虑按照上述进行重构。
您可以使用 setVisible 属性 到 'true' 或 'false'。
我无法让第二帧显示 GUI 组件。我使用第一帧中的 JButton
打开了框架。
这是屏幕截图
这是第一帧 - ClientModule.java
第 2 帧 - ClientMenu.java
这是我试过的代码
ClientModule.java
import java.net.*;
import java.util.*;
import java.io.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class ClientModule extends JFrame implements Runnable{
private JPanel panel;
private JFrame frame;
private JLabel titleLbl, userLbl, passLbl, hostLbl, portLbl, ipLbl;
private JTextField userTxt, hostTxt, portTxt, ipTxt;
private JPasswordField passTxt;
private JButton loginBtn;
public static void main(String[] args)
{
new ClientModule().run();
}
public ClientModule()
{
frame = new JFrame("DMS(Drawing Message System)");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
panel = new JPanel();
panel.setPreferredSize(new Dimension(500,500));
panel.setLayout(new FlowLayout());
titleLbl = new JLabel("LogIn to Drawing Message System(DMS)");
titleLbl.setFont(new Font("Rockwell Condensed",Font.BOLD,28));
userLbl = new JLabel("Username:");
passLbl = new JLabel("Password:");
hostLbl = new JLabel("Hostname:");
portLbl = new JLabel("Port No.:");
ipLbl = new JLabel("IP Address:");
userTxt = new JTextField();
userTxt.setPreferredSize(new Dimension(100,30));
passTxt = new JPasswordField();
passTxt.setEchoChar('*');
passTxt.setPreferredSize(new Dimension(100,30));
portTxt = new JTextField();
portTxt.setPreferredSize(new Dimension(100,30));
ipTxt = new JTextField();
ipTxt.setPreferredSize(new Dimension(100,30));
hostTxt = new JTextField();
hostTxt.setPreferredSize(new Dimension(100,30));
loginBtn = new JButton("Login!");
loginBtn.setPreferredSize(new Dimension(90,30));
loginBtn.addActionListener(new LoginBtnListener());
panel.add(titleLbl);
panel.add(userLbl);
panel.add(userTxt);
panel.add(passLbl);
panel.add(passTxt);
panel.add(hostLbl);
panel.add(hostTxt);
panel.add(portLbl);
panel.add(portTxt);
panel.add(ipLbl);
panel.add(ipTxt);
panel.add(loginBtn);
frame.add(panel);
}
private class LoginBtnListener implements ActionListener
{
@SuppressWarnings("deprecation")
public void actionPerformed(ActionEvent action)
{
//thinking this frame will close after ClientMenu's frame is open
ClientModule client = new ClientModule();
client.setVisible(false);
ClientMenu menu = new ClientMenu();
menu.setVisible(true);
}
}
public void run()
{
frame.pack();
frame.setVisible(true);
}
}
ClientMenu.java
import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
import java.io.*;
import java.util.*;
public class ClientMenu extends JFrame{
JFrame frame;
JPanel panel;
JLabel titleLbl;
JButton sendBtn,receiveBtn,logoutBtn;
public ClientMenu()
{
frame = new JFrame("Drawing Message System(DMS)");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
panel = new JPanel();
panel.setLayout(new FlowLayout());
panel.setPreferredSize(new Dimension(500,500));
titleLbl = new JLabel("Main Menu");
titleLbl.setFont(new Font("Rockwell Condensed",Font.BOLD,28));
sendBtn = new JButton("Send a Drawing");
sendBtn.setPreferredSize(new Dimension(100,30));
receiveBtn = new JButton("Receive a Drawing");
receiveBtn.setPreferredSize(new Dimension(100,30));
logoutBtn = new JButton("Logout");
logoutBtn.setPreferredSize(new Dimension(100,30));
logoutBtn.addActionListener(new LogoutBtnListener());
panel.add(titleLbl);
panel.add(sendBtn);
panel.add(receiveBtn);
panel.add(logoutBtn);
frame.add(panel);
}
private class LogoutBtnListener implements ActionListener
{
//@SuppressWarnings("deprecation")
public void actionPerformed(ActionEvent action)
{
ClientModule client = new ClientModule();
client.setVisible(true);
ClientMenu menu = new ClientMenu();
menu.setVisible(false);
}
}
public static void main(String[] args)
{
new ClientMenu().run();
}
public void run()
{
frame.pack();
frame.setVisible(true);
}
}
我不确定我是否遗漏了什么,或者编码有误,还是其他什么。我已经搜索并尝试过.. 感谢您的帮助和理解 (:
我设法通过添加对 run()
方法的调用来显示第二个框架(包括其内容):
ClientMenu menu = new ClientMenu();
menu.setVisible(true);
menu.run();
话虽这么说,但您的代码存在很多问题:
您的每个 class 中都有一个
main
方法。每个应用程序应该 只有 1 个主方法。由于ClientModule
似乎是您想要打开的第一个框架,您可能希望将主要方法保留在那里并删除另一个 class. 中的方法
每个 class 中都有一个
run()
方法。就个人而言,我倾向于避免这样命名方法,因为它可能会与run()
方法混淆,在处理线程时需要重写该方法。您显然正在尝试在ClientModule
中执行一些多线程操作,但不会起作用。请查看 this 并发教程以更好地理解线程。您还应该明白,您永远不应该 自己给run()
打电话。教程应该说清楚了。Swing 应用程序的启动方式与其他应用程序略有不同。详情请参考this教程。
您有两个 class 和
extend
JFrame,但是请提供您自己的。这会导致创建其他 JFrames,这就是我的情况(每个实例化我得到 2 个 JFrames)。如果你想让你的 class 表现得像 JFrame,考虑扩展它,如果你想使用 JFrame,那么将你的 class 组合成一个,而不是两者(至少在这种情况下不是)。最后,要摆脱以前的 JFrame,您 可以 对其调用
dispose()
。也就是说,该方法通常是使用Card Layout
。这将允许您拥有包含多个内容的 1 帧。
抱歉这么长 post,但请在继续之前考虑按照上述进行重构。
您可以使用 setVisible 属性 到 'true' 或 'false'。