0

The following code snippet paints a suggested auto complete string in a JTextArea:

@Override
public void paintComponent(Graphics g) {
    super.paintComponent(g);
    if (suggestion != null && isSuggesting()) {
        final String selectedSuggestion = 
                suggestion.list.getSelectedValue().getValue().substring(
                        suggestion.subWord.length());
        g.setColor(Color.GRAY);
        final int position = getCaretPosition();
        Point location;
        try {
            location = modelToView(position).getLocation();
        } catch (BadLocationException e2) {
            e2.printStackTrace();
            return;
        }
        //TODO: 13 ???
        g.drawString(
                selectedSuggestion, 
                location.x, 
                13 + location.y);
    }
}

I use the magic number 13, which is great in my L&F:

enter image description here

But how do I calculate the right y position of the current line for general font size / L&F?

Elist
  • 5,313
  • 3
  • 35
  • 73

2 Answers2

2

You can use the current font size for calculating the correct position.

Simply add the current font size to location.y like this:

g.drawString(selectedSuggestion, location.x, g.getFont().getSize() + location.y);

Edit: Using FontMetrics

    FontMetrics fm = getFontMetrics(g.getFont());
    int heightToAdd=(int)fm.getStringBounds("Sample Text", g).getHeight();
    g.drawString("Sample text", location.x, location.y+heightToAdd);

This was just a try with some random text.

Please refer the java docs here: Using FontMetrics

Kunjan Thadani
  • 1,660
  • 3
  • 18
  • 26
  • This doesn't work. It draws the string a pixel or two above the line. I guess it is because each line has some kind of bounds, but I can't figure out how to tell it's size. – Elist Dec 14 '14 at 14:08
  • Well, using 13 is working for you because default font size 12. So, it adjusts well. By the way, do you want the output the way it has been shown in the image or the suggestion should be in the same line as the typed text? Because adding the font size or some number would make it appear below the typed text. – Kunjan Thadani Dec 14 '14 at 14:15
  • I want it to be as the grey text as shown in the image - in the same line with the typed text. You are saying the the fontsize + 1 should always be fine? Where is this 1 pixel comes from? how do I know the insets of the text line? – Elist Dec 14 '14 at 14:25
  • Ok. fontsize + 1 is not sure to work. Yes, point to be noted that 1 pixel is being added. I am too not getting this. One more thing you can try is using the FontMetrics for getting the bounds. I have done some edits in the answer. – Kunjan Thadani Dec 14 '14 at 14:54
  • I have used this: `int heightToAdd = (int)(fm.getStringBounds("Sample Text", g).getHeight() - g.getFont().getSize()) / 2;` and added the font size to it. But I still have a feeling that is not the right way... – Elist Dec 14 '14 at 15:20
  • May be some more workout with the text bounds could help with some alternate. – Kunjan Thadani Dec 14 '14 at 15:50
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/66900/discussion-between-elist-and-kunjan-thadani). – Elist Dec 15 '14 at 08:47
2

Maybe I'm missing something, but you already have the information you need:

Rectangle r = textArea.modelToView( textArea.getCaretPosition() );
int yOffset = r.y + r.height;
camickr
  • 321,443
  • 19
  • 166
  • 288
  • @Elist, then I guess I am missing something. This would be equivalent to the spacing used by the text area. How is that too low? What is your exact requirement for the "Y position"? Are you trying to paint it one pixel below the "y" in "By"? If so then you need to play more with the font metrics by using the ascent, descent, etc.. values to determine the exact location to use. I agree that randomly dividing by 2 it not the right way. – camickr Dec 14 '14 at 22:25