Is it possible to dynamically update a JTextArea? - java

I have a JTextArea and a button which removes the selected text (from textArea).
RemoveButton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
String test = textArea.getSelectedText();
textArea.replaceSelection("");
}
});
The code above works fine, however, when I click the button the text shows like this:
Here I removed the first and third Test. How can I make this dynamically update so it displays the text without gaps?
I could call a method re-populate the JTextArea with the remaining elements but is there a better way to do this?

You can try something like
textArea.setText(textArea.getText().replaceAll("\n\n",""));
However, a TextArea may not be the best component for that kind of use. A Jlist could be more fitted if you want to store input on different lines.

Related

How to add on text into current textfield at current cursor position (Java)

I am trying to finish up a GUI calculator in Java, and have run across a problem in which I cannot figure out how to add text onto the end of current text within a textfield that the cursor is currently positioned at.
Here is a picture of the calculator.
I have completed the operation buttons on the left and right side columns, and now am trying to complete the action listeners for the numbers buttons. I want to get it so that when my cursor was in the left textfield and I click on a number button, it adds that number into the textfield, and the same for the right textfield. I've tried using focus functions but couldn't figure out a way to add the button input into more whichever textfield my cursor was last in.
https://github.com/johnwaugh1/projects/blob/main/calculator
I hope I have successfully linked my code above, and the action listener which I was currently working on was for the button a0, towards the end of my code.
I tried many approaches, mostly using if else statements combined with focus functions, but none was able to insert text into more than one textfield.
Add a FocusListener to tf1 and tf2, and add text to tfLast.
Off the top of my head, something like this should work.
private JTextField tfLast;
FocusAdapter fa = new FocusAdapter() {
public void focusGained(FocusEvent e) {
tfLast = (JTextField)e.getSource();
}
}
tf1.addFocusListener(fa);
tf2.addFocusListener(fa);
tf1.requestFocusInWindow();
. . . .
tfLast.setText( . . . . );

Stopping a JTextPane from receiving new line feeds

I want my JTextPane to have some functionality when the user presses Enter and not just change the line. Now I understand how to implement the functionality I want, but I still can't negate the line feed from pressing Enter. I have tried the following but it doesn't seem to work, the new line will be created anyway.
To give a better idea of what I'm trying to achieve here, the textpane is supposed to contain a certain filepath, so I want the user to be able to scroll only horizontaly and not add new lines verticaly. Is the JTextPane component suitable for this use?
locationPane = new JTextPane();
locationPane.addKeyListener(new KeyAdapter() {
#Override
public void keyPressed(KeyEvent arg0) {
if(arg0.getExtendedKeyCode() == KeyEvent.VK_ENTER){
locationPane.setText(locationPane.getText().substring(0, locationPane.getText().length()));
}
}
});
KeyListener is never a suitable soution for text components. Instead you should be using a DocumentFilter to filter out things you don't want to be added to the underlying Document.
See Implementing a Document Filter and DocumentFilter Examples for more details
You could also alter the insert-break key binding, changing the behaviour or taking additional action.
See this example for more details
the textpane is supposed to contain a certain filepath, so I want the user to be able to scroll only horizontaly and not add new lines verticaly. Is the JTextPane component suitable for this use?
I would suggest there are better options.
If you only have a single line of text then just use a JTextField. To handle the Enter key you can add an ActionListener to the text field.
If you do need multiple line then I would suggest you could use a JList.

Search for buttons in jpanel and get the button's text?

Hi I have a problem about getting the text from the buttons in a JPanel. My program will have a JPanel and there are 4 buttons inside it. Each button will have a random integer shown as a text. I want my program to be able to get the key that is pressed from the keyboard, and check if that key is matched with any of the buttons' text (Something like the calculator).
If the key is matched with any buttons in the JPanel, it will print out that key and make that button disabled.
My code is something like:
private void formKeyPressed(java.awt.event.KeyEvent evt) {
Component[] comp = numpanel.getComponents();
for (int i = 0;i<comp.length;i++) {
if (comp[i] instanceof JButton) {
//check if it matches with any button's text
}
}
}
and I get an error when I try to write comp[i].getText() in order to check the key and the button's text. In my understanding, it says that comp[i] is a Component, which doesn't have the method getText(), am I understand it correctly ?
How can i fix it or are they any alternative ways to do this?
it says that comp[i] is a Component, which doesn't have the method getText(), am I understand it correctly ?
Yes.
How can i fix it or are they any alternative ways to do this?
If you know that comp[i] is a JButton, such as within the if statement you have where you checked that it is with instanceof, then you can cast it as a JButton, and use the getText() method.
.... = ((JButton)comp[i]).getText();

How to make only the next line of JTextArea (+JScrollPane) editable

So im creating a server, and that works great, however I am a bit stuck on the GUI. You see, I would like it to look just like Command Prompt, where only the next line is editable, and it does not let you delete any other text. So right now I have:
JTextArea ta = new JTextArea();
JScrollPane sp = new JScrollPane(ta);
Then the frame stuff...
f.setTitle("Server");
f.setBounds(ss.width - 600, 50, 550, 350);
f.setResizable(false);
f.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);//added window listener so closes socket connection first
f.setAlwaysOnTop(true);
Then adding it:
f.add(sc);
jt.setBackground(Color.BLACK);
jt.setForeground(Color.WHITE);
//jt.setEditable(false);
Finally, the method I use to output to the TextArea:
public static void append(String text) {
jt.append(text);
jt.append("\n\n"+System.getProperty("user.name")+" / "+getIp()+" > ");
jt.setCaretPosition(jt.getDocument().getLength());
}
Now I need to assign a String to what the user types into the JTextArea after they press enter:>?
jt.addActionListener(...{
public void ActioEvent(ActionEvent e){
String text = JTextArea.getLines().getLastLine().getText().replace(System.getProperty("user.name")+" / "+getIp()+" > ", "");
}
});
Maybe something like that?
Then I need to have it so that only the part after the ">" is editable?
The way to do this is with a DocumentFilter. This is a fairly obscure and little-used part of Java, and is far from easy to use. However it allows you to insert a DocumentFilter between the UI (where rich text content is edited) and the underlying model (the content). You pass all the 'insert' and 'remove' operations through the filter, which can either accept, refuse or modify them. You can code the filter to only permit modifications to the command line, and not to the prompt.
As I say, this is a pretty hard piece of coding, and the Document/DocumentFilter structure has a lot of complexity that your particular application doesn't need. However it does provide you with the facilities you need.
There is a tutorial in the standard Java doc pages, but not an advanced one, and very few examples that I know of are out there on the web.
ProtectedTextComponent (thanks camickr) provides an example of how to do something similar.
Use a Collection a JTextField.
Let the user type on a JTextField, and once he presses enter, move the control to the next JTextField while making the above JTextField uneditable and also remove the JScrollPane from it.
Hope this helps.
I also agree that the JTextArea/JTextField approach is the common and simpler approach.
However if you want to complicate your life a little then you can check out Protected Text Component which will do most of the logic for you.
The current implemtation of the ProtectedDocument only allows you to add protection to the Document, not remove it so the first thing you will need to do is add a method to "Clear" all the protect pieces of text. This is easy enough, you just clear the entries in the Map used by the class.
Next you will need to replace the default "Enter" Action used by the JTextPane. You do this by playing with the Key Bindings of the text area. See Key Bindings for some basic information. In your custom Action you would first need to invoke the newly created "clear(...)" method. Then you would add you text to the text area. Finally you would protect all the text but the last "x" number of characters.

Switching the text on a JButton

This one may be easy for you. But I'm stuck and can't figure out an algorithm for doing that. I want to show a JTextField and change the text on the JButton to "Hide" if it's "Search". If
the text on the JButton is "Search" a JTextBox should appear and vice versa, if the text is "Hide" make the JTextField invisivle and change the text on JButton to "Search"
This is how I have done it:
private void switchBtnText(){
searchTxtField.setVisible(true);
btnSearch.setText("Hide");
if(btnSearch.getText().equals("Hide")){
btnSearch.setText("Search");
searchTxtField.setVisible(false);
}
}
If I comment the if section it works to show the JTextField. My problem is to go back to the default settings which is a JButton with "Search" as a text and with an invisible JTextField.
The method is then called in an ActionEvent. I've done this before, in C#, so I know I'm close.
Thank you in advance. The fastest and best answer will get upvoted and accepted.
This should work although I've not tested it.
//btn action
private void toggleVisible(){
String btnVal = btnSearch.getText();
if(btnVal.equals("Search")){
searchTxtField.setVisible(true); // or however you are showing search field
btnSearch.setText("Hide");
}else{
searchTxtField.setVisible(false);
btnSearch.setText("Search");
}
}
Take a look at your execution sequence....
setText to "Hide"
if text equals "Hide", change text to "Show"
Try changing the logic so you check the text first, then make decisions about what should be done...
If text equals "Hide", change text to "Show"
Else, change text to "Hide"

Categories

Resources