Custom JEditorPane behaviour - java

Hi fellow programmers!
I have a JEditorPane, where user is supposed to input series of numbers (quantities with optional uncertainities) separated by semicolons, for example:
3.0; 5.8; 70+-5; ...
The list is then mapped to ArrayList wrapper containing parsed quantities.
I'd like to implement a specific behaviour for input pane. For example pressing ';' or ' ' should insert '; ', pressing backspace/delete between ';' and ' ' should erase both of them and combine separated numbers. Cuts and pastes also have specific behaviour, and so on. I want it to be user-friendly and intuitive.
I tried DocumentFilter, but it seems to be too simple and it can mess up caret/selection. So I thought about writing my very own StyledEditorKit subclass, but there's a load of Actions to implement and a lot of technical details, which I am not certaing about.
How can I deal with it? Is there any way of doing it without writing EditorKit from scratch?

First of all I wouldn't use a JEditorPane for this. A JEditorPane is for displaying HTML. It will be much easier using a JTextArea or JTextPane since this only contains text and no tags to worry about.
I tried DocumentFilter, but it seems to be too simple and it can mess up caret/selection.
A DocumentFilter is designed to used by multiple Documents and therefore knows nothing about the actual text component you are using. If you want to control caret location then you would need to pass the text component as a parameter to your DocumentFilter class.
pressing ';' or ' ' should insert '; ',
If you don't like a DocumentFilter, then maybe you can use Key Bindings and handle the keyTyped event
pressing backspace/delete between ';' and ' ' should erase both
A DocumentFilter should work or again you can use Key Bindings. Note for the backspace key I believe you need to handle Ctrl+H.
Cuts and pastes also have specific behaviour
A DocumentFilter won't the reason for the update to the Document (ie user typing or user pasting. You could try overriding the cut/copy/paste methods of the text component.
So I thought about writing my very own StyledEditorKit subclass, but there's a load of Actions to implement
Agreed, I think this is overkill.

Related

Sending Unicode Text to Cursor Position in Java

Doing linguistics and phonetics, I often need to use certain special phonetic symbols. Although I'm using a special keyboard layout that enables me to write some of those characters by typing, they key combinations can often get both quite complex and highly repetitive, so I would like to create a litle app that would contain some buttons, perhaps, each of them capable of sending a specified (phonetic) symbol to whatever the current cursor position is, no matter what window on one's screen is in focus.
Is anything of this sort possible to do in Java?
I've seen a solution that copies the values into clipboard and then pastes them (Java paste to current cursor position), but that is not a very clean way to do it, is it? Is there a way better than just pasting the charactedr(s) via ctrl+V?
Many thanks for any help or advice in advance!
P.
You can use the AWT Robot to generate key press events. This will not provided the ability to insert arbitrary unicode characters but you can combine it with the technique you already described: transfer the unicode characters to the clipboard and generate a CTRL+V key event afterwards. You can try to save and restore the original clipboard content but this will work with types supported by Java only.
The focus problem mentioned in the comments can be solved by setting the window to not receive the focus via Window.setFocusableWindowState with an argument of false.
An alternative is to provide the unicode text via drag&drop. Most applications support dropping text in their input fields. The code for exporting the text is very similar as both, clipboard and d&d use the same interfaces in Java.

Java GUI dynamic text with editable delimiters

First of all, I don't know how to exactly formulate my question, so I don't know what to search for, really. If you know what I mean and it has a name, or even an answer somewhere, feel free to tell me.
I want to segment texts (into sentences or sentence-like structures) and show the segments to the user, with delimiters (extends JComponent) after each segment. Since the segmentation won't always fit, the user should then have the possibility to delete delimiters and insert new ones, but the text itself should not really be editable.
The question is, how (by what class or structure) should I display the text and delimiters so that the structure, but not the text itself is editable?
Any suggestions?
What I'm trying to do:

Selecting nested subexpressions in a Swing GUI

As a part of a GUI design that I'm implementing in Java swing, I need the user to be able to select parts or subparts of a tree like structure represented as a string.
For example, if I were to display the following expression, ((a|b)|(c|d))
The user would need to be able to select any of the following
(a|b), (c|d) or the entire thing ((a|b)|(c|d)).
Ideally I'd like them to be able to navigate via the keyboard arrows, moving up and down though the nested subexpressions, and hit enter when they come to the subexpression they want. However if its only possible to do this on mouse click, thats also acceptable.
The main issue that I'm having with this is the nesting component. I could easily make the entire expression selectable, but I don't know how to allow subexpressions to be selectable using SWING components. Based on my research Swing doesn't allow nesting of labels of text areas in the manner that I need so I'm looking for any alternatives.
Any help or suggestions would be much appreciated.
You could use a Highlighter and a DocumentListener on the read-only JTextField suggested by Joop in the comment above, following http://docs.oracle.com/javase/tutorial/uiswing/components/textfield.html in the section about JTextFieldDemo. That way you can highlight your (partial) string and listen to what (sub)string is selected, and compare it to the original string to check for matches.

JKeyListener chars / auto complete

I want to make an auto completion textfield, which replaces the input with the first hit and selects the part which wasn't entered by the keyboard yet. To do so, I'll have to count the chars typed (or deleted). How can I filter if the KeyEvent is a printable Char (and not SHIFT f.e.)?
Look at https://swingx.dev.java.net/
This lib is already have great autocomplete text fields
i prefer to do it with the KeyListener
Well, a KeyListener is the wrong tool for the job.
If you really want to write your own code then you should start with a DocumentListener. Every time text is added or removed from the text field you will be notified. Then you can implement your auto completion code.

Making words different colors in JTextField/JTextPane/?

I'm trying and failing to understand how to use Java's text editor components to colorize text as you insert it. I don't want or need a fully featured syntax highlighting library.
Basically, I have a JTextField (or some other JText... component), and a list of words. I want any words in the field that appear in the list to be red, and the rest of the words be green. So for example, if "fire" is in the list, "fir" would appear green and "fire" would appear red.
I've tried using a JTextPane and a DefaultStyledDocument, using a KeyListener to go over the text in the document and using AbstractStyledDocument.replace to replace the existing words with versions that have the correct attributes. This didn't do anything. What am I doing wrong?
Neither JTextPane nor JTextField isn't able to present formatted text, i.e text having more than one format. For text-editor-like capabilities like you'd find in WordPad or HTML, the component to use is the JEditorPane or its descendant, JTextPane.
The simplest thing you can do is set the ContentType of the JEditorPane to "text/html" and simply set its text to a string containing HTML. The Java structured text components are surprisingly competent with HTML; you can display tables and/or DIVs, and there is support for much of CSS2. Simplest to do your styles inline, but you can even do external style hrefs.
If you want to get fancy programmatically, you can access the DocumentModel and create text from spans of text each having their own formatting. The DocumentModel works essentially like a programmable text editor.
EDIT: Re-reading your question, I see my answer doesn't quite address it. Since you want multi-colored text JEditorPane is your only option; but rather than just piping in pre-colored text via HTML or such, you'll have to put a listener on your document model to catch changes introduced when you type; and after every document change you'll want to examine the text (again from the Document model) for text that should or should not be highlighted, and you'll want to apply formatting to certain runs of text.
There are devils in the details, but this should get you started.

Categories