Im having problems creating a GUI. I want to make a program that allows users to enter their password through buttons, and it takes 3 chances before the GUI closes. I have attempted a few different methods but cannot get it to fully work.
JTextField1 is where the instructions are shown.
JTextField2 is where the password is input (correct password should be 1234)
After putting in the wrong password for the 3rd time I want it to shut.
I think the issue is that it is taking the same password 3 times and will automatically end, but I am not sure how to fix or loop properly as I am quite new to java and gui's.
This is what I have so far:
final String PASSWORD = "1234";
int attempts = 3;
String password = "";
while (attempts-- > 0 && !PASSWORD.equals(password))
{
jTextField1.setText("Enter your password");
password = jTextField2.getText();
if (password.equals(PASSWORD))
jTextField1.setText("Welcome ");
else
jTextField1.setText("Incorrect Pin, please try again");
}
Consider these two lines:
jTextField1.setText("Enter your password");
password = jTextField2.getText();
The second line executes immediately after the first line. There is no code here which waits for the user to type anything.
Graphical user interfaces are event-based. A program must respond to events based on user behavior. It is not possible to handle GUI interactions a single sequential function.
You respond to events in Java by adding an event listener to an object which is capable of generating certain kinds of events. A JTextField fires an action event when the user presses Enter while it has focus. JButtons fire an action event when activated (by user doing a mouse press and release inside it, or by the user pressing space while it has focus).
You want to add an ActionListener only once, typically right after you create the component to which it will be added. Since the ActionListener is a separate method, you will need to keep track of your attempts in an instance field:
private static final String PASSWORD = "1234";
private int attempts = 3;
// ...
private void buildWindow() {
// ...
jTextField2 = new JTextField(20);
jTextField2.addActionListener(e -> checkPassword());
// ...
}
private void checkPassword() {
if (password.equals(PASSWORD)) {
jTextField1.setText("Welcome ");
} else if (--attempts > 0) {
jTextField1.setText("Incorrect Pin, please try again");
} else {
System.exit(0);
}
}
Related
Question: Trying to get the same effect as the code below only with JTextArea so I want the JTextArea to be read and spelling suggestions to be recommended every time the user types a new misspelt word.
Below is the working example with 'System.in' which works well.
(Vars userField = JTextArea & dic.txt is a list of the english language for the system to use for suggestions)
CODE (1)
public SpellCheckExample() {
try {
SpellDictionary dictionary = new SpellDictionaryHashMap(new File(dic.txt));
spellCheck = new SpellChecker(dictionary);
spellCheck.addSpellCheckListener(this);
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
while (true) {
System.out.print("Enter text to spell check: ");
String line = in.readLine();
if (line.length() <= 0)
break;
spellCheck.checkSpelling(new StringWordTokenizer(line));
}
} catch (Exception e) {
e.printStackTrace();
}
}
What I have Been trying:
CODE (2)
public void spellChecker() throws IOException{
String userName = System.getProperty("user.home");
SpellDictionary dictionary = new SpellDictionaryHashMap(new File(userName+"/NetBeansProjects/"+"/project/src/dic.txt"));
SpellChecker spellCheck = new SpellChecker(dictionary);
spellCheck.addSpellCheckListener(this);
try{
StringReader sr = new StringReader(userField.getText());
BufferedReader br = new BufferedReader(sr);
while(true){
String line = br.readLine();
if(line.length()<=0)
break;
spellCheck.checkSpelling(new StringWordTokenizer(line));
}
}catch(IOException e){
e.printStackTrace();
}
}
March 3rd 2016 (Update)
public void spellChecker() throws IOException{
// getting context from my dic.txt file for the suggestions etc.
SpellDictionary dictionary = new SpellDictionaryHashMap(new File("/Users/myname/NetBeansProjects/LifeSaver/src/dic.txt"));
SpellChecker spellCheck = new SpellChecker(dictionary);
// jt = JTextField already defined in constructors and attemtpting to pass this into system and
InputStream is = new ByteArrayInputStream(jt.getText().getBytes(Charset.forName("UTF-8")));
//spellCheck.checkSpelling(new StringWordTokenizer(line)); ""ORIGINAL"""
// reccomending cast to wordfinder
spellCheck.checkSpelling(new StringWordTokenizer(is);
}
You don't want to try to drop console UI code into an event-driven GUI, as it will never work like that. Instead you need to use GUI events to trigger your actions, not readln's.
The first thing you must decide on is which event you wish to use to trigger your spell check. For my money, I'd get the user's input in a JTextField, not a JTextArea since with the former, we can easily trap <enter> key presses by adding an ActionListener on the JTextField. You can always use both, and then once the text is spell checked, move it to the JTextArea, but this is exactly what I'd recommend:
use a JTextField,
add an ActionListener to the JTextField to be notified whenever the field has focus and enter is pressed,
within this listener, extract the text from the JTextField, by calling getText() on the field
Then run your spell check code on extracted text,
and output the result into a nearby JTextArea.
Take a look at Concurrency in Swing for reasons why your current approach won't work, then have a look at Listening for Changes on a Document and Implementing a Document Filter for some possible solutions
As someone is bound to mention it, DON'T use a KeyListener, it's not an appropriate solution for the problem
Put simpler, Swing is a single threaded, event driven framework. So anything you do which blocks the Event Dispatching Thread, will prevent it from processing new events, including paint events, making your UI unresponsive
As an event driven environment, you need to register interested in been notified when some event occurs (this is an example of Observer Pattern) and then take appropriate actions based on those events.
Remember though, you can not make changes to a Document via a DocumentListener, so be careful there
I have an assignment for class, and I made a simple accounting program in Java with a GUI. This is my first time working with a GUI in Java, and i'm not that good a programmer.
When the program runs, the user can select five JButtons which when clicked takes them to a new JFrame with some input dialogs, which are saved as Strings and Doubles.
My variables are set to something like
variable = JOptionPane.showInputDialog("TEXTGOESHERE");
My Problem is that after entering values into the dialogs, they will pop up a second time, like in a loop. The user has to enter an input into every dialog twice.
Code for one of the buttons:
pcButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
JFrame pcframe = new JFrame("Choosing a File Menu");
pcframe.setSize(760,500);
pcframe.add( new JPanel()
{
public void paintComponent( Graphics g )
{
super.paintComponent(g);
//ACTION BEGIN-----------------------------------------
The input dialogs which are showing up twice:
compName = JOptionPane.showInputDialog("What is the name of your business?");
firstName = JOptionPane.showInputDialog("What is your first name?");
lastName = JOptionPane.showInputDialog("What is your last name?");
day = JOptionPane.showInputDialog("What is the day?");
month = JOptionPane.showInputDialog("What is the month?");
year = JOptionPane.showInputDialog("What is the year?");
String filename = JOptionPane.showInputDialog("Would you like file 1, 2, or 3? (Type in 1, 2, or 3");
filename = (filename + ".txt");
//Storing File into array
//Calculations
g.drawString("" + compName, 330, 15);
//More drawStrings
//ACTION END-------------------------------------------
}
});
pcframe.setVisible( true );
}
});
modePanel.add(pcButton);
When the pcButton is pressed, the user is supposed to enter their name, file, etc. However, every dialog input shows up twice. I want the inputs to show up just once.
Any help would be greatly appreciated, thanks.
Sorry, but that's all wrong. You should never call JOptionPanes or do anything other than painting from within a paintComponent method. You never have full control over when or even if that method gets called, and your program's perceived responsiveness is partly dependent on how fast that method completes its jobs. So my main recommendation -- get all non-painting code out of that method and into a method that you can fully control.
Myself, rather than throw a bunch of JOptionPanes at the user, I'd create a JPanel that has all the fields that I want the user to fill out, and then show one single JOptionPane that holds this JPanel, and get all the input all at once.
Next, your secondary dialog window should be a true dialog, and for Swing that means a JDialog (or JOptionPane which is a type of modal JDialog) and not a JFrame.
I have a panel just with a Jtextfield that only accept numbers. So, when I press enter will load a user profile. this is just to see his profile.
What I want: When I press ENTER again all the profile will be cleared, and when I press the numbers and press ENTER again and load the profile again and again...
My problem: I pressed enter and the profile is cleared (Ok all fine), but when I enter the number and press the ENTER, The numbers are cleared and nothing happens, it is like a loop in matriculaTxt.addKeyListener(new KeyAdapter() { ... }
Sorry for my bad English.
private void matriculaTxtActionPerformed(java.awt.event.ActionEvent evt)
{
String matricula = matriculaTxt.getText().trim();
if (!matricula.matches("[0-9]+")) {
matriculaTxt.setText("");
} else {
fc = new FrequenciaController();
matriculaTxt.setEditable(false);
matriculaTxt.requestFocus();
fc.checkinManual(Integer.parseInt(matricula));
}
// the problem is here.
matriculaTxt.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent evt) {
if (evt.getKeyCode() == KeyEvent.VK_ENTER) {
nomeTxt.setText("");
statusTxt.setText("");
imageLb.setIcon(null);
acessoLabel.setText("");
matriculaTxt.setText("");
observacaoTxt.setText("");
System.err.println("ENTER");
PendenciasTableModel ptm = new PendenciasTableModel();// vazio
pendenciasTabela.setModel(ptm);
matriculaTxt.setEditable(true);
matriculaTxt.requestFocus();
}
}
});
}
What I wanted to do was simple. The user types in the text field their numbers, pressing ENTER: their data are loaded. requestFocus() into the text field and it will not be editable anymore, because when I press Enter again the field will be editable but everything will be deleted, and so on.
First off, you should never use a KeyListener for this sort of thing. Consider instead using either a JFormattedTextField or using a DocumentFilter to prevent non-numeric entry. Next, you should use an ActionLIstener to have the JTextField accept and react to the user's pressing the Enter key.
Edit
You state:
my exact requirements is, when i press ENTER again all data will be cleaned for a new data be inserted.
Why not simply have in your JTextField's ActionLIstener:
#Override
public void actionPerformed(ActionEvent e) {
// get the text
JTextComponent textComp = (JTextComponent) e.getSource();
String text = textComp.getText();
// do what you want with text here
// clear the text
textComp.setText("");
}
Again, you should not use a KeyListener for any of this stuff.
Edit 2
If you want a multi-state action listener, one that reacts differently depending on the state of the program, then give it some if blocks to allow it to react to the state of the JTextField. If the field is empty, do one thing, if it has numbers, do another, if it has text, show a warning and clear it:
#Override
public void actionPerformed(ActionEvent e) {
// get the text
JTextComponent textComp = (JTextComponent) e.getSource();
String text = textComp.getText().trim(); // trim it to rid it of white space
if (text.isEmpty()) {
// code to show a profile
return; // to exit this method
}
// if we're here, the field is not empty
if (!text.matches("[0-9]+")) {
// show a warning message here
} else {
// numeric only data present
// do action for this state
}
// clear the text
textComp.setText("");
}
The key again is to not use a KeyListener, but rather to "listen" for the enter key press with the ActionListener only, but to react differently depending on the state of the program, here likely being depending on what content is present in the JTextField.
I think that your problem that the KeyListener it'll not trigger, it will not execute the code inside it, because whenever you press ENTER it will trigger the matriculaTxtActionPerformed then declared the KeyLister, so the ENTER will effect it.
I have a type game in which you have to type the words that appear as fast as possible before the time limit runs out, but every time you type a word, you must move the mouse and click enter and click back into the user input to type the next word. I was just hoping if there was way to use "keyCode.VK_Enter" to issue an Action Command called by the JButton.
Some snippets of my code:
The Enter button and user input and output:
enter = new JButton("Enter");
enter.setFont(serif); //serif is specified earlier
enter.setActionCommand("Enter");
enter.addActionListener(this);
container.add(enter);
userOutput = new JTextField(50);
userOutput.setFont(serif);
container.add(userOutput);
userOutput.setEditable(false);
userInput = new JTextField(43);
userInput.setFont(serif);
container.add(userInput);
userInput.setEditable(false);
The actionPerformed method getting the enter button's action command:
if(userInput.getText().equals(userOutput.getText())){
userInput.setText("");
score += 100;
Why don't you just add an actionlistener to the JTextField (which would be triggered when the user hits enter).
userInput.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// Do something
}
});
I am working on a project and have stuck at a point. I am working with Java Swing and this is the Problem:
When the user clicks on readMore button, I am creating an instance of class VerifyFF. Now, this class creates a frame which has an input field and two buttons namely cancel and continue. If the user presses cancel, then the frame disposes and nothing needs to be done. If he enters the correct password in the text field and then presses cont, I need to check whether the password is correct or not. For this I am using a boolean variable named as verified.
When the password entered is correct then the value of verified is set to true else nothing happens. The user gets and prompt of wrong password and again he can enter the correct password or can press cancel.
Now, in the class where I am creating the instance of VerifyFF class, I want to check whether the entered password was correct or not, hence I am checking for the value of variable boolean (which is also static). The trouble is, when the constructor of VerifyFF runs, there is nothing which stops the execution and waits for the user to enter something. Both the checking is done inside the function
JButton.addActionListener(new ActionListener()
{
};
The code in class instantiating the variable is:
VerifyFF vff = new VerifyFF();
if(vff.verified)
readMore();
Whenever I run this code, it doesn't waits to see whether any button is placed or not. I want to know how I can make it to wait till some button is pressed.
You don't have to wait until somebody pressed the button. Just move your
if(vvf.verified) readMode();
into your action listener for 'continue' button.
I am not sure of the problem. But maybe you should reconsider your implementation. In the constructor do just the first display then have a function that provides more whenever user clicks on more and password was correct.
You really do not need to stop constructor from being constructed, this sounds bad.
Good luck, Boro.
Your class should have a validatePassword method, which could be called on the click of the continue button.
class VerifyFF implements ActionListener {
private static final String ACTION_CONTINUE = "CONTINUE";
private JButton continueBtn = null;
private static boolean valid = false;
public VerifyFF() {
this.continueBtn = new JButton("Continue");
this.continueBtn.setActionCommand(VerifyFF.ACTION_CONTINUE);
this.continueBtn.addActionListener(this);
}
public static boolean validatePassword() {
//Validates the password field...
}
void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals(VerifyFF.ACTION_CONTINUE)) {
VerifyFF.valid = VerifyFF.validatePassword();
}
}
}
This way, the validate method is called on the press of the Continue button. and you can then do whatever you need according to the boolean 'valid'