Swing text API: override LabelView with a different string length?

I have an instance of StyledDocument that contains, among other things, strings that represent numbers. Overriding the attributes of a string element, I use the custom view for them that I got from LabelView. I want to allow the user to select the base of the displayed number, for example. 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 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 is only one problem: text selection no longer works because the returned getText string does not have the required length (p1 - p0). The JTextPane component is implemented in order to select exactly this set of characters, therefore, using the above solution, the user can select only the characters p1 - p0, even if the new base could display a longer string representation of the number string in the model.

So, what is the correct way to have a view that displays a string that has a different length than the one in the model? I do not want to update the model just because the user wants a different view of the content.

Edit: Here is an example. Try to select text - you can select only all characters or characters, because the model has only one character.

 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 longer than model text"; return new Segment(line.toCharArray(), 0, line.length()); } } 
+6
source share
1 answer

There are several possible solutions.

  • Could you define larger strings for adding numbers, for example. Do spaces always have equal text length? For instance. you have numbers from 1 to 100, so add spaces before or after to always have 3 characters.

  • If you just need to change the rendering, leaving all reas as they are. You can override

    public void paint (Graphics g, Form a)

and use g.drawString() to render the desired text. You can set the font from the document method public Font getFont(AttributeSet attr) . The question is how to handle resizing and carriage navigation in number, but can also be overcome.

0
source

Source: https://habr.com/ru/post/958666/


All Articles