Java应用程序,具有多个场景

Java应用程序,具有多个场景,java,swing,Java,Swing,我正在从事一个java项目,我处理了所有的功能,但说到GUI,我是一个初学者。我想知道的是,我是否可以像javaFX那样使用java在一个阶段中显示不同的场景?e、 g我的起点是登录后的登录面板清空Jframe并显示下一个脉络或场景。有很多观点认为我应该怎么做?如果你想要一种不同的方法,我建议你学习JavaFX。您可以将StackPane加载到FX场景中(场景是FX对象,而不是您所说的场景),然后将另一个StackPane(您的场景)加载到第一个StackPane中。当您希望更改场景时,只需从第

我正在从事一个java项目,我处理了所有的功能,但说到GUI,我是一个初学者。我想知道的是,我是否可以像javaFX那样使用java在一个阶段中显示不同的场景?e、 g我的起点是登录后的登录面板清空Jframe并显示下一个脉络或场景。有很多观点认为我应该怎么做?

如果你想要一种不同的方法,我建议你学习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,我会很熟悉它。

如果您想要不同的方法,我建议您学习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();
设置布局(卡片布局);
//这是可以确定的