I've got a StyledDocument instance that contains, among other things, strings that represent numbers. By overriding the attributes of the string's element, I'm using a custom View for them that I derived from LabelView. I want to allow the user to select the base of the displayed number, e.g. decimal or hexadecimal. This is my current solution:
public class AddressView extends LabelView {
@Override
public Segment getText(int p0, int p1) {
// get string representation of the number from the model
String stringNumber = super.getText(p0, p1).toString();
// get base from document's attributes
int base = getDocument().getProperty(BaseProperty);
// convert string to desired base
String stringNumberOverride = Integer.toString(Integer.parseInt(stringNumber), base);
// return as segment (can have a different length, JTextPane doesn't like that)
char[] strNum = stringNumberOverride.toCharArray();
return new Segment(strNum, 0, strNum.length);
}
}
There's only one problem: Selecting text doesn't work anymore because the returned string of getText doesn't have the requested length (p1 - p0). The JTextPane component is implemented to select exactly that many chars, so with the above solution the user can only select p1 - p0 characters, even though the new base could have displayed a longer string representation of the number string in the model.
So, what's the correct way to have a View that displays a String that has a different length than the one in the model? I don't want to update the Model just because the user desires a different representation of the content.
Edit: Here's a self-contained example. Try selecting the text - you can only select all chars or no chars because there's only one character in the model.
package mini;
import javax.swing.*;
import javax.swing.text.*;
public class Mini extends JFrame {
public Mini() {
setDefaultCloseOperation(EXIT_ON_CLOSE);
JTextPane pane = new JTextPane();
pane.setEditorKit(new MyEditorKit());
add(new JScrollPane(pane));
pack();
}
public static void main(String[] args) {
Mini mini = new Mini();
mini.setVisible(true);
}
}
class MyEditorKit extends StyledEditorKit {
@Override
public ViewFactory getViewFactory() {
return new ViewFactory() {
public View create(Element elem) {
return new MyView(elem);
}
};
}
}
class MyView extends LabelView {
public MyView(Element elem) {
super(elem);
}
@Override
public Segment getText(int p0, int p1) {
String line = "Displayed text that's longer than model text";
return new Segment(line.toCharArray(), 0, line.length());
}
}
I want to allow the user to select the base of the displayed number, e.g. decimal or hexadecimal
what does it mean ? – AsomatousDocuemnt
. If i am understanding you correctly if i type:This is what your ID 123 and reach to the station.
You want it as:this is what your ID 0x7B and reach to the station
. I don't think using EditorKit to change data on view is going to make this faster. Because, returned label view's getText will always gets called while inserting the data and it needs to be called the complete text of the document to render the view. – Asomatous