I want to create a Swing JTextPane that takes action when the user types text into it. But I also want to be able to alter the text in that pane without it treating that alteration as a user typing. How can I do this?
If you don't let update events fire, then chances are that your UI won't get updated either, depending on the actual implementation. So I agree that you might be better off by talking to the event handler, letting it know that the next alteration is going to be a programmatic change. Something like this:
try {
listener.setProgrammaticChange(true);
// change document
}
finally {
listener.setProgrammaticChange(false);
}
Related
I'm trying to make an autocomplete textbox for a program I'm writing. I have the logic down, but I'm having some trouble implementing it properly. First I tried it with a key listener, but that solution was a bit strange in the way that it handled multiple key presses at the same time. Then I tried DocumentListener which was far better, but doesn't allow me to edit the document from within the Listener because of a threading issue. I read something about DocumentFilter, but I can't find a single guide on how to use it. Is there a way of editing the doc from with documentListener? Or would you recommend DocumentFilter and if so, how do you use it??
DocumentListener should not be used to edit the document. Doing so would require a call to SwingUtilities.invokeLater(...) and since DocumentListener detects changes to the document, any edits would result in an infinite loop. Best bet is to use DocumentFilter.
I want to do something based on the model change, e.g. if user enters text in the Text SWT widget, I would like to do something based on that. But the problem is, if I use e.g. key listener on the widget, it will get called before the data binding process occurs and therefore the behaviour would'nt be consistent. One way around this is to do the logic inside the binding process, but this is not really a convinient way of handling this problem. Suggestions?
So basically, what I need is an event listener, which is triggered after the data binding occures (on some specified widget of course).
Use an IChangeListener to listen for changes on the model observable value. This will be called after the model has been updated from the target.
Something like:
IObservableValue targetOV = WidgetProperties.text(SWT.Modify).observe(text control);
IObservableValue modelOV = PojoProperties.value("your field").observe(object);
bindContext.bindValue(targetOV, modelOV);
modelOV.addChangeListener(change listener);
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.
This is for an assignment so responses should not contain the code written for me.
I have written a program that is essentially an auto-complete program. It takes a word and returns the best matches.
I am trying to write a front end for it in swing(which I have no experience in) and want my front end to do the following: I want the input box to constantly be reading for user input, feeding that value to the other program, and returning the matches immediately in a drop down box, as, say, Google does. I can't seem to find any information on how to do this, all the intro tutorials use a submit button.
Can anyone explain to me how this would be done, or point me to a resource that could explain it? Again, please don't write the code for me, I don't want to unwittingly cheat on my assignment.
If you are using a JTextField, you could register a document listener on it.
If your input box is a JTextField, you can add a DocumentListener (this is a good tutorial) to capture character entries.
I think that no one from answerers ..., I'm only about Don't reinvent the wheel
1) use JTable with one (or two if is about Dictionary) Column and with basic implmentation for Sorting and Filtering (example with filtering from JTextField is in the Tutorial), JTable could be most complex from JComponents and there is everything (quite easilly) possible
2) use AutoComplete JComboBox / JTextField
3) use SwingX Decorator with JXList or JXTable
4) if you needed redirect output to the separate window then use JDialog / JWindow for popup window
One approach could be:
Attach a handler to detect a key press on the text box.
Grab the text from the box, and construct a "lookup" event which is runnable and submit this to some form of service which will dispatch it at some point in the future (hint: ExecutorService, Future)
Save this handle, and if the key press event happens again, cancel the previous and submit a new one.
When the event executes in the future and returns the result, popup a panel which displays the list of items.
I've got a JTextField, and I'd like the system to do some processing on what the user typed whenever the user leaves the text field. The ActionListener that you can add to just the JTextField only fires when the user presses enter, however.
I'd like the processing routine to run whenever the user leaves the text box by any means - tabs, clicks out of it, presses enter, etc. (The processing in question is to save the text the user typed to the appropriate data object, nothing fancy.)
My google-fu has failed on this one: I'm confident that it's possible, I just can't see how.
Add a FocusListener.
It's worth noting that this is a relatively low-level listener. On JComboBox it wont work unless you find the text field (and perhaps button) that the particular PL&F inserts. Swing is a bit odd that way (amongst many other ways).
Although for my money, non-cosmetic changes that happen when focus leaves a field give poor user experience. Much better to do any relevant changes on every change with a listener on the text field's document.
If you want to edit the text as it is typed then you should use an DocumentFilter.
If you want to validate the text as a complete entity then you can use an InputVerifier.