In my swing application I want to echo jpassword field character for some time (1 second) and then again hide it. I want to do it character by character after user inputs a character (When user inputs a character, show it, then hide it. Then for all input characters repeat this).
Can someone tell me is it possible, if yes how?
Thanks in advance!
It's not very complicated, you can disable the masking characters when you set this value to “0″ with this method: setEchoChar((char) 0)
pass.getDocument().addDocumentListener(new DocumentListener() {
public void changedUpdate(DocumentEvent e) {
unhide();
}
public void removeUpdate(DocumentEvent e) {
unhide();
}
public void insertUpdate(DocumentEvent e) {
unhide();
}
public void unhide(){
pass.setEchoChar((char) 0);//display password
//here your timer
pass.setEchoChar('*');//hide with '*'
}
});
The code above shows you a first idea of what you should do. You'll have to use a thread to wait for the desired time.
I came across this which may be a good start as it displays the last char entered and shows the rest of the password is masked but doesn't hide it after a set time so you would probably need to implement an event to hide after set time Check it out here
Related
I recently run in to same problem as this guy 4 years before. He get some answers there but non of it work either for him or me and then the question was not updated anymore.
How to get string from JTextField and save it in variable?
The point is to check what is typed in textfield and if, like in example is yet decimal dot in the TextField, then consume event and not allow to add second decimal dot.
Main problem I figured out is that I need to add this inside the key event as shown belox. But this. statement inside the event reffers to event itself and not on JTextField.So I need to find bypass or other solution how to write getText statement
String text = this.getText().toString();
if someone have ideas of how to improve code as well I'm opened to any suggestions except for rewriting it as formatted field because the user experience is a little different, from the point where I was trying formatted field.
public class TxtfNumber extends JTextField {
String text = this.getText().toString();
public TxtfNumber(){
KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(new KeyEventDispatcher() {
#Override
public boolean dispatchKeyEvent(KeyEvent evt) {
switch (evt.getID()) {
case KeyEvent.KEY_TYPED:
String text = this.getText().toString();
if(evt.getKeyChar()=='.'&& text.contains(".")){
evt.consume();
}
}
return false;
}
});
}
}
SOLUTION
I accidentally run in solution when I used lambda expression. The formula you need to use is the name of class then .this.
So in this case,
String text = TxtfNumber.this.getText().toString();
is the solution.
But eventually, when I know how to implement JTextField, I no longer need a solution by string. So I'm giving the whole code here for later use. Feel free to use it as Choose Bean component.
It restricts the user to use only one minus sign at the start of the text, one decimal dot anywhere and then type in two decimal numbers.
import java.awt.KeyEventDispatcher;
import java.awt.KeyboardFocusManager;
import java.awt.event.KeyEvent;
import javax.swing.JTextField;
public class TxtfNumber extends JTextField {
public TxtfNumber(){
KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(new KeyEventDispatcher() {
#Override
public boolean dispatchKeyEvent(KeyEvent evt) {
switch (evt.getID()) {
case KeyEvent.KEY_TYPED:
//restricts input charactes
if(!Character.isDigit(evt.getKeyChar()) && (evt.getKeyChar()!='.') && (evt.getKeyChar()!='-') && (evt.getKeyChar()!=','))
evt.consume();
//change , and . for securing of different keyboard language
if (evt.getKeyChar()==',')
evt.setKeyChar('.');
//allow only one decimal dot in text
if (evt.getKeyChar()=='.' && TxtfNumber.this.getText().contains("."))
evt.consume();
//allow minus sign only at the start of text
if (evt.getKeyChar()=='-' && TxtfNumber.this.getText().length() != 0)
evt.consume();
//allow two decimal numbers after dot
for (int i = -1; (i = TxtfNumber.this.getText().indexOf(".", i + 1)) != -1; i++) {
if (i+3 == TxtfNumber.this.getText().length())
evt.consume();
}
break;
}
return false;
}
});
}
};
I've made a simple calculator using an tutorial online using Netbeans and it works fine when clicking the respective buttons, however I'm looking to improve it by allowing keypresses to work.
What I'd like is for the numbers 0-9 to work, +, -, *, / and enter as =.
I think I know how to do it, but can't seem to figure it out.
For example, the code for my 1 button is:
private void btnOneActionPerformed(java.awt.event.ActionEvent evt) {
String btnOneText = txtDisplay.getText() + btnOne.getText();
txtDisplay.setText(btnOneText);
}
So for the keypress I created a keypress event but I'm not sure what the code is. I assume it's something like this:
private void jPanel1KeyPressed(java.awt.event.KeyEvent evt) {
//if statement to check if 1 key has been pressed, then execute rest of code
String btnOneText = txtDisplay.getText() + btnOne.getText();
txtDisplay.setText(btnOneText);
}
However I'm probably completely wrong. Any help?
You can use either of KeyListener or KeyBindings depending on your usage.
Since you are designing a simple calculator, there is no harm with KeyListener since there are not many controls.
Demo code for the same is.
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
switch( keyCode ) {
case KeyEvent.VK_0:
//handle 0 press
break;
case KeyEvent.VK_1:
// handle 1 press
break;
case KeyEvent.VK_2:
// handle 2 press
break;
case KeyEvent.VK_3 :
// handle 3 press
break;
//
}
}
You can find the keycodes here : http://docs.oracle.com/javase/7/docs/api/java/awt/event/KeyEvent.html
I found some good Q/A here on my problem but couldn't find the right one.
I have a barcode reader that reads barcode and sends scanned code as keyboard input. It is alright I can catch input easily
browser.addKeyListener(new KeyAdapter() {
#Override public void keyPressed(KeyEvent e) {
if(e.keyCode >=48 && e.keyCode <=57) {
System.out.println("number caught");
}
}
});
But I will have more inputs in my application so I need to know if it is send by barcode reader or by keyboard.
I think it can be achieved by adding some timer in code that verifies how long is some "sequence" reading.
I just can not figure it out, (I mean logic behind it), I am missing piece of logic.
User is typing some info, (alpha numerical)
user desides to use barcode reader to read barcode
I tried timer e.g
if(System.currentTimeMillis() - lastPressProcessed ??? 500) { after keyListener is triggered but I think I am missing something.
sidenote:
USB barcode reads code fast so keystrokes are emulated really fast est whole barcode is written in about 1 second + carry /r/n (also enter is pressed).
sidenote2: barcodes are going to be different in length so I can not read just some length in short time and decide wether it is user input or barcode input (max numbers read 13 + enter).
sidenote3: I have no input field for barcode I am trying to achieve running it on "background".
I am seeking logic/pseudocode suggestions on topic.
related topics that are really close to mine are here, and here
Thank you.
edit
After deep tought I found out the solution I'll keep this Q here just for another users that might find this usable.
solution
--moved to answer + edited
This code coveres everything I wanted to achieve, it reads just numbers (actualy numbers that are under F keys, not numbers that are on numpad, I had problem with it because scanner is keyboard dependant so I made function signsToNumbers() that converts signs !##$%^&*() to numbers 1234567890. I may change this function because every key on keyboard has its own unique identifier + modifier, it seems that scanner sends also SHIFT modifier to the application but that is not as problem as it seems I'll just match e.keyCode.
The code below works as:
waits for number input otherwise does nothing
if 1st number is inserted it is looping in if condition until either 200ms is reached or '\r\n` is received
sends data to server via URL
code
#Override public void keyPressed(KeyEvent e) {
if (timer == true && System.currentTimeMillis() - lastTimer < 200) {
if(e.keyCode >=48 && e.keyCode <=57) { //number pressed
lastTimer = System.currentTimeMillis();
myString = myString + Character.toString(e.character);
}
if(e.keyCode == SWT.CR) {
myString = signsToNumbers(myString);
newUrl = browser.getUrl()+ "/newcode/" + myString;
browser.setUrl(newUrl);
text.setText(newUrl);
System.out.println(myString);
System.out.println("barcode read");
myString = "";
timer = false;
lastTimer = 0;
}
}else{
if(e.keyCode >=48 && e.keyCode <=57) {
lastTimer = System.currentTimeMillis();
timer = true;
myString = Character.toString(e.character);
}
myString = "";
lastTimer = 0;
}
}
});
Here you can download my solution:
http://jhead.hu/resource/java/general/BarcodeReader.java
The following code sample shows you, how to use it. When a new barcode is identified, an ActionEvent is generated and you can get the barcode via the getActionCommand() method. If the panel is not active you can send the characters further to the focus manager.
The only problem is that my barcode scanner sends the characters too fast so the character bits are sometimes mixed. I've got no better solution yet.
public class PanelWithBarcodeReading extends javax.swing.JPanel implements ActionListener {
private BarcodeReader barcodeReader = new BarcodeReader();
public PanelWithBarcodeReading() {
initComponents();
barcodeReader.addActionListener(this);
barcodeReader.setParent(this);
KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(barcodeReader);
}
#Override
public void actionPerformed(ActionEvent e) {
if (SwingUtilities.getWindowAncestor(this).isActive()) {
System.out.println("BARCODE='" + e.getActionCommand() + "'");
} else {
barcodeReader.dispatchLastBarcodeAsKeyEvents();
}
}
...
}
I am building a GWT component to behave much like the comments box here on stackoverflow, and other sites. I am trying to register listeners for KeyPress, Change and ONPASTE events that will update my status line with number of characters remaining, etc.
It works except it is always one character behind the actual number of characters in the text area. I set the max number of characters to 10. When I type the first character it still says, "10 characters remaining". It doesn't update the status line until I type the second character and then it is one off, it says 9 characters remaining when the second character is typed.
When I BACKSPACE or DELETE, it is also one off, when there are no characters it still says "9 characters remaining" until I press the BACKSPACE or DELETE a second time.
I am getting this behavior in both Firefox, Chrome and Internet Explorer on Windows. So I think I am not registering something correctly.
I know this has something to do with when the events are getting fired, but I have spend hours on trying to diagnose this behavior and have run out of ideas.
Here is where I am registering the event handlers, the complete code is BoundedTextAreaWithFeedback.
private void registerHandlers()
{
final BoundedTextAreaWithFeedback outer = this;
this.textArea.addChangeHandler(new ChangeHandler()
{
public void onChange(final ChangeEvent changeEvent)
{
outer.validate();
}
});
this.textArea.addKeyPressHandler(new KeyPressHandler()
{
public void onKeyPress(final KeyPressEvent keyPressEvent)
{
outer.validate();
}
});
this.panel.addFocusHandler(new FocusHandler()
{
public void onFocus(final FocusEvent focusEvent)
{
outer.textArea.setFocus(true);
}
});
// capture paste events
this.textArea.sinkEvents(Event.ONPASTE);
}
Here is the validate() method.
private boolean validate()
{
final boolean isValid;
final int len = this.textArea.getText().length();
if (len < this.minLength)
{
this.status.setText("Enter at least " + this.minLength + " characters.");
this.status.setStyleName("input-status-underflow");
isValid = false;
}
else if (len > this.maxLength)
{
this.status.setText(this.maxLength - len + " characters remaining");
this.status.setStyleName("input-status-overflow");
isValid = false;
}
else
{
this.status.setText(this.maxLength - len + " characters remaining");
this.status.setStyleName("input-status-ok");
isValid = true;
}
return isValid;
}
I just started adding every addXXXHandler() until one worked.
this.textArea.addKeyUpHandler(new KeyUpHandler()
{
public void onKeyUp(final KeyUpEvent event)
{
outer.validate();
}
});
Seems to have done the trick.
Here is the working code, CTRL-V and paste from context menu also work now.
Try using a DeferredCommand to execute the validation code. I believe the problem is that when the event is firing, they character is not yet added to the text area. The DeferredCommand will not execute until any pending event handlers have finished, allowing the length of the text to be calculated correctly.
See this question for an example of using a DeferredCommand.
I'm trying to learn something about GUI, using NetBeans6.8, starting with the GUI section in The java tutorial.
There is a simple exercise for a Celsius-Fahrenheit converter. I want that to have two TextFields, one for Celsius and one for Fahrenheit temperature; if the user types in the celsius text field he got the result "printed" in the fahrenheit text filed. and vice versa.
So, i put on both the textfields one KeyTyped event, here's the code:
private void celsiusTextKeyTyped(java.awt.event.KeyEvent evt) {
int cels = Integer.parseInt(celsiusText.getText());
int fahr = (int)(cels * 1.8 + 32);
fahrText.setText(fahr + "");
}
private void fahrTextKeyTyped(java.awt.event.KeyEvent evt) {
int fahr = Integer.parseInt(fahrText.getText());
int cels = (int)(fahr / 1.8 - 32);
celsiusText.setText(cels + "");
}
It doesn't work. If i type something in a textfield i got this exception: java.lang.NumberFormatException: For input string: ""
The code that attach the listeners:
celsiusText.addKeyListener(new java.awt.event.KeyAdapter() {
public void keyTyped(java.awt.event.KeyEvent evt) {
celsiusTextKeyTyped(evt);
}
});
fahrText.addKeyListener(new java.awt.event.KeyAdapter() {
public void keyTyped(java.awt.event.KeyEvent evt) {
fahrTextKeyTyped(evt);
}
});
[However, i can't modify it, it's autogenerated.]
Method .getText() returns a string not a number, if that string contains non-numeric characters (i.e. a letter, a space, nothing at all) then parseInt will throw a NumberFormatException. Since your using KeyEvent, as soon as you press say "7", the event is fired before 7 is entered into the text box. Thus the text box still only contains "", which is where the error comes from. You may wish to also listen to the keyUp event instead.
You need to enclose your code in a try catch block.
private void fahrTextKeyTyped(java.awt.event.KeyEvent evt)
{
try
{
int fahr = Integer.parseInt(fahrText.getText());
int cels = (int)(fahr / 1.8 - 32);
celsiusText.setText(cels + "");
}
catch(NumberFormatException ex)
{
//Error handling code here, i.e. informative message to the user
}
}
An alternative is you could filter out non-numbers on keydown event, see example here - http://www.javacoffeebreak.com/java107/java107.html (Creating a custom component - NumberTextField)
I suspect that what's happened is that you added these handlers with something like celsiusText.addKeyListener, yes?
The thing is, that'll give you not just the KEY_TYPED events you wanted, but also KEY_DOWN and KEY_UP. The KEY_DOWN event will happen before the text is really entered into the field, so your code firing on that will see the field as blank still. Trying to convert the empty string to a number gives you a format exception.
The easiest way to fix this is the try/catch construct other people have been posting.
You probably set action to keyDown, this mean that even occur before the key value is "added" to textbox, while You retrieve the value from it is still empty "".
There is a simple exercise for a
Celsius-Fahrenheit converter
That is a really old example. The better approach is to use a DocumentListener, not a KeyListener.