代码之家  ›  专栏  ›  技术社区  ›  Guybrush

与父JPanel通信

  •  0
  • Guybrush  · 技术社区  · 7 年前

    应用程序的设计如下:

    • 有一个班 QuizPanel 延伸的 JPanel
    • 我的应用程序的每个“屏幕”都是一个单独的类,它扩展了 面板 快速面板 根据需要。
    • 快速面板 实现我的接口 Switchable 可切换 SwitchView(ViewState state) 方法。我通过了 this 到中实例化的每个“屏幕” 快速面板 顶级面板,因此他们可以调用 SwitchView 当按下按钮时。

    在登录屏幕上,用户输入一个pin和学生ID,如果它们与数据库中的令牌匹配,我需要通过 Token

    我唯一能想到的方法就是创建一个带有静态 代币 代币 在我的应用程序的不同屏幕上?

    public static void main(String[] args) {
        QuizPanel quizPanel = new QuizPanel();
    
        JFrame frame = new JFrame("Quiz");
        frame.setPreferredSize(new Dimension(400, 400));
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(quizPanel);
        frame.pack();
        frame.setLocationRelativeTo(null);
    
        frame.setVisible(true);
    }
    

    QuizPanel类

    public class QuizPanel extends JPanel implements Switchable{
    
        private MainMenuPane mainMenuPane;
        private RegisterPane registerPane;
        private LoginPane loginPane;
    
        public QuizPanel() {
            setLayout(new BorderLayout());
    
            registerPane = new RegisterPane();
            RegisterController registerController = new RegisterController(registerPane, this);
    
            mainMenuPane = new MainMenuPane();
            MainMenuController mainMenuController = new MainMenuController(mainMenuPane, this);
    
            loginPane = new LoginPane();
            LoginController loginController = new LoginController(loginPane, this);
    
            switchView(ViewState.MAINMENU_STATE);
        }
    
        @Override
        public void switchView(ViewState state) {
            System.out.println("Changing state: " + state);
            switch (state) {
                case REGISTER_STATE:
                    removeAll();
                    setLayout(new BorderLayout());
                    add(registerPane, BorderLayout.CENTER);
                    repaint();
                    revalidate();
                    break;
                case MAINMENU_STATE:
                    removeAll();
                    setLayout(new BorderLayout());
                    add(mainMenuPane, BorderLayout.CENTER);
                    repaint();
                    revalidate();
                    break;
                case LOGIN_STATE:
                    removeAll();
                    setLayout(new BorderLayout());
                    add(loginPane, BorderLayout.CENTER);
                    repaint();
                    revalidate();
                    break;
                default:
                    System.out.println("UNREGISTERED STATE!");
                    break;
            }
        }
    }
    

    登录控制器

    public class LoginController implements ILoginController, ILoginViewObserver {
        private ILoginView view;
        private LoginModel loginModel;
        private Switchable parentView;
    
        public LoginController(ILoginView view, Switchable parentView) {
            this.view = view;
            this.loginModel = new LoginModel();
            this.parentView = parentView;
    
            view.addLoginViewObserver(this);
        }
    
        @Override
        public ILoginView getLoginView() {
            return view;
        }
    
        @Override
        public void submitButtonWasPressed(Token token) {
            Token verifiedToken = loginModel.verifyToken(token);
    
            if (verifiedToken != null) {
                System.out.println("Token (" + token.token + ") successfully verified");
                // How can I pass the token to the new JPanel the parent view will be displaying?
            } else {
                System.out.println("Token is invalid");
            }
        }
    
        @Override
        public void cancelButtonWasPressed() {
            parentView.switchView(ViewState.MAINMENU_STATE);
        }
    }
    

    public class LoginModel {
        private List<Token> tokens;
    
        public LoginModel() {
            TokenDao tokenAccessObject = new TokenAccessObject();
            tokens = tokenAccessObject.getAllTokens();
        }
    
        public Token verifyToken(Token providedToken) {
            for (Token token : tokens) {
                if (token.studentID == providedToken.studentID){
                    if (token.token.compareTo(providedToken.token) == 0) {
                        return token;
                    }
                }
            }
            return null;
        }
    }
    
    3 回复  |  直到 7 年前
        1
  •  1
  •   Sergiy Medvynskyy    7 年前

    我想在这种情况下你可以用 Singleton pattern . 这种模式应该尽量少用,但在您的情况下(必须从不同的应用程序类访问的公共信息),您可以使用它(IMHO)。

    1. 任何Swing窗口都有根窗格。每一个 JComponent 那是被放置的 在窗口中可以访问此窗格。
    2. J组件 也有可能在地图上存储一些用户数据, 称为“客户端属性”。因为 JRootPane J组件 你可以存储/检索你的令牌就是这个地图。

    public class TokenUtils {
    
        private static final String TOKEN_PROPERTY = "token";
    
        public static Token findToken(JComponent component) {
            JRootPane root = component.getRootPane();
            if (root != null) {
                return Token.class.cast(root.getClientProperty(TOKEN_PROPERTY));
            }
           return null;
        }
    
        public static void putToken(JComponent component, Token token) {
            JRootPane root = component.getRootPane();
            if (root != null) {
                root.putClientProperty(TOKEN_PROPERTY, token);
            }
        }
    }
    

    重要的 :如果使用多个窗口,则必须将令牌放入每个窗口中。

        2
  •  1
  •   Donatic    7 年前

    将令牌值传递给父JPanel的方法是在接口中添加一个方法,如setToken(int token)和测试面板中的一个全局变量

    private int token;
    @Override
    public void setToken(int token){
         this.token = token;
    }
    

    滑动接口:

    public void setToken(int token);
    

    登录:

    parentView.setToken(token);
    

    parentView.setToken(token) 在你的登录控制器中。现在将设置QuizPanel中的token变量。

        3
  •  0
  •   Cufe    7 年前

    您可以将令牌保存到一个文件中,然后在jpanel上读取该文件以获取令牌