I am a beginner in Java and I appreciate any tips. I was making a simple program that opens a very simple login window and when you enter the correct password (Hello.123), it is supposed to execute a second class that opens another window with a square that can be moved with the arrow keys. I tried executing the second class independently and it worked fine, but when I tried executing it as a part of the main program, it didn´t work. I thought that it was because the second class was executing as a Daemon Thread, so I tried making it a subclass of another class that sets the thread to non-daemon, but that didn´t work either. Is there something I am missing or did I do something wrong? (The code here has the thing to make it non-daemon) Login.java package main;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JButton;
import javax.swing.JTextField;
import java.awt.Color;
import java.awt.Font;
import javax.swing.BorderFactory;
import javax.swing.border.Border;
import javax.swing.ImageIcon;
import javax.swing.SwingUtilities;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.net.URL;
import main.PostFrameThr.PostFrame;
import main.PostFrameThr;
public class Login {
public static void main(String[] args) throws IOException {
System.out.println("Initializing main Method");
Border border = BorderFactory.createLineBorder(Color.black,5);
JFrame login = new JFrame();
login.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
login.setTitle("Login");
login.setResizable(false);
login.setSize(600, 500);
login.setLocation(350, 100);
login.setVisible(true);
URL url1 = Login.class.getResource("/resources/WindowLogo.png");
URL url2 = Login.class.getResource("/resources/LoginLogo.png");
ImageIcon logo = new ImageIcon(url1);
ImageIcon loginico = new ImageIcon(url2);
login.setIconImage(logo.getImage());
login.getContentPane().setBackground(Color.gray);
JButton loginButton = new JButton("Login");
loginButton.setBounds(255, 210, 70, 60);
login.add(loginButton);
JTextField password = new JTextField();
password.setBounds(190, 180, 200, 20);
login.add(password);
JLabel logintxt = new JLabel();
logintxt.setText("Please Enter Your Password");
logintxt.setIcon(loginico);
logintxt.setForeground(Color.BLACK);
logintxt.setSize(10, 10);
logintxt.setHorizontalTextPosition(JLabel.CENTER);
logintxt.setVerticalTextPosition(JLabel.TOP);
logintxt.setFont(new Font("Plain",Font.PLAIN,20));
logintxt.setBackground(Color.gray);
logintxt.setOpaque(true);
logintxt.setBorder(border);
logintxt.setVerticalAlignment(JLabel.TOP);
logintxt.setHorizontalAlignment(JLabel.CENTER);
login.add(logintxt);
SwingUtilities.updateComponentTreeUI(login);
int lock = 1;
if(lock==1) {
System.out.println("Finished Loading Login Window Components");
System.out.println("Initializing Login Method");
}
while(lock==1) {
lock = lock + 1;
lock = lock - 1;
String passwordtext = password.getText();
loginButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if(passwordtext.equals("Hello.123")) {
System.out.println("Login Successfull!");
// try {
//Runtime.getRuntime().exec("calc.exe");
//} catch (IOException e1) {
// TODO Auto-generated catch block
//e1.printStackTrace();
//}
new PostFrameThr();
new PostFrame();
login.dispatchEvent(new WindowEvent(login, WindowEvent.WINDOW_CLOSING));
}
}
});
}
}
}
PostFrame.java
package main;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.*;
import java.lang.Thread;
class PostFrameThr extends Thread {
static void thr() {
PostFrameThr Thread = new PostFrameThr();
Thread.setDaemon(false);
Thread.start();
new PostFrame();
}
@SuppressWarnings("serial")
public static class PostFrame extends JFrame implements KeyListener {
int X = 155;
int Y = 130;
int size = 70;
JLabel label;
PostFrame(){
this.setTitle("Snake");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setResizable(false);
this.setSize(400, 400);
this.setLayout(null);
this.addKeyListener(this);
this.setLocationRelativeTo(null);
label = new JLabel();
label.setBounds(X, Y, size, size);
label.setBackground(Color.black);
label.setOpaque(true);
label.setVisible(true);
this.add(label);
this.setVisible(true);
SwingUtilities.updateComponentTreeUI(this);
}
@Override
public void keyPressed(KeyEvent e) {
// TODO Auto-generated method stub
switch(e.getKeyChar()) {
case 'w' : label.setLocation(label.getX(), label.getY()-5);
break;
case 'a' : label.setLocation(label.getX()-5, label.getY());
break;
case 's' : label.setLocation(label.getX(), label.getY()+5);
break;
case 'd' : label.setLocation(label.getX()+5, label.getY());
}
}
@Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
@Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
}
}
Swing, like most GUI frameworks, is event driven.
Doing something like...
while (lock == 1) {
lock = lock + 1;
lock = lock - 1;
String passwordtext = password.getText();
is not only incorrect, it's also CPU intensive (not to mention that on each iteration, you're adding a new ActionListener
to the button)
Instead, just get rid of the loop and when the ActionListener
is triggered, get the value from the JTextField
loginButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
String passwordtext = password.getText();
if (passwordtext.equals("Hello.123")) {
System.out.println("Login Successfull!");
new PostFrameThr();
new PostFrame();
login.dispose();
}
}
});
You'll probably want to take the time to look at:
Oh, and SwingUtilities.updateComponentTreeUI(login);
isn't doing what you think it is doing. Instead, move login.setVisible(true);
to the end of the main
method