Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Text 'Extent' property doesn't contain the correct size

I want to place some text in a GUI, and I want to know the exact size the uicontrol of type 'text' needs to be!

I've found several threads explaining that this can be done using the 'Extent' property of a 'text' object containing the same text, see example:

function form = tempfunc(txt,font,fontsize)
    if nargin <3
        fontsize = 10;
    end
    if nargin < 2
        font = 'courier';
    end
    f = figure('Visible','off','Units','pixels');
    u = uicontrol(f,'Style','text','Units','pixels','String',txt,'FontName',font,'FontSize',fontsize);
    textsize = get(u,'Extent');
    textsize = textsize(3:4);
    close(f);

    form = figure('Units','pixels');
    uicontrol(form,'Style','text','Units','pixels','String',txt,'FontName',font,'FontSize',fontsize,'Position',[5,5,textsize]);
end

My problem is now that this doesn't work. When I run the above with tempfunc(repmat('A',14)); I get the following figure window:

enter image description here

As you can see from the image the height of the text extracted in the textsize variable is too small!

Note that this is the result I got when I ran the program on my Windows computer running Matlab R2014a. I later ran the exact same code on a Linux machine running Matlab R2013b, and on that machine I got the result I wanted.

The GUI I am making should (hopefully) be able to run on any computer, but right now I am really at a loss on how I should proceed to make a version that works on any machine, so please help me!

EDIT: I tried to run the same code on another Windows 7 machine (this time Ultimate edition instead of my Enterprise edition) running Matlab R2011b (instead of my R2014a), it still produced the wrong height of the text box - but this time the text box was too high - see image:

enter image description here

EDIT2: I finally got R2014b installed, but sadly it did not help! I got a similar looking picture:

enter image description here

I also tried to see if different choices of resolution of my screen made any difference - they did not.

EDIT3:

I've noticed that different fonts yield different errors in the height, e.g. the default font (MS Sans Serif) yields a text box that is too high (and this error in height also grows as more lines get added) - On Linux however I got the correct result for all the fonts I tried.

But really the case I am most interested in is the case using the courier font, since I need a monospaced font for my purpose.

like image 666
Jens Boldsen Avatar asked Feb 05 '15 12:02

Jens Boldsen


1 Answers

Observing the Java side of things, Swing components have several methods of interest:

  • getVisibleRect
  • getSize (which, from my tests, gives comparable results to getVisibleRect)
  • getPreferredSize

The thing is, that the "preferred size" seems to be the correct size (which you seek), whereas the size returned by get(...,'Extent'); is the visible size, which has the following meaning:

getVisibleRect()

Returns the Component's "visible rectangle" - the intersection of this component's visible rectangle, new Rectangle(0, 0, getWidth(), getHeight()), and all of its ancestors' visible rectangles.

To clarify the above: theme- and platform-specific decorations of the figure window may decrease the available space of the component, and therefore its visible size (as mentioned here).

As a numeric example, when running with default settings and repmat('A',14), I get (on Win7, MATLAB 2015a):

  • get(u,'Extent') - [0,0,116,214]
  • jHandle.getVisibleRect - java.awt.Rectangle[x=0,y=0,width=116,height=214]
  • jHandle.getSize - java.awt.Dimension[width=116,height=214]
  • jHandle.getPreferredSize - java.awt.Dimension[width=116,height=221]

Now the question is how to get PreferredSize (or jHandle from which it may be retreived) conveniently...

One option, which I used, is the findjobj utility, whose usage is as simple as jHandle = findjobj(u).

To summarize:

  1. Place findjobj in your working folder.
  2. Replace the two lines where you find textsize by this:

    v = findjobj(u); textsize = [v.getPreferredSize.getWidth v.getPreferredSize.getHeight];

  3. PROFIT.

P.S.

My reasoning may be flawed and understanding of Swing incorrect, however this explanation makes sense to me and more importantly - it works.

like image 63
Dev-iL Avatar answered Nov 15 '22 05:11

Dev-iL