所以我是java新手,我正在嘗試將登錄視窗作為程式的前身。登錄視窗非常標準,它有一個密碼和用戶輸入,一個登錄按鈕,右上角有一個 x。但是,我試圖讓用戶在輸入正確的登錄資料之前無法與主程式互動。然而,雖然 setenabled(false) 功能允許我阻止訪問主程式,但在用戶輸入正確的資訊后,什么都沒有發生,登錄螢屏仍然存在。
public static void main(String[] args) {
JFrame frame = MainUI.getInstance();
frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);
frame.setSize(900, 600);
frame.pack();
frame.setVisible(true);
frame.setEnabled(false);
login loginframe = new login();
loginframe.setResizable(false);
loginframe.setTitle("Login Form");
loginframe.setVisible(true);
loginframe.toFront();
loginframe.setBounds(10, 10, 375, 300);
loginframe.setDefaultCloseOperation(loginframe.EXIT_ON_CLOSE);
if (loginframe.loggedin)
frame.setEnabled(true);
}
在我的登錄類中,如果檢測到正確的輸入,我有一個登錄的布林值。但是, setenabled(true) 似乎沒有執行,并且在輸入正確的輸入后登錄視窗似乎沒有關閉。這是我登錄類中的 actionperformed 方法:
public void actionPerformed(ActionEvent e){
//Coding Part of LOGIN button
if (e.getSource() == loginButton) {
String userText;
String pwdText;
userText = userTextField.getText();
pwdText = passwordField.getText();
String line;
Boolean match = false;
try {
BufferedReader br = new BufferedReader(new FileReader("database.txt"));
while((line = br.readLine())!= null){
String[] values = line.split(",");
//System.out.println(values[0] values[1]);
if (userText.equalsIgnoreCase(values[0]) && pwdText.equalsIgnoreCase(values[1])) {
match = true;
break;
} else {
match = false;
}
}
if (match) {
JOptionPane.showMessageDialog(this, "Login Successful");
loggedin= true;
this.setDefaultCloseOperation(this.EXIT_ON_CLOSE);
} else {
JOptionPane.showMessageDialog(this, "Invalid Username or Password");
loggedin = false;
System.exit(0);
}
} catch (IOException a) {
a.printStackTrace();
}
}
}
Does anyone know why this is? Is my this.setDefaultCloseOperation(this.EXIT_ON_CLOSE); not doing what I think it should be doing? Does it not just close the current window (the login window) thus giving the user access to the main program?
uj5u.com熱心網友回復:
package stackoverflow;
import javax.swing.JFrame;
import javax.swing.WindowConstants;
public class ExitFrame {
public static void main(final String[] args) {
final JFrame f = new JFrame();
// this will do nothing, thus not react to the user trying to close the window
f.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
// this will only hide the window, as if fsetVisible(false) was called
f.setDefaultCloseOperation(WindowConstants.HIDE_ON_CLOSE);
// this will actually dispose the window, as if f.dispose() was called
f.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
// this will shut down the whole JVM, ending your program, as if System.exit(0); was called
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
}
為了幫助您解決實際問題:
為了阻止對呼叫(父)視窗的訪問,您應該使用對話框,如 JDialog,將其設定為模式模式,并為父視窗提供引數。
final JDialog d = new JDialog(f);
d.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
d.setModal(true);
// add elements
d.setVisible(true); // will block until d gets hidden or disposed.
// code will resume here
你也可以只擁有class MyDialog extends JDialog,就像你在代碼中使用 JFrame 一樣。
更高級的方法
不是在 JFrames 或 JDialogs 上實作東西,而只是作為 JPanel。為什么?因為您可以在任何您喜歡的地方添加它,而不必擔心“外部”行為。
然后,您可以將該面板添加到 JFrame、JWindow、JDialog、另一個 JPanel,甚至是帶有訊息對話框的 JOptionPane 等。
實作起來有點困難,因為您需要以某種方式將父級的“外部”事件附加到 JPanel,但是一旦您發現它就很容易了。
完整程式示例:
I've just implemented a login demo in Swing to show you how I would do it. This serves this question and another one, where I'll post a link to here.
DemoWindow
package stackoverflow.userlogin;
import java.awt.BorderLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
import stackoverflow.userlogin.UserLoginPanel.UserCredentials;
public class DemoWindow extends JFrame {
private static final long serialVersionUID = -5431874284425397696L;
public static void main(final String[] args) {
new DemoWindow();
}
private final JTextField gTxtStatus = new JTextField();
private final JButton gBtnLogin = new JButton("Log in!");
private User mCurrentUser = null;
public DemoWindow() {
setTitle("Logging in...");
setBounds(100, 100, 200, 200);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
setLayout(new BorderLayout());
add(new JLabel("Status:"), BorderLayout.NORTH);
gTxtStatus.setText("Not logged in!");
add(gTxtStatus);
gBtnLogin.addActionListener(al -> runLogin());
add(gBtnLogin, BorderLayout.SOUTH);
setVisible(true);
}
private void runLogin() {
try {
UserCredentials uc = null;
while (true) {
uc = UserLoginPanel.getUserCredentials(this, uc);
if (uc == null) {
gTxtStatus.setText("User login aborted.");
break;
}
final User user = UserManager.getUserByName(uc.mUsername);
if (user == null) {
gTxtStatus.setText("No user with name [" uc.mUsername "] found!");
continue;
}
final String hashedPassword = PasswordHasher.hashPassword(uc.mPasswordChars);
final boolean passwordOK = user.matchesPasswordHash(hashedPassword);
if (!passwordOK) {
gTxtStatus.setText("Password mismatch!");
continue;
}
mCurrentUser = user;
gTxtStatus.setText("User logged in: [" mCurrentUser "]");
break;
}
} catch (final Exception e) {
JOptionPane.showMessageDialog(this, "Error: " e, "Error", JOptionPane.ERROR_MESSAGE);
}
}
}
PasswordHasher
package stackoverflow.userlogin;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.security.MessageDigest;
import java.util.Arrays;
public class PasswordHasher {
static public final String MY_APP_SALT = PasswordHasher.class.getPackageName();
public static void main(final String[] args) throws IOException {
try (final BufferedReader buffer = new BufferedReader(new InputStreamReader(System.in));) {
while (true) {
System.out.println("Enter password. Enter empy line to end app.");
final String line = buffer.readLine();
if (line == null || line.trim().length() < 1) break;
final String hash = hashPassword(line.toCharArray());
System.out.println("Password: " line);
System.out.println("Hash: " hash);
System.out.println();
}
}
System.out.println("\nApp ended.");
}
static public String hashPassword(final char[] pPasswordChars) {
try {
final MessageDigest md = MessageDigest.getInstance("SHA1");
md.reset();
final byte[] saltBuffer = MY_APP_SALT.getBytes("UTF-8");
md.update(saltBuffer);
final byte[] passwordBuffer = charsToBytes(pPasswordChars);
md.update(passwordBuffer);
final byte[] digest = md.digest();
String hexStr = "";
for (int i = 0; i < digest.length; i ) {
hexStr = Integer.toString((digest[i] & 0xff) 0x100, 16).substring(1);
}
return hexStr;
} catch (final Exception e) {
throw new RuntimeException(e);
}
}
static public byte[] charsToBytes(final char[] pChars) {
final CharBuffer charBuffer = CharBuffer.wrap(pChars);
final ByteBuffer byteBuffer = Charset.forName("UTF-8").encode(charBuffer);
final byte[] bytes = Arrays.copyOfRange(byteBuffer.array(), byteBuffer.position(), byteBuffer.limit());
Arrays.fill(byteBuffer.array(), (byte) 0); // clear sensitive data
return bytes;
}
}
User
package stackoverflow.userlogin;
import java.util.Objects;
public class User {
private final String mUsername;
private final String mPasswordHash;
public User(final String pUsername, final String pPasswordHash) {
mUsername = pUsername;
mPasswordHash = pPasswordHash;
}
public User(final String pLine) {
final String[] args = pLine.split(",");
mUsername = args[0];
mPasswordHash = args[1];
}
public String getUsername() {
return mUsername;
}
public boolean matchesUsername(final String pUsername) {
return stringMatches(mUsername, pUsername);
}
public boolean matchesPasswordHash(final String pPasswordHash) {
return stringMatches(mPasswordHash, pPasswordHash);
}
static public boolean stringMatches(final String pString1, final String pString2) {
final String s1 = pString1 == null ? null : pString1.trim().toLowerCase();
final String s2 = pString2 == null ? null : pString2.trim().toLowerCase();
return Objects.equals(s1, s2);
}
@Override public String toString() {
return mUsername;
}
}
UserLoginPanel
package stackoverflow.userlogin;
import java.awt.BorderLayout;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
public class UserLoginPanel extends JPanel {
private static final long serialVersionUID = -2478650783143301888L;
static public class UserCredentials {
public final String mUsername;
public final char[] mPasswordChars;
public UserCredentials(final String pUsername, final char[] pPasswordChar) {
mUsername = pUsername;
mPasswordChars = pPasswordChar;
}
public void clearPassword() {
for (int i = 0; i < mPasswordChars.length; i ) {
mPasswordChars[i] = 0;
}
}
}
static public UserCredentials getUserCredentials(final Window pParent, final UserCredentials pDefaultCredentials) {
final JDialog d = new JDialog(pParent);
d.setTitle("Please log in");
final UserLoginPanel panel = new UserLoginPanel(ae -> d.dispose(), pDefaultCredentials);
d.setModal(true);
d.add(panel);
d.pack();
d.setVisible(true);
d.dispose();
return panel.getReturnValue();
}
private final JTextField gTxtUsername = new JTextField();
private final JPasswordField gTxtPassword = new JPasswordField();
private final JButton gBtnCancel = new JButton("Cancel");
private final JButton gBtnOK = new JButton("OK");
private final ActionListener mActionListener;
private UserCredentials mReturnValue = null;
public UserLoginPanel(final ActionListener pActionListener, final UserCredentials pDefaultCredentials) {
mActionListener = pActionListener;
mReturnValue = pDefaultCredentials;
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
add(new JLabel("Username:"));
if (mReturnValue != null) gTxtUsername.setText(mReturnValue.mUsername);
add(gTxtUsername);
add(new JLabel("Password:"));
if (mReturnValue != null) gTxtPassword.setText(new String(mReturnValue.mPasswordChars));
add(gTxtPassword);
{
final JPanel hor = new JPanel();
gBtnCancel.addActionListener(al -> gBtnCancel_click());
hor.add(gBtnCancel, BorderLayout.WEST);
gBtnOK.addActionListener(al -> gBtnOK_click());
hor.add(gBtnOK, BorderLayout.EAST);
add(hor);
}
}
private void gBtnOK_click() {
mReturnValue = new UserCredentials(gTxtUsername.getText(), gTxtPassword.getPassword());
mActionListener.actionPerformed(new ActionEvent(this, 0, "ok"));
}
private void gBtnCancel_click() {
mReturnValue = null;
mActionListener.actionPerformed(new ActionEvent(this, -1, "cancel"));
}
public UserCredentials getReturnValue() {
return mReturnValue;
}
}
UserManager
package stackoverflow.userlogin;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.stream.Collectors;
public class UserManager {
static public final String USER_DB_FILENAME = "user-database.txt";
static private List<User> sLoadedUsers;
static public List<User> getAllUsers() throws IOException {
if (sLoadedUsers == null) {
final Path file = Paths.get(USER_DB_FILENAME);
try {
sLoadedUsers = Files.lines(file)
.filter(p -> p != null && !p.isEmpty() && p.contains(","))
.map(p -> new User(p))
.collect(Collectors.toList());
} catch (final Exception e) {
Files.write(file, "username,passwordhash".getBytes()); // create default file
throw e;
}
}
return sLoadedUsers;
}
static public User getUserByName(final String pUsername) throws IOException {
for (final User user : getAllUsers()) {
if (user.matchesUsername(pUsername)) return user;
}
return null;
}
}
My user-database.txt file:
Peter,744ed63cee96b0542fcde52b63410ef6a9b8ae63
contains the user 'Peter' with the password 'Lustig'.
Steps to run:
- Run the DemoWindow once. Click on "Log in!" and then in the dialog "OK". An error will occur and the user database file
user-database.txtwill be created. - Run the PasswordHasher, and generate a hash. Past that hash into the user database file.
- Run DemoWindow again. This time play with several things, like enetering no username, no password, wrong username, wrong password, proper stuff.
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/455090.html
上一篇:Java無法獲取檔案的相對路徑
