I'm working on a JTexfield which sets its own text to the name of the key pressed when it has the focus on the window. I've managed to let it have only a word with the code:
#Override
public void keyReleased(KeyEvent ev) {
if (ev.getKeyCode() != 0) {
keyTrigger = ev.getKeyCode();
txtTrigger.setText(ev.getKeyText(keyTrigger));
}
}
#Override
public void keyTyped(KeyEvent ev) {
txtTrigger.setText("");
}
However it looks horrible when you press special keys like F1--12 or Ctrl because it keeps the last typed non-special key (for example, if you press 'T' and then 'Ctrl', the text in the field keeps being 't' until you release the 'Ctrl' key).
This is the code so far for the JTextField:
txtTrigger = new JTextField();
txtTrigger.setColumns(10);
txtTrigger.addKeyListener(this);
txtTrigger.setBounds(80, 5, 64, 20);
contentPane.add(txtTrigger);
What I want is the field to be empty until you release the key. How can I get the application working this way?
I don't think a editable text field is your best choice here. What I've done in the past is basically faked it.
I've generated a custom component that "looks" like a JTextField and, using my own KeyListener, I've added elements to the view (I did my own "key" renderer, but you could simply have a list of String elements that you can render).
Basically, when keyPressed is triggered, I would add the key code to a list (taking into consideration things like its modifier state). If another key event is triggered with the same key code, then you can ignore it.
When keyReleased is triggered, you can remove that keycode from the active list.
You can add the keylistener to the jframe or many components...
Just make sure that component has the focus.
Related
I have a JEditorPane with text/html type. When an enter key is pressed with the editor focused, I want to do some checks about the state of the document and then override the enter key default functionality if conditions are met.
I believe this can be done with a KeyListener listening for a key, then consume the event if conditions are met to cancel the key making any change to the input. Testing this idea I'm just trying to consume the key event when any key is pressed. The key listener below is printing output when i press any key, but the characters are still getting inserted into the editor pane.
How can I stop the characters getting inserted altogether?
Thanks for your help.
String content = "";
String type = "text/html";
editor = new JEditorPane(type, content);
editor.setEditorKit(new HTMLEditorKit());
editor.setEditable(true);
editor.setPreferredSize(new Dimension(500, 500));
panel.add(editor);
editor.addKeyListener(new KeyAdapter() {
#Override
public void keyPressed(KeyEvent e){
System.out.println("huh?");
e.consume();
}
});
EDIT----------
Removed key listener, and added instead
Action enter = new AbstractAction()
{
public void actionPerformed(ActionEvent e)
{
System.out.println("enter!");
if ( condition == true ){
// default enter key behaviour
}
}
};
editor.getActionMap().put("insert-break", enter);
Ok I got rid of the KeyListener and added this, which prevents the default enter-key functionality which is great. But how would i insert a break (the default enter key behaviour) if my if clause is true?
I can't figure out how to trigger that on the editor programmatically.
You are over thinking it.
We save the Action because we want to invoke the actionPerformed(...) method of the Action.
Assuming the original Action is stored in the variable "original" the code would be:
if (condition == true)
original.actionPerformed( e );
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.
Here is my application. It's a wallet to update my money when I spend or get profit. Look it up on image hosting here http://tinypic.com/r/687bdk/8
Is there a way to detect that a cursor has been put into one of the JTextFields? If there is, then could I dispatch a method that would delete whatever is in the other JTextField? There should only be one JTextField with input, it is unacceptable to have inputs in both text fields.
You can add a FocusListener to each textfield i.e.
JTextField myTextField = new JTextField();
myTextField.addFocusListener(new FocusListener() {
#Override
public void focusGained(FocusEvent e) {
//when selected...
}
#Override
public void focusLost(FocusEvent e) {
//when not selected..
}
});
Is there a way to detect that a cursor has been put into one of the JTextfields? If there is, than I could dispatch a method that would delete whatever is in the other JTextField.
As a user I'm not too crazy about that design. I've used accounting type applications before where you have two columns (debit/credit) and a number can only be entered into one.
In those applications the number is not removed on focus, it is removed if a value is entered in the other field. This allows for tabbing between fields on the forum without data disappearing just because focus changes.
To implement this type of functionality you would add a DocumentListener to the Document of the text field. Then whenever text is entered into the Document the listener is invoked and you can clear the text from the other text field.
Check out the section from the Swing tutorial on How to Write a DocumentListener for more information and examples.
It called: CaretListener
jTextArea=new JTextArea();
jTextArea.addCaretListener(new CaretListener(){
public void caretUpdate(CaretEvent e){
//your code
}
}
);
It mainly used when you need to know that your caret position is changed.
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.
ChatGUI
im using 2 JEditorPane to transfer text from one to another.
once i have transfered the data i do the following:
JEditorPane.setText(null);
JEditorPane.setCaretPosition(0);
but as you can see from the attached image the return action makes the prompt appear a row down. how can i fix this?
EDIT: does the following seem correct to you? if so then why is caret not positioning itself to chracter 0 position?
private class MyKeyAdapter extends KeyAdapter {
#Override
public void keyPressed(KeyEvent ke) {
int kc = ke.getKeyCode();
if (kc == ke.VK_ENTER) {
System.out.println(editorPaneHistory.getText());
System.out.println(editorPaneHomeText.getText());
editorPaneHistory.setText(editorPaneHomeText.getText());
//JEditorPane - editorPaneHistory
//JEditorPane - editorPaneHomeText
editorPaneHomeText.setText(null);
editorPaneHomeText.setCaretPosition(0);
}
}
}
After your code runs, the JEditorPane is reacting to the enter key in the usual way, by inserting a newline. Try calling ke.consume() to "consume" the event so that the JEditorPane itself doesn't handle it.
Don't use a KeyListener. You should be using a custom Action. This way you can replace the default Action. Read up on Key Bindings.