Java应用程序,具有多个场景
我正在从事一个java项目,我处理了所有的功能,但说到GUI,我是一个初学者。我想知道的是,我是否可以像javaFX那样使用java在一个阶段中显示不同的场景?e、 g我的起点是登录后的登录面板清空Jframe并显示下一个脉络或场景。有很多观点认为我应该怎么做?如果你想要一种不同的方法,我建议你学习JavaFX。您可以将StackPane加载到FX场景中(场景是FX对象,而不是您所说的场景),然后将另一个StackPane(您的场景)加载到第一个StackPane中。当您希望更改场景时,只需从第一个场景卸载stackpane并加载另一个场景Java应用程序,具有多个场景,java,swing,Java,Swing,我正在从事一个java项目,我处理了所有的功能,但说到GUI,我是一个初学者。我想知道的是,我是否可以像javaFX那样使用java在一个阶段中显示不同的场景?e、 g我的起点是登录后的登录面板清空Jframe并显示下一个脉络或场景。有很多观点认为我应该怎么做?如果你想要一种不同的方法,我建议你学习JavaFX。您可以将StackPane加载到FX场景中(场景是FX对象,而不是您所说的场景),然后将另一个StackPane(您的场景)加载到第一个StackPane中。当您希望更改场景时,只需从第
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class HelloWorld extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage window) {
window.setTitle("Hello World!");
root.getChildren().add(sceneOne);
Scene scene = new Scene(root, 400, 400);
window.setScene(scene);
window.show();
}
private StackPane root = new StackPane();
private MyFirstScene sceneOne = new MyFirstScene();
private MySecondScene sceneTwo = new MySecondScene();
}
对于MyFirstScene(MySecondScene),您只需扩展StackPane,就可以添加所需的所有元素。我之所以建议使用FX,是因为Swing有点贬值,Oracle制造了FX来取代它。如果您打算使用Java制作许多GUI,我会很熟悉它。如果您想要不同的方法,我建议您学习JavaFX。您可以将StackPane加载到FX场景中(场景是FX对象,而不是您所说的场景),然后将另一个StackPane(您的场景)加载到第一个StackPane中。当您希望更改场景时,只需从第一个场景卸载stackpane并加载另一个场景
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class HelloWorld extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage window) {
window.setTitle("Hello World!");
root.getChildren().add(sceneOne);
Scene scene = new Scene(root, 400, 400);
window.setScene(scene);
window.show();
}
private StackPane root = new StackPane();
private MyFirstScene sceneOne = new MyFirstScene();
private MySecondScene sceneTwo = new MySecondScene();
}
对于MyFirstScene(MySecondScene),您只需扩展StackPane,就可以添加所需的所有元素。我之所以建议使用FX,是因为Swing有点贬值,Oracle制造了FX来取代它。如果您打算使用Java制作许多GUI,我会很熟悉它。如果您想要不同的方法,我建议您学习JavaFX。您可以将StackPane加载到FX场景中(场景是FX对象,而不是您所说的场景),然后将另一个StackPane(您的场景)加载到第一个StackPane中。当您希望更改场景时,只需从第一个场景卸载stackpane并加载另一个场景
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class HelloWorld extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage window) {
window.setTitle("Hello World!");
root.getChildren().add(sceneOne);
Scene scene = new Scene(root, 400, 400);
window.setScene(scene);
window.show();
}
private StackPane root = new StackPane();
private MyFirstScene sceneOne = new MyFirstScene();
private MySecondScene sceneTwo = new MySecondScene();
}
对于MyFirstScene(MySecondScene),您只需扩展StackPane,就可以添加所需的所有元素。我之所以建议使用FX,是因为Swing有点贬值,Oracle制造了FX来取代它。如果您打算使用Java制作许多GUI,我会很熟悉它。如果您想要不同的方法,我建议您学习JavaFX。您可以将StackPane加载到FX场景中(场景是FX对象,而不是您所说的场景),然后将另一个StackPane(您的场景)加载到第一个StackPane中。当您希望更改场景时,只需从第一个场景卸载stackpane并加载另一个场景
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class HelloWorld extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage window) {
window.setTitle("Hello World!");
root.getChildren().add(sceneOne);
Scene scene = new Scene(root, 400, 400);
window.setScene(scene);
window.show();
}
private StackPane root = new StackPane();
private MyFirstScene sceneOne = new MyFirstScene();
private MySecondScene sceneTwo = new MySecondScene();
}
对于MyFirstScene(MySecondScene),您只需扩展StackPane,就可以添加所需的所有元素。我之所以建议使用FX,是因为Swing有点贬值,Oracle制造了FX来取代它。如果您打算使用Java制作许多GUI,我会很熟悉它。基本上,在Swing
CardLayout
中,您可以在单个容器内的视图之间切换。首先看一看,了解更多细节
下面的示例使用了一种方法,旨在同时解耦代码,因此我担心这有点冗长,但这是使用MVC和代码分离方法的结果(我喜欢对接口进行编码)
让我们从定义我们想要的视图开始
public interface IView<C extends IViewController> {
public JComponent getView();
public C getViewController();
}
public interface ILoginView extends IView<ILoginViewController> {
}
public interface IWelcomeView extends IView<IWelcomeViewController> {
}
现在很明显,我们需要能够在视图之间传递一些数据(在本例中是用户详细信息或“凭证”)
现在,让我们进入实质并定义视图的实际实现
public abstract class AbstractView<C extends IViewController> extends JPanel implements IView<C> {
private C viewController;
public AbstractView(C viewController) {
this.viewController = viewController;
}
@Override
public JComponent getView() {
return this;
}
@Override
public C getViewController() {
return viewController;
}
}
public class WelcomeView extends AbstractView<IWelcomeViewController> implements IWelcomeView {
private JLabel userName;
public WelcomeView(IWelcomeViewController viewContoller) {
super(viewContoller);
viewContoller.setCredentialsListener((ICredentials credentials) -> {
userName.setText(credentials.getUserName());
revalidate();
repaint();
});
userName = new JLabel("...");
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.insets = new Insets(10, 10, 10, 10);
add(new JLabel("WELCOME!"), gbc);
add(userName, gbc);
}
}
public class LoginView extends AbstractView<ILoginViewController> implements ILoginView {
private JTextField userName;
private JPasswordField password;
private JButton login;
private JButton cancel;
public LoginView(ILoginViewController controller) {
super(controller);
setLayout(new GridBagLayout());
userName = new JTextField(10);
password = new JPasswordField(10);
login = new JButton("Login");
cancel = new JButton("Cancel");
login.addActionListener((ActionEvent e) -> {
// Fake the login process...
// This might be handed off to another controller...
String name = userName.getText();
if (name != null && !name.isEmpty()) {
Random rnd = new Random();
if (rnd.nextBoolean()) {
getViewController().loginWasSuccessful(new DefaultCredentials(userName.getText()));
} else {
getViewController().loginDidFail();
}
}
});
cancel.addActionListener((ActionEvent e) -> {
getViewController().loginWasCancelled();
});
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.insets = new Insets(2, 2, 2, 2);
gbc.gridwidth = GridBagConstraints.REMAINDER;
add(new JLabel("Login"), gbc);
gbc.gridx = 0;
gbc.gridy++;
gbc.gridwidth = 1;
add(new JLabel("Username:"), gbc);
gbc.gridy++;
add(new JLabel("Password:"), gbc);
gbc.gridx++;
gbc.gridy = 1;
add(userName, gbc);
gbc.gridy++;
add(password, gbc);
JPanel controls = new JPanel();
controls.add(login);
controls.add(cancel);
gbc.gridx = 0;
gbc.gridy++;
gbc.gridwidth = GridBagConstraints.REMAINDER;
add(controls, gbc);
}
public class DefaultCredentials implements ICredentials {
private final String userName;
public DefaultCredentials(String userName) {
this.userName = userName;
}
@Override
public String getUserName() {
return userName;
}
}
}
这几乎就是“核心”Swing集成。只需很少的工作,您就可以使用JavaFX中的控制器和视图接口
现在所做的就是向用户显示登录视图,如果用户成功登录,它会将视图切换到欢迎视图,并将用户凭据传递给它
如果您不想复制和粘贴所有这些,这是一个简单的可运行示例,我用来测试它
import java.awt.CardLayout;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class TestCardLayout {
public static void main(String[] args) {
new TestCardLayout();
}
public TestCardLayout() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new MainPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class MainPane extends JPanel {
protected static final String LOGIN_VIEW = "View.login";
protected static final String WELCOME_VIEW = "View.welcome";
private CardLayout cardLayout;
private ILoginView loginView;
private IWelcomeView welcomeView;
public MainPane() {
cardLayout = new CardLayout();
setLayout(cardLayout);
// This could be established via a factory or builder pattern
loginView = new LoginView(new LoginViewController());
welcomeView = new WelcomeView(new WelcomeViewController());
add(loginView.getView(), LOGIN_VIEW);
add(welcomeView.getView(), WELCOME_VIEW);
cardLayout.show(this, LOGIN_VIEW);
}
protected class LoginViewController implements ILoginViewController {
@Override
public void loginWasSuccessful(ICredentials credentials) {
welcomeView.getViewController().setCredentials(credentials);
cardLayout.show(MainPane.this, WELCOME_VIEW);
}
@Override
public void loginDidFail() {
JOptionPane.showMessageDialog(MainPane.this, "Login vaild", "Error", JOptionPane.ERROR_MESSAGE);
}
@Override
public void loginWasCancelled() {
SwingUtilities.windowForComponent(MainPane.this).dispose();
}
}
protected class WelcomeViewController implements IWelcomeViewController {
private IWelcomeViewController.ICredentialsListener credentialsListener;
private ICredentials credentials;
@Override
public ICredentials getCredentials() {
return credentials;
}
@Override
public void setCredentials(ICredentials credentials) {
this.credentials = credentials;
IWelcomeViewController.ICredentialsListener listener = getCredentialsListener();
if (listener != null) {
listener.credentialsWereUpdated(credentials);
}
}
@Override
public void setCredentialsListener(IWelcomeViewController.ICredentialsListener listener) {
this.credentialsListener = listener;
}
@Override
public IWelcomeViewController.ICredentialsListener getCredentialsListener() {
return credentialsListener;
}
}
}
public interface IViewController {
}
public interface ILoginViewController extends IViewController {
public void loginWasSuccessful(ICredentials credentials);
public void loginDidFail();
public void loginWasCancelled();
}
public interface IWelcomeViewController extends IViewController {
public ICredentials getCredentials();
public void setCredentials(ICredentials credentials);
public void setCredentialsListener(ICredentialsListener listener);
public ICredentialsListener getCredentialsListener();
public interface ICredentialsListener {
public void credentialsWereUpdated(ICredentials credentials);
}
}
public interface ICredentials {
public String getUserName();
}
public interface IView<C extends IViewController> {
public JComponent getView();
public C getViewController();
}
public interface ILoginView extends IView<ILoginViewController> {
}
public interface IWelcomeView extends IView<IWelcomeViewController> {
}
public abstract class AbstractView<C extends IViewController> extends JPanel implements IView<C> {
private C viewController;
public AbstractView(C viewController) {
this.viewController = viewController;
}
@Override
public JComponent getView() {
return this;
}
@Override
public C getViewController() {
return viewController;
}
}
public class WelcomeView extends AbstractView<IWelcomeViewController> implements IWelcomeView {
private JLabel userName;
public WelcomeView(IWelcomeViewController viewContoller) {
super(viewContoller);
viewContoller.setCredentialsListener((ICredentials credentials) -> {
userName.setText(credentials.getUserName());
revalidate();
repaint();
});
userName = new JLabel("...");
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.insets = new Insets(10, 10, 10, 10);
add(new JLabel("WELCOME!"), gbc);
add(userName, gbc);
}
}
public class LoginView extends AbstractView<ILoginViewController> implements ILoginView {
private JTextField userName;
private JPasswordField password;
private JButton login;
private JButton cancel;
public LoginView(ILoginViewController controller) {
super(controller);
setLayout(new GridBagLayout());
userName = new JTextField(10);
password = new JPasswordField(10);
login = new JButton("Login");
cancel = new JButton("Cancel");
login.addActionListener((ActionEvent e) -> {
// Fake the login process...
// This might be handed off to another controller...
String name = userName.getText();
if (name != null && !name.isEmpty()) {
Random rnd = new Random();
if (rnd.nextBoolean()) {
getViewController().loginWasSuccessful(new DefaultCredentials(userName.getText()));
} else {
getViewController().loginDidFail();
}
}
});
cancel.addActionListener((ActionEvent e) -> {
getViewController().loginWasCancelled();
});
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.insets = new Insets(2, 2, 2, 2);
gbc.gridwidth = GridBagConstraints.REMAINDER;
add(new JLabel("Login"), gbc);
gbc.gridx = 0;
gbc.gridy++;
gbc.gridwidth = 1;
add(new JLabel("Username:"), gbc);
gbc.gridy++;
add(new JLabel("Password:"), gbc);
gbc.gridx++;
gbc.gridy = 1;
add(userName, gbc);
gbc.gridy++;
add(password, gbc);
JPanel controls = new JPanel();
controls.add(login);
controls.add(cancel);
gbc.gridx = 0;
gbc.gridy++;
gbc.gridwidth = GridBagConstraints.REMAINDER;
add(controls, gbc);
}
public class DefaultCredentials implements ICredentials {
private final String userName;
public DefaultCredentials(String userName) {
this.userName = userName;
}
@Override
public String getUserName() {
return userName;
}
}
}
}
导入java.awt.CardLayout;
导入java.awt.EventQueue;
导入java.awt.GridBagConstraints;
导入java.awt.GridBagLayout;
导入java.awt.Insets;
导入java.awt.event.ActionEvent;
导入java.util.Random;
导入javax.swing.JButton;
导入javax.swing.JComponent;
导入javax.swing.JFrame;
导入javax.swing.JLabel;
导入javax.swing.JOptionPane;
导入javax.swing.JPanel;
导入javax.swing.JPasswordField;
导入javax.swing.JTextField;
导入javax.swing.SwingUtilities;
导入javax.swing.UIManager;
导入javax.swing.UnsupportedLookAndFeelException;
公共类TestCardLayout{
公共静态void main(字符串[]args){
新的TestCardLayout();
}
公共TestCardLayout(){
invokeLater(新的Runnable(){
@凌驾
公开募捐{
试一试{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}catch(ClassNotFoundException |实例化Exception | IllegalacessException |不支持ookandfeelException ex){
例如printStackTrace();
}
JFrame=新JFrame(“测试”);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(新主窗格());
frame.pack();
frame.setLocationRelativeTo(空);
frame.setVisible(true);
}
});
}
公共类主窗格扩展了JPanel{
受保护的静态最终字符串登录\u VIEW=“VIEW.LOGIN”;
受保护的静态最终字符串WELCOME\u VIEW=“VIEW.WELCOME”;
私人卡布局卡布局;
私人ILoginView loginView;
私人IWelcomeView welcomeView;
公共主窗格(){
cardLayout=新的cardLayout();
设置布局(卡片布局);
//这是可以确定的