Text 'Extent' property doesn't contain the correct size
Asked Answered
B

1

6

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.

Brunswick answered 5/2, 2015 at 12:42 Comment(9)
I have the correct behavior under R2014b, Ubuntu 14.04. As they have changed the graphical rendering in depth for R2014b, it seems that this kind of problem is now fixed.Nonintervention
I think that is simply because it is linux, it didn't help anything when I installed R2014b.Brunswick
I confirm I observe this problem in R2014b and in R201b, both on WindowsGorget
I also notice that if tempfunc(repmat('A',14)); is replaced by tempfunc(repmat('A',5));or some other number, the amount of extra or missing vertical space varies. The more tests I do, the more it looks like a bug?Gorget
I also find it to be font dependent, maybe there's a clue here, and it's the OS fonts that trick matlab...Napper
another interesting fact, in matlab's documentation it says that "To adjust the width and height of the uicontrol to accommodate the size of the String value, set the Position width and height values to be slightly larger than the Extent width and height values." .... So they know the function is not perfect... (see under Extent mathworks.com/help/matlab/ref/uicontrol-properties.html)Napper
Nice observations bla! Though Mathworks seems to be wrong on this "slightly larger"-part, since sometimes it should be slightly larger sometimes it fits perfectly and sometimes it should be slightly smaller - also it seems that it is only the height of the text that should be slightly larger/smaller.Brunswick
inconsistencies might be less to do with OS and more to do with screen resolution (720 dpi or else), graphics adapter.Kaph
consider using other monospace fonts (for example Consolas, en.wikipedia.org/wiki/Consolas )Napper
P
1

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

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.

Poetize answered 25/5, 2015 at 16:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.