我正在使用Swing和MVC设计模式创建Java应用程序。
该应用程序的设计如下:
QuizPanel
扩展了JPanel
。此面板是保存我的应用程序主屏幕的容器。JPanel
的单独类。这些JPanel可以根据需要从QuizPanel
添加/删除。QuizPanel
实现了我的界面Switchable
。 Switchable
接口由单个SwitchView(ViewState state)
方法组成。我将this
传递给在QuizPanel
顶层面板中实例化的每个“屏幕”,以便他们可以在按下按钮时调用SwitchView
。在登录屏幕上,用户输入一个密码和学生ID,如果它们与数据库中的令牌匹配,我需要将Token
对象传递给我的应用程序的另一个屏幕(我尚未回答的问题屏幕)尚未实施)或以某种方式提供。从嵌入式Derby数据库中检索令牌。
我想到的唯一方法是创建一个带有静态Token
变量的实用程序类,该变量可以被其他类访问(这似乎是一种讨厌的方法)。因为我的应用程序设计有缺陷,我是否对此感到麻烦?我可以使用任何技术在应用程序的不同屏幕之间传递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);
}
}
LoginModel类
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;
}
}
答案 0 :(得分:1)
将令牌的值传递给父级JPanel的方法是在您的界面中添加一个方法,例如setToken(int token)和“测验”面板中的全局变量
QuizPanel:
private int token;
@Override
public void setToken(int token){
this.token = token;
}
夹心界面:
public void setToken(int token);
登录:
parentView.setToken(token);
在您的LoginController中说parentView.setToken(token)
。现在,将在QuizPanel中设置令牌变量。
答案 1 :(得分:1)
我认为在这种情况下,您可以使用Singleton pattern。此模式应尽可能少用,但是在您的情况下(必须从不同应用程序类访问的公共信息),可以使用它(IMHO)。
但是,根据您的情况,您还可以使用一个Swing功能。
JComponent
窗外的人可以访问此窗格。JComponent
也可以在地图中存储一些用户数据,
称为“客户端属性”。因为JRootPane
扩展了JComponent
您可以在地图上存储/检索令牌。这是一个简单的代码:
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 :(得分:0)
您可以将令牌保存到文件中,然后在jpanel上读取该文件以获取令牌