Problem with viewToModel()

Discussion in 'Java' started by Sascha Konrad, Jun 27, 2005.

  1. Hello,

    I have a JTextPane where I want to determine the position of the mouse.
    So if there is a mouse moved event, I will do

    int hoverPosition = jCurrentSentencePane.viewToModel(e.getPoint());

    to determine the position (as the position of the letter) in the text
    pane over which the mouse hovers. Now I have the problem that this
    method returns bogus values if the mouse is somewhere in the text pane,
    but not on the text. E.g., when I slowly approch the text somewhere
    from the top, it tells me 0 as the hoverPosition, from the bottom it
    tells me 35 (the length of my text). I was expecting to receive -1 or
    so when I am not over the text, not the beginning or end of my text.
    Does anybody have any suggestions?

    Thanks.
    Sascha Konrad, Jun 27, 2005
    #1
    1. Advertising

  2. Sascha Konrad <> wrote:

    > I have a JTextPane where I want to determine the position of the mouse.
    > So if there is a mouse moved event, I will do
    >
    > int hoverPosition = jCurrentSentencePane.viewToModel(e.getPoint());
    >
    > to determine the position (as the position of the letter) in the text
    > pane over which the mouse hovers. Now I have the problem that this
    > method returns bogus values if the mouse is somewhere in the text pane,
    > but not on the text. E.g., when I slowly approch the text somewhere


    It is (where?) expected to make a closest guess. This may not always
    be implemented in an optimal way.

    > from the top, it tells me 0 as the hoverPosition, from the bottom it
    > tells me 35 (the length of my text). I was expecting to receive -1 or
    > so when I am not over the text, not the beginning or end of my text.
    > Does anybody have any suggestions?


    Use modelToView() on the result and check whether the point is near there.
    Actually, use getUI().viewToModel() to also get aware of the bias.



    Christian
    Christian Kaufhold, Jun 27, 2005
    #2
    1. Advertising

  3. Sascha  Konrad

    Sascha Guest

    Hi Christian,

    Thanks for your replay.

    I found out that when I call jCurrentSentencePane.setMargin(0,0,0,0),
    everything works as expected. Now, I was wondering if I can find out
    the rectangle of the displated text in the JCurrentTextPane. If that is
    possible, then I can just ignore the mouse being on the margin. But I
    have not found out how to do that. I can call the JTextArea to get the
    size of the margin, but I don't know how to obtain the heigth and width
    of the text. (I.e., the right and lower boundary of the displayed
    text). Any ideas?

    Thanks
    Sascha, Jun 28, 2005
    #3
  4. Sascha <> wrote:

    > Thanks for your replay.


    Please quote some context.


    > I found out that when I call jCurrentSentencePane.setMargin(0,0,0,0),
    > everything works as expected. Now, I was wondering if I can find out
    > the rectangle of the displated text in the JCurrentTextPane. If that is
    > possible, then I can just ignore the mouse being on the margin. But I
    > have not found out how to do that. I can call the JTextArea to get the
    > size of the margin, but I don't know how to obtain the heigth and width
    > of the text. (I.e., the right and lower boundary of the displayed
    > text). Any ideas?



    Untested!:


    JTextComponent t = ...;

    Insets n = t.getInsets();

    Rectangle r = new Rectangle(n.left, n.top, t.getWidth() - n.left - n.right, t.getHeight() - n.top - n.bottom);

    View v = t.getUI().getRootView(t);

    Shape textShape = v.modelToView(v.getStartOffset(), Position.Bias.Forward, v.getEndOffset(), Position.Bias.Backward, r);



    Christian
    Christian Kaufhold, Jun 28, 2005
    #4
  5. Sascha  Konrad

    Sascha Guest

    Christian, thanks for your efforts, but your solution still does not
    work, you still get the width and heigth of the whole text pane.

    But you pointed me in the right direction and I think I got it now. You
    need to look at each row of each paragrah individually (i only have one
    paragrah), determining the width and heigth of this row. Then you
    create a new rectangle based on the width of the current row and the
    heigth of this row and all previous rows.

    Here is the code, in case anybody is interested. It works fine for me
    and sets the boolean variable hit to true if the mouse is positioned
    over text:

    boolean hit=false;

    Insets n = jCurrentSentencePane.getInsets();
    Rectangle r=new Rectangle(n.left,n.top,0,0);

    View sectionView =
    jCurrentSentencePane.getUI().getRootView(jCurrentSentencePane).getView(0);

    int paragraphCount = sectionView.getViewCount();

    for (int paragraphIndex = 0; paragraphIndex < paragraphCount;
    paragraphIndex++) {
    View paragraphView = sectionView.getView(paragraphIndex);
    if (paragraphView instanceof ParagraphView) {
    ParagraphView newparagraphView = (ParagraphView) paragraphView;
    int rowCount=newparagraphView.getViewCount();
    //oldHeigth contains the height of the previous row and is used to
    update the y position
    int oldHeight=0;
    for (int rowIndex = 0; rowIndex < rowCount; rowIndex++) {
    View rowView= newparagraphView.getView(rowIndex);

    r.width=(int) rowView.getPreferredSpan(View.X_AXIS);
    r.y=r.y+oldHeight;
    r.height=(int) (rowView.getPreferredSpan(View.Y_AXIS));

    if(r.contains(e.getX(),e.getY()))
    {
    //The point was in the rectangle, i.e. mouse is over text
    hit=true;
    break;
    }

    oldHeight=(int) rowView.getPreferredSpan(View.Y_AXIS);
    }
    }
    }

    It's mighty complicated though, I would be happy to see a simpler
    solution.

    -- Sascha
    Sascha, Jun 28, 2005
    #5
  6. Sascha <> wrote:

    > Christian, thanks for your efforts, but your solution still does not
    > work, you still get the width and heigth of the whole text pane.


    Again, please quote some context.


    AFAICS, the reason my code does not work is a broken (?) optimization in
    CompositeView.

    Use getEndOffset() - 1 instead of getEndOffset(), then it is not used,
    and it does not matter.



    Christian
    Christian Kaufhold, Jun 28, 2005
    #6
  7. Sascha  Konrad

    Sascha Guest

    Wow, thanks Christian, it works now, you're the Swing master. I guess I
    haven't really understoof this whole concept of views and models.
    Thanks again for your help.

    -- Sascha
    Sascha, Jun 29, 2005
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Andreas Suurkuusk
    Replies:
    0
    Views:
    3,968
    Andreas Suurkuusk
    Jul 27, 2003
  2. Ted Miller
    Replies:
    0
    Views:
    5,145
    Ted Miller
    Sep 13, 2003
  3. Merek
    Replies:
    0
    Views:
    1,957
    Merek
    Dec 3, 2003
  4. Scott Meddows
    Replies:
    1
    Views:
    386
    John Saunders
    Jun 8, 2004
  5. Mike

    Problem problem problem :( Need Help

    Mike, May 7, 2004, in forum: ASP General
    Replies:
    2
    Views:
    543
    Bullschmidt
    May 11, 2004
Loading...

Share This Page