In my application four TextArea is there and I want to enter only four character in one Text area and cursor automatically move to next TestArea. Again when I enter four character in this TextArea then again cursor automatically move to next TextArea.
Example: At the time of installing Window XP it want "Key" and there are four section when you enter four character in first section then cursor automatically move to the next section.
Same thing I want in my application.
For this first of all I add CustomizedTextFields.jar and then created four IntegerField:
private IntegerField text1;
private IntegerField text2;
private IntegerField text3;
private IntegerField text4;
after this I show all these IntegerField on my frame.
Now I tried this code to send cursor to the next field but it's not working:
text1.addKeyListener(new KeyListener() {
#Override
public void keyTyped(KeyEvent e) {
int a2 = text1.getText().length();
if (a2 == 3) {
text2.getCursor();
}
}
#Override
public void keyReleased(KeyEvent e) {
}
#Override
public void keyPressed(KeyEvent e) {
}
});
interesting enough question to try improving my shadowy knowledge of the text package :-)
There are two separate requirements here
restrict the lenght of the text: that's done with a DocumentFilter as #mKorbel already noted
automatically transferFocus to the next component after the max length is reached: turns out that can be done with a NavigationFilter
in code:
JComponent panel = new JPanel();
final int maxSize = 3;
for (int i = 0; i < 4; i++) {
final JTextField field = new JTextField(5);
NavigationFilter filter = new NavigationFilter() {
#Override
public void setDot(FilterBypass fb, int dot, Bias bias) {
if (dot >= maxSize) {
fb.setDot(0, bias);
field.transferFocus();
return;
}
fb.setDot(dot, bias);
}
#Override
public void moveDot(FilterBypass fb, int dot, Bias bias) {
if (dot >= maxSize) {
fb.setDot(0, bias);
field.transferFocus();
return;
}
fb.moveDot(dot, bias);
}
};
field.setNavigationFilter(filter);
((AbstractDocument) field.getDocument()).setDocumentFilter(new DocumentSizeFilter(maxSize));
panel.add(field);
}
The documentFilter is the one from the Swing Tutorial
At the time of installing Window XP it want "Key" and there are four section
when you enter four character in first section then cursor automatically move
to the next section.
add DocumentListener to the JTextComponents, for listening add DocumentFilter
don't use KeyListener for JTextComponents, use only DocumentListener
add required next JTextArea to the DocumentListener, if is there typed 4th. Char into JTextArea,
notice, moving with Focus from one JTextArea to another would be better wrapped into invokeLater
Replace text2.getCursor() with text2.requestFocus().
getCursor() is for retrieving the shape of the mouse pointer when hovering over a component.
Also, with this method it is still possible to enter more than 4 chars in a field, for example by pasting from clipboard. If you want to block that, you would need to check if text entered is longer than 4 chars, and if so, take only first 4 chars from it.
Something like this should work:
text1.addKeyListener(new KeyAdapter(){
public void keyPressed(KeyEvent e){
String value=text1.getText();
if(value.length()==4){
text2.requestFocus();
}
}
Where text2 is your next textfield
simply just create textarea and go to key typed events
den u may write this
String number=jTextArea1.getText();
int l=number.length();
if(l==3){
jTextArea1.transferFocus();
}
Related
In most text editors and platforms there are two ways of selecting text using the mouse:
The regular, Click+Drag, moves the end of the selection along with the mouse cursor
Double-click+Drag, same as #1 but it starts by selecting one whole word, and then snaps the end of the selection to whole words
In Swing GUI however, #2 does not work as above. It starts correctly by selecting the whole word where the double-click was, but then it does not snap to whole words during selection.
Is there any way to get Swing text fields to behave as 2, with the selection snapping to whole words?
You can create a method to calculate the index of where word your selection ends and starts. See below:
int getWordEndPos(String text, int initPos) {
int i = initPos;
while(Character.isAlphabetic(text.charAt(i))) {
i++;
}
return i;
}
int getWordStartPos(String text, int initPos) {
int i = initPos;
while(Character.isAlphabetic(text.charAt(i))) {
i--;
}
return i+1;
}
Then in your UI (not sure exactly how JTextArea works) you could get the start and end position of your selection, and actually selects the start and end position of their words:
void updateSelection(JTextArea ta) {
String text = ta.getText();
int start = ta.getSelectionStart();
int end = ta.getSelectionEnd();
start = getWordStartPos(text, start);
end = getWordEndPos(text, end);
ta.select(start, end);
}
But where to call the snippet above? You could listen to CarretEvent instead of MouseEvent (see Which event a selection of text trigger in Java JTextArea?):
textArea.addCarretListener((evt) -> updateSelection(textArea));
But another problem arrises: how to know the click count of MouseEvent. You could make an attribute to store it, and then into the mouse event listener, it can be set. The code below tries to put everything toghether:
class UI implements MouseListener, CarretListener {
JTextArea textArea;
int clickCount = 0;
UI() {
textArea.addCarretListener(this);
textArea.addMouseListener(this);
// ...
}
#Override
void mouseClicked(MouseEvent evt) {
this.clickCount = evt.getClickCount();
// other stuff
}
// other MouseListener methods
#Override
void caretUpdate(CaretEvent evt) {
if (clickCount == 1) updateSelection(textArea);
// other caret listener stuff
}
void updateSelection(JTextArea ta) {
String text = ta.getText();
int start = ta.getSelectionStart();
int end = ta.getSelectionEnd();
start = getWordStartPos(text, start);
end = getWordEndPos(text, end);
ta.select(start, end);
}
}
I have a problem with JTextPane font color and cannot seem to find a solution.
I have a text box (JTextPane) where the user is typing in text. At some point he presses a button which will change the color of some of the words.
SimpleAttributeSet attr = new SimpleAttributeSet();
StyleConstants.setBackground(attr, Color.RED);
StyledDocument doc = inputArea.getStyledDocument();
//find the start of the word
String wholeText = inputArea.getText();
int i = 0;
while (i <= wholeText.length() - word.length()) {
if (wholeText.substring(i, i + word.length()).equals(word)) {
doc.setCharacterAttributes(i, word.length(), attr, false);
}
i ++;
}
The problem now is that if this word is the last one from the text, if the user returns back to writing text, the newly typed text is red, not black. I have spent 2 hours trying to figure it out, but no luck.
Edit: I have also tried using Highlighter, but the problem is the same.
I've use the following code before after inserting text with attributes into a document:
// Newly typed text at the end of the document will inherit the
// "keyword" attributes unless we remove the attributes
textPane.setCaretPosition(doc.getLength());
textPane.getInputAttributes().removeAttributes(keyWord);
Ok, so I figured it out so I will post my solution.
Even with the above solution if I clicked the highlighted word and for example added a character to it, the caret would become red and won't be fixed by anything.
That is why I added a key listener to the text pane and on each key stroke I did this:
inputArea.addKeyListener(new KeyListener() {
#Override
public void keyTyped(KeyEvent e) {
StyleConstants.setForeground(blackColor, Color.BLACK);
inputArea.setCharacterAttributes(blackColor, false);
}
#Override
public void keyPressed(KeyEvent e) {
}
#Override
public void keyReleased(KeyEvent e) {
}
});
Where black color is of type SimpleAttributeSet. This may be not very elegant, but solves it.
I have a keypad made up of jbuttons and a jtextfield that has an action listener. When I press the button the number shows in the textfield but the next number overwrites it. Could anyone tell me how to append the text to the length 13 numbers and when it get's there to carriage return.
If I use the keyboard to enter numbers I can enter a String of numbers but not from the buttons.
I am using:
JButton buttonNo2 = new JButton("2");
buttonNo2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
textfield.setText("2");
}
buttonNo1.setBounds(11, 18, 50, 50);
keyboardPanel.add(buttonNo2);
buttonNo1.setForeground(Color.BLUE);
buttonNo1.setFont(new Font("Perpetua", Font.BOLD, 20));
Try using something like
textfield.setText(textfield.getText() + "2");
instead of textfield.setText("2");
setText does just that, sets the text of the text field to the value you specified.
Also buttonNo1.setBounds(11, 18, 50, 50); looks like you're trying to do without a layout manager. Avoid using null layouts, pixel perfect layouts are an illusion within modern ui design. There are too many factors which affect the individual size of components, none of which you can control. Swing was designed to work with layout managers at the core, discarding these will lead to no end of issues and problems that you will spend more and more time trying to rectify
You could also make it much simpler for yourself, and use the Action API instead, which would save you a not lot of repeated typing...
public class NumberAction extends AbstractAction {
private JTextField field;
private int number;
public NumberAction(JTextField field, int number) {
this.field = field;
this.number = number;
putValue(NAME, Integer.toString(number));
}
#Override
public void actionPerformed(ActionEvent e) {
Document doc = field.getDocument();
try {
doc.insertString(doc.getLength(), Integer.toString(number), null);
} catch (BadLocationException ex) {
ex.printStackTrace();
}
}
}
Then you would just need to add each button as required...
add(new JButton(new NumberAction(textfield, 1)));
add(new JButton(new NumberAction(textfield, 2)));
add(new JButton(new NumberAction(textfield, 3)));
See How to Use Actions for more details
You have to get the text first and set the text by appending the previous and current text.
public void actionPerformed(ActionEvent e) {
String str = textfield.getText();
textfield.setText(str+the number printed);
}
As #MadProgrammer already posted How to achieve it with JTextField ,
You can opt for JTextArea#append method
public void append(String str)
Appends the given text to the end of the document. Does nothing if the
model is null or the string is null or empty.
Parameters:
str - the text to insert
I have added set of integers to a JTextArea for each button click.
what exactly I want is that I want to add all the integers and display in a separate JTextArea,Also I want to ask whether we can access the value of a variable within an action listener outside the action listener.
Here is the code:
private ActionListener listener = new ActionListener() {
#Override
public void actionPerformed(ActionEvent evt) {
if(evt.getActionCommand().equals(t.getText()))
{
onec=one.calone(n);
td.append(Double.toString(onec));
td.append("\n");
}
res=Integer.parseInt(td.getText());
}
};
When the user presses button 't' It will keep on adding the integer 'onec' to
textarea 'td' using append method.And I have stored the result from the action
listener into a variable 'res' of double datatype.
private ActionListener listener2 = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if(e.getActionCommand().equals(tot.getText()))
{
totd.setText(Double.toString(res));
}
}
};
When the user clicks the button 'tot',It should add all the integers in the
textarea 'td' and display it in the textarea 'totd'.
This code is not working.
Please help me this is the last part of my project.
As I don't know what is not working - it would of been good if you explained more clearly - my guess is...
Instead of Double.toString(onec)
Use String.valueOf(onec)
EDIT: If this is not the case, please elaborate on what your problem is, and a fuller code listing.
converting the contents of the textArea to double does not calculate sum. Try looping throught the first textArea reading each value while calculating the sum
I'm trying to add functionality to a Swing JLabel and JTextArea such that:
The user is only allowed to enter 500 characters into the textarea (max)
The label contains a string message telling the user how many characters they have left (after every key stroke or backspace)
When the components initialize the label reads "500 characters maximum!"
For the first 500 characters typed, for every keystroke (a - z, A - Z, 0 - 9, and punctuation) typed, the label reads "x characters remaining", where x is the number of chars they have left before they reach the max of 500
When the 500th character is typed, the label reads "0 characters remaining", and no further characters can be typed into the text area
If the user types the backspace button (KeyEvent.VK_BACK_SPACE), they "free" up a character, and the count increments. Thus if they had 400 characters remaining, and they type backspace, the label now reads "401 characters remaining"
If the user highlights a set of characters and performs a bulk command on them (such as a backspace, or replacing the highlighted text with a single character), the correct # of chars remaining will be calculated correctly and the label will be updated. So if they have 50 chars remaining, and they highlight 5 letters and hit backspace, they now have "55 characters remaining"
I have 90% of this functionality working, but have a few bugs, and have no clue as to how to implement the last item above (bulk commands on highlighted text). Here's what I have:
boolean ignoreInput = false;
int charMax = 500;
JLabel charCntLabel = getLabel();
JTextArea myTextArea = getTextArea();
myTextArea.addKeyListener(new KeyListener() {
#Override
public void keyTyped(KeyEvent e) {
return;
}
#Override
public void keyReleased(KeyEvent e) {
// If we should be ignoring input then set make sure we
// enforce max character count and remove the newly typed key.
if(ignoreInput)
myTextArea.setText(myTextArea.getText().substring(0,
myTextArea.getText().length()));
}
#Override
public void keyPressed(KeyEvent e) {
String charsRemaining = " characters remaining";
int newLen = 0;
// The key has just been pressed so Swing hasn't updated
// the text area with the new KeyEvent.
int currLen = myTextArea.getText().length();
// Adjust newLen depending on whether the user just pressed
// the backspace key or not.
if(e.getKeyCode() == KeyEvent.VK_BACK_SPACE) {
newLen = currLen - 1;
ignoreInput = false;
}
else
newLen = currLen + 1;
if(newLen < 0)
newLen = 0;
if(newLen == 0)
charCntLabel.setText(charMax + " characters maximum!");
else if(newLen >= 0 && newLen < charMax)
charCntLabel.setText((charMax - newLen) + charsRemaining);
else if(newLen >= charMax) {
ignoreInput = true;
charCntLabel.setText("0 " + charsRemaining);
}
}
});
The above code works pretty well, but has a few bugs:
It doesn't prevent the user from typing in > 500 characters. When the user types in the 500th character, the label reads "0 characters remaining." But you can continue to type in characters after that, and the label stays the same.
If you have > 500 characters in the textarea, and you start backspacing, you'll see each character being removed from the textarea (the underlying model), but the label stays the same. But, once you backspace enough to get to the 500th character, and you backspace, the label will start changing properly, telling you that you have "1 characters remaining", "2 characters remaining", etc. So...
This code seems to work but just stops working > 500 characters. Once you get back inside that 500 char max, it begins working again.
The questions
Is there a simpler way to implement this desired functionality (and for a Swing JTextArea)? I feel like I'm reinventing the wheel here and that there might be a "cleaner" way of enforcing character maximums and updating their respective labels.
If not, can anybody spot my > 500 char bug? I've been looking at it all morning and am pulling my hair out.
Most importantly, how do I implement my requirement to handle bulk commands to highlighted text? How do I hand text selections inside the textarea, listen for changes to the highlighted text (e.g., deleting multiple highlighted characters with the backspace button, etc.), and correctly calculate the new value for chars remaining?
Thanks in advance.
You can limit the max size by using a DocumentFilter, check this documentation section, it has a working example of what you need.
Take this as an example, I used the component from the example file above:
import java.awt.BorderLayout;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.*;
import components.DocumentSizeFilter;
public class Test {
public static void main(String[] args) {
new TestFrame().setVisible(true);
}
private static class TestFrame extends JFrame{
private JTextField textField;
private DefaultStyledDocument doc;
private JLabel remaningLabel = new JLabel();
public TestFrame() {
setLayout(new BorderLayout());
textField = new JTextField();
doc = new DefaultStyledDocument();
doc.setDocumentFilter(new DocumentSizeFilter(500));
doc.addDocumentListener(new DocumentListener(){
#Override
public void changedUpdate(DocumentEvent e) { updateCount();}
#Override
public void insertUpdate(DocumentEvent e) { updateCount();}
#Override
public void removeUpdate(DocumentEvent e) { updateCount();}
});
textField.setDocument(doc);
updateCount();
add(textField, BorderLayout.CENTER);
add(remaningLabel, BorderLayout.SOUTH);
setLocationRelativeTo(null);
pack();
}
private void updateCount()
{
remaningLabel.setText((500 -doc.getLength()) + " characters remaining");
}
}
}
evt.consume(); will help alot in this case..you dont need to use DocumentFilter. here is a much easier way of limiting user at certain length
private void jTextArea1KeyTyped(java.awt.event.KeyEvent evt) {
String s=jTextArea1.getText();
int l=s.length();
jTextField1.setText(String.valueOf(l));
int i=10-l;
jTextField2.setText(String.valueOf(i));
try{
if(l>=10){evt.consume();
}
}
catch(Exception w){}
}
To add on to what Ray S. Kan said:
There is an easier way to limit the characters for a JTextArea without having to use a DocumentFilter as shown by Ray S. Kan, but the issue with his answer is that it does not prevent someone from pasting in a long text. The following will prevent a user from pasting in stuff to bypass the limit:
#Override
public void keyTyped(KeyEvent e) {
int max = 25;
if(text.getText().length() > max+1) {
e.consume();
String shortened = text.getText().substring(0, max);
text.setText(shortened);
}else if(text.getText().length() > max) {
e.consume();
}
}
This will stop a key from being pressed if the length is not pass max, but if it passes max, it will simply replace the string in the text area with a shorter string. The text variable is the JTextArea swing object.