First off I making a simple typing program. If you type the a letter and hit the spacebar the TTextArea will be matched with the label text to see if it matches. But it keeps coming out wrong cause there is space added before the letter after the first output everytime and I do not understand why? Is this something that just happens or can ypu
The is my code
public void keyTyped(KeyEvent e) {
if(e.getKeyChar() == KeyEvent.VK_SPACE){
input = textArea.getText();
if(input.length() <= 0){
JOptionPane.showMessageDialog(null, "Type something first");
} else {
input.trim();
System.out.println(input);
gameLogic.score(input, letterLabel.getText());
gameLogic.error(input, letterLabel.getText());
scoreLabel.setText("Score: " + String.valueOf(gameLogic.score));
errorLabel.setText("Errors: " + String.valueOf(gameLogic.error));
gameLogic.changeDifficulty();
letterLabel.setText( gameLogic.changeText());
textArea.setText("");
textArea.setCaretPosition(0);
}
}
this is my output
l
l
x
k
ss
Several things...
KeyListener is not a recommend way to deal with monitoring or effecting the changes to any text component. If you are lucky enough that the key stroke isn't consumed by the component, the component has already being updated with the last key stroke.
A better approach would be to use a DocumentListener if you just wanted to monitor changes to the text component or a DocumentFilter if you want to change what is being passed to the field.
Check out Using Text Components for more details
Related
I have a requirement where need to mask the value entering into jText area at runtime. I am able to achieve this but problem is scenario with backspace. When I press back space sequentially (one by one) then it work while if I kept pressing then its counting the event as one and removing only one character (by considering the key event as one key released).
Here my code snippets is :
public void showPrompt() throws InterruptedException {
sem.acquire();
this.toFront();
this.setAlwaysOnTop(true);
this.setVisible(true);
if(encryptKeystroke == true) {
jTextArea.addKeyListener(new KeyListener() {
public void keyTyped(KeyEvent e) {
}
public void keyPressed(KeyEvent e) {
}
public void keyReleased(KeyEvent e) {
if (e.getExtendedKeyCode() == KeyEvent.VK_BACK_SPACE) {
text = text.substring(0, text.length() - 1);
}
else {
text += String.valueOf(e.getKeyChar());
}
jTextArea.setText(text.replaceAll(".", "*"));
}
});
}
}
Is there any way if I kept pressing the backspace then it should remove all the characters irrespective of considering it one key event ?
As you have said in the comment that the requirements are not exactly like the password and so you won't be using JPasswordField, I would like to give a solution for the question.
Here, the code to detect a backspace key stroke is written inside the keyReleased() method. Now, the keyReleased() method will be called by the keyListener when you will pull your finger up from a key in this case your backspace key. That is why even if you continuously keep pressing the backspace key, it will execute the code only once i.e. only when you release the key.
Now, you wish to remove one character every time backspace is pressed so you can just move your code from the keyReleased() method to the keyPressed() method.
If you move the code inside the keyPressed() method, then the code will be executed at every key stroke even if you continuously keep pressing the backspace key.
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 problem with my code. I think that my problem is easy,but i have compiled for 3 days without good results. I have three images. They are put on screen one-one each time. User choose from 4 button if image's side is up, down, right or left. Also, i want to understand if user was wrong and then i will count errors. When user make 3 errors then the game will stop. I have shown code below. Please help me if you have any good idea.
The problem is that at the first loop,run right.It goes at the first if. After that it do the loop and then it does not go to second if.
if it is more helpful,some details:
i want to make a programma that it will show to user an image.This image has 4 sides (up,down,right,left).When the image is at "up side",user has to click on up button,when the image is at "down side",user has to click on down button etc. User can do 3 errors max. At first,program show the image at right side,if user clicks on right button then i want to show the "second image" at left side.If user does not at left side,then i want to add an error(error++) and after it shows the third image at up side etc. I hope it is more helpful to understand. If you can't please let me know.
My program is at Netbeans,java.
Thank you
public void actionPerformed(ActionEvent e)
{
while(errors<3)
{
image.setIcon(createImageIcon("visual1" + e.getActionCommand() + ".PNG"));
if (k==1)
{
if(e.getSource() == right_button)
{
image.setIcon(createImageIcon("visual2" + e.getActionCommand() + ".PNG"));
}
}
else if ( k==2 )
{
if(e.getSource() == left_button )
{
image.setIcon(createImageIcon("visual3" + e.getActionCommand() + ".PNG"));
}
}
else if (k==3 )
{
if(e.getSource() == up_button)
{
System.out.print("if3");
}
}
else
{
errors++;
}
k=k+1;
}
}
You should consider calling Repaint and Invalidate, right after you update your GUI like this -
mainframe.repaint();
mainframe.invalidate();
here mainframe is your JFrame object.
A problem I see with your while loop is that it is at risk of getting stuck in an infinite loop, since the variable used as an exit criterion is only updated some of the time, in an else block. I think you should re-arrange your logic:
Get rid of that while loop as it will only cause trouble. It is useful for a linear command line program but not for an event-driven GUI program like yours.
Read in all images and create all ImageIcons in the class constructor, and store them in variables. There's no need to re-read the images multiple times (unless they're huge).
Instead of using a while loop, increment the error variable in your method above, and then write the method so that it will change behaviors depending on the value of error (depending on the state of the class).
e.g.,
// somewhere in your code create your icons
Icon rightIcon = ......;
Icon leftIcon = .....;
Icon upIcon = .....;
Icon downIcon = .....;
// elsewhere in your code
public void actionPerformed(ActionEvent e) {
if (errors >= 3) {
// notify user of error
return; // end this method
}
// check if current icon matches image
// if so, change icon
// if not increment error
}
Note that an enum Direction {UP, DOWN, LEFT, RIGHT} and a Map<Direction, Icon> could be helpful here.
I am writing a GUI for animation in Java. I am completely stumped on one element. I have a 2 JTextAreas that are called InputText, and OutputText where the input is copied to the output area with the use of a copy Jbutton. I then have a Next and Previous Button that should switch through frames on the OutputText area. I used a JLabel as a counter in between these two buttons.
What I am trying to do is use the clipboard to hold each "frame" if you will, on the Output JTextArea as I flip through the counter. As well as return the text once I flip backwards through the counter. Is this even possible? I have looked through multiple links online that describe Clipboard usage, but none of the examples that I have come across give a solid understanding how to do this.
Please see code below:
*Note I have left out unimportant elements that I already know work! Thanks!
This is called at the top of my Java file:
private Clipboard clipbd = getToolkit().getSystemClipboard();
public static final int MAX_COUNT = 10;
//sets maximum for count
public static final int MIN_COUNT = 1;
//sets minimum for count
private int count = 1;
//sets up integer for counter
This is called in the ActionListener:
public void actionPerformed ( ActionEvent event ) {
boolean status = false;
String OutputText1;
if(event.getSource()== CopyButton){
//get text from InputText
OutputText1 = InputText.getText();
//put text into OutputText field
OutputText.setText(OutputText1);
}//end if for CopyButton
if(event.getSource() == NextButton){
//LabelOutPut.setText("Next");
if (count < MAX_COUNT) {
count++;
}//end if
LabelCounter.setText("" + count);
OutputText.setText("");
}//end if for NextButton
if(event.getSource() == PreviousButton){
//LabelOutPut.setText("Previous");
if(count > MIN_COUNT){
count--;
}//end if
LabelCounter.setText("" + count);
}//end if for PreviousButton
Why would you use a Clipboard to hold text. Just use a String and the data is in the control of your program. I don't see any reason to complicate your processing.
Also, follow standard Java naming conventions. Varible names should NOT start with an upper cased character.
LabelCounter ==> labelCounter
You only need the SystemClipboard if you want to get copied/pasted data from places outside your program. If you just have to copy between 2 places in your own program, and you need history etc... just use a variable in your code (string, or list of strings, or whatever) and just update this when they click the button. Camickr mentions the same as well...
The JTextField is a calculator display initialized to zero and it is bad form to display a decimal number with a leading 0 like 0123 or 00123. The numeric buttons (0..9) in a NetBeans Swing JFrame use append() [below] to drop the leading zeros, but the user may prefer the keyboard to a mouse, and non-numeric characters also need to be handled.
private void append(String s) {
if (newEntry) {
newEntry = false;
calcDisplay.setText(s);
} else if (0 != Float.parseFloat(calcDisplay.getText().toString())) {
calcDisplay.setText(calcDisplay.getText().toString() + s);
}
}
You could restrict the characters input to the JTextField by adding a custom KeyListener. Here is a quick example to demonstrate the idea:
myTextField.addKeyListener(new KeyAdapter() {
#Override
public void keyTyped(KeyEvent e) {
char c = e.getKeyChar();
if (!Character.isDigit(c)) {
e.consume(); // Stop the event from propagating.
}
}
});
Of course, you need to consider special keys like Delete and combinations like CTRL-C, so your KeyListener should be more sophisticated. There are probably even freely available utilities to do most of the grunt work for you.
You can do this with DocumentFilter.
(Edit: This answer originally included a ling to a simple complete example program on my now defunct weblog.)