Position of Not-visible figure is WRONG (two monitors bug?)

If I create a figure and maximize it, I got sizes fitting my second monitor:
fig = figure('Menu','none','ToolBar','none','WindowState','maximized','Visible','on');
>> fig.Position
ans =
1.0e+03 *
0.0010 0.0490 1.2800 0.6493
But if I create a not visibile figure, I got a wrong position:
fig = figure('Menu','none','ToolBar','none','WindowState','maximized','Visible','off');
>> fig.Position
ans =
360 198 560 420
Moreover, if I change the visible property to "ON", Matlab at first shows me the same wrong position (even if the figure is indeed maximized, I can see it on the screen):
fig.Visible='on'
but when I click on "show all properties", it shows the right position:
fig.Position
ans =
1.0e+03 *
0.0010 0.0490 1.2800 0.6493
How can I solve this? I need it to properly define some sizes in my App (app designer).
For now, I create a figure, store the position and close it. But I would like the user didn't see an empty figure during the process.
Thank you

1 Commento

Again, you can avoid that by a selective workaround of a set of coordinates that you know are going to be in the visible range...depends upon which effect you think the lesser evil -- the temporary figure flicker or not being exactly where you want it.
I'd think it possible to figure out an algorithm about where your position is that you could compute a satisfactory set of coordinates from the data that are available.

Accedi per commentare.

 Risposta accettata

dpb
dpb il 10 Mag 2022
I deal with it by having a usersettings structure saved as a .mat file that contains all the stuff to restore from the user's last session including the last position of figures where the user left them. The startup function reloads all those so the figure will be recreated where the user last left it. If the file doesn't exist, then there are some system defaults that are reasonable for the number/size of monitor(s).
You can discover the number and size of monitors at the time your app starts by querying the root properties of the graphics environment. See the doc section titled "Root Properties" under Graphics Object Properties
With that data, you can set reasonable bounds based on the user's environment and not be dependent upon the defaults as your present method is.

5 Commenti

I'm not sure if store the usersettings would help me: the app will be used by several clients and I don't know on how many monitors or if they will be switch monitors during the analyses. However I'm going to think about it, thank you.
I correct myself. I already use the root properties to get the screensize, but then I use the figure plot to get the correct position with respect to the Windows taskbar. I didn't manage to properly get this information without the plot.
My code does something like to create the GUI on the left:
% Access screen size where the App runs (it automatically detects the size
% of the monitor on which the app is running)
screenSize = get(groot,'ScreenSize');
screenWidth = screenSize(3);
screenHeight = screenSize(4);
% Plot a figure to get the size of Windows taskbar
figH = figure('Menu','none','ToolBar','none','WindowState','maximized','Visible','on');
pause(3)
drawnow;
Position = get(figH,'Position');
close(figH);
% Place the GUI left to the screen
% GUI position and size:
left = Position(1);
bottom = Position(2);
width = 280;
height = (screenHeight-bottom)*0.965; %0.96 is a tolerance on the size
% Store for later
Store_sizes={'screenWidth', screenWidth;...
'screenHeight',screenHeight;...
'left',left;...
'bottom',bottom;...
'width',width;...
'height', height};
app.Property_StoreSize=Store_sizes;
drawnow;
app.StaringUIFigure.Position = [left bottom width height];
Please note that:
bottom =
49
After that, the code will produce a figure on the right part of the screen:
width=Sizes_stored{5,2};
bottom=Sizes_stored{4,2};
App_wid=Sizes_stored{1,2}-width;
App_hei=Sizes_stored{6,2};
set(gcf, 'Position', [width, bottom, App_wid, App_hei]);
I tried different solutions to get the bottom value (like such) but they didn't work.
For example, the following shows details only on the main screen. I think it may be solved with java but I am not an expert and I didn't solve it for now.
toolkit = java.awt.Toolkit.getDefaultToolkit();
scr_size = toolkit.getScreenSize();
fprintf('Screen size is: %d x %d\n', scr_size.width, scr_size.height)
jframe = javax.swing.JFrame;
insets = toolkit.getScreenInsets(jframe.getGraphicsConfiguration());
fprintf('Windows task bar height is: %d\n', insets.bottom)
Screen size is: 1920 x 1080 % this is the main monitor, my app is running over the second one
Windows task bar height is: 72 % I need 49 here
It would be easy if the figure position was correct from the beginning, when set to not-visible.
"It would be easy if the figure position was correct from the beginning, when set to not-visible."(*)
Well, that's the point -- it isn't so you've got to either find a way to get the right information (maybe java can help, I "know nuthink!" much about it, either, but if there's a method it should be discoverable with Mr. Gargle's magic search engine or in the doc) or have a fallback kludge to something reasonable.
I'm suggesting the latter; set some reasonable values on startup if they don't exist or are out of a valid range in the usersettings object for the given platform/session. You CAN get what are visible coordinates of the two monitors so it will be in the visible area; it may not be absolutely perfect the first time, but the user then can put it where wanted and then will have that from then on.
Sometimes, just have to be "perfect enough", not perfect.
(*) I won't disagree it seems as though the position should be the same regardless of the 'Visible' property setting; that would seem worthy of a bug report on at least the "quality of implementation" argument.
"...but the user then can put it where wanted and then will have that from then on''.
The task I am required to do is to locate GUI and plots perfectly from the beginning, not "perfectly enough" (unfortunately I'm not my own boss): GUI on the left + plots on the right, image attached below. I did it with the visible-figure opening, the step further would have been to make it invisible.
I am thinking about using just one time a visible-figure and store that position as you suggested. Maybe I could compare the stored width and heigth (that would include the taskbar size) with the current screensize: if I'm within a certain tolerance, gonna accept that, otherwise I will use a second visible figure to get the new position and store it again.
Thanks for the help!
ps. Mr. Gargle's magic search -> you mean, Google? Because I got T O O O O NS of information about java on Google, but not knowing java, so far I haven't solved and the timeline I have been given does not allow me spending further time on it.
'The task I am required to do is to locate GUI and plots perfectly from the beginning, not "perfectly enough"'
You need to switch graphics libraries then, unless you are using fixed width plots with fixed font size and fixed graphics resolution.
The graphics model used by MATLAB postpones layout until the graphics objects are made visible, for efficiency.
Automatic layout is fairly complicated. For example the exact drawing width of an axes depends on the details of how rounding is done in the conversion between data coordinates and physical coordinates which depends in part on the magnifying factor to account for high resolution displays. But whether you can complete a word or need to split over two lines can depend on the exact pixel width... and so on.
Yeah, Walter, I didn't even begin to touch that level of detail -- in my environment at least, it's good enough to have the figure be on the screen; ime the user will always end up tweaking/moving stuff around anyways, no matter how finely-tuned the developer thinks they've made it.
Sometimes, there is no practical alternative but "perfect enough"...

Accedi per commentare.

Più risposte (0)

Categorie

Scopri di più su Environment and Settings in Centro assistenza e File Exchange

Richiesto:

il 10 Mag 2022

Commentato:

dpb
il 12 Mag 2022

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by