JavaFX GridLayoutPane with GridData.heightHint not updating unless Focus changes - layout

I created a GridLayoutPane and want to set the size of its children programmatically. This is working fine and the sizes are set correct,
but they are not applied after beeing set automatically.
My first thought was that I might have to call .layout() on the Pane, but this has no result at all. Now I noticed that my heightHint (on the GridData) do get applied when I click on a TextField after generating the heightHint (so changing focus does the trick)
I try to get a look into the world of JavaFX
SWT was my default for years nowm but for several reasons I try to port my widgets to JavaFX.
GridLayoutPane http://efxclipse.bestsolution.at/doc/api/org/eclipse/fx/ui/panes/GridLayoutPane.html
is there a manual way to tell JavaFX to layout ALL nodes on a Pane?
layout()
layoutChildren()
requestLayout()
have no result!

Related

How to make an overlay which capture no events

I would like to draw some sort of window on top of all the other windows. For example, to display some debugging infos (like conky) or things like a timer.
The main thing is that I would like to able to continue using the other windows while using it (the events go through transparently).
I've tried doing it with pygtk, pyqt and others but can't find a way to make it a real overlay with no event capture.
Is there some low-level x11 solution?
I think the Composite-extension-approach will not work when a compositing manager is running (and thus Composite's overlay window is already used).
Since you explicitly mention "no event capture":
The SHAPE extension allows to set some different shapes for a window. Version 1.1 of this extension added the "input" shape. Just setting this to an empty region should pretty much do what you want.
Some concrete example of exactly what I think you ask for can be found in Conky's source code: http://sources.debian.net/src/conky/1.10.3-1/src/x11.cc/?hl=769#L764-L781
Edit: Since you said that you didn't find anything in Gtk (well, PyGtk), here is the function that you need in Gtk: https://developer.gnome.org/gdk3/stable/gdk3-Windows.html#gdk-window-input-shape-combine-region
You might need Composite extension + GetOverlayWindow request:
Version 0.3 of the protocol adds the Composite Overlay Window, which
provides compositing managers with a surface on which to draw without
interference. This window is always above normal windows and is always
below the screen saver window. It is an InputOutput window whose width
and height are the screen dimensions. Its visual is the root visual
and its border width is zero. Attempts to redirect it using the
composite extension are ignored. This window does not appear in the
reply of the QueryTree request. It is also an override redirect
window. These last two features make it invisible to window managers
and other X11 clients. The only way to access the XID of this window
is via the CompositeGetOverlayWindow request. Initially, the Composite
Overlay Window is unmapped.
CompositeGetOverlayWindow returns the XID of the Composite Overlay
Window. If the window has not yet been mapped, it is mapped by this
request. When all clients who have called this request have terminated
their X11 connections the window is unmapped.
Composite managers may render directly to the Composite Overlay
Window, or they may reparent other windows to be children of this
window and render to these. Multiple clients may render to the
Composite Overlay Window, create child windows of it, reshape it, and
redefine its input region, but the specific arbitration rules followed
by these clients is not defined by this specification; these policies
should be defined by the clients themselves.
C api : XCompositeGetOverlayWindow
PyGTK Solution:
I think the composite and shapes X extensions are sufficiently ubiquitous and shall assume here that they are active on your system. Here's PyGtk code for this:
# avoid title bar and standard window minimize, maximize, close buttons
win.set_decorated(False)
# make the window stick above all others (super button will still override it in the z-order, which is fine)
win.set_keep_above(True)
# make events pass through
region = cairo.Region(cairo.RectangleInt(0, 0, 0, 0))
my_window.input_shape_combine_region(region)
win.show_all()
# set the entire window to be semi-transparent, if we like
win.set_opacity(0.2)
Basically what this does is tell Gtk that other than pixel (0,0) the entire window my_window should not be considered part of itself in terms of event propagation. That in turn, according to my current understanding means that when the pointer moves and clicks, the events go to the underlying window under the pointer position, as if my_window was not there.
Caveat:
This does allow your overlay window being the focus window (due to user-solicited window switching or just because it pops up and gets the focus when your application starts). Which means that for example, keyboard events will still undesirably go to it up until the user has clicked through it to make it lose focus in favor of whatever window is under the cursor. I would likely use the approach described here to iron out this aspect.
If there's a different and proper approach for making a portion of the screen "display stuff but not receive events", without building an oddball window like above over it, I'm happy to learn about it.
I assume that one's particular desktop environment (gnome, unity, etc. on linux) may interfere with this solution depending on version and configuration, on some occasions.

JavaFX request layout does nothing

I'm absolutely confused.
Studying JavaFX for several months.
In my application I have a custom scrollpane, where I recount scrollbar values manually. Everything is OK there. And when I resize the window it also works fine.
The problem appears when I launch application the first time. I see that my scrollbar value is incorrect, and it become correct when I resize window or move the pane placed inside scrollpane.
So theoretically all i need is just update my scrollpane on window start, or after window start. And... I've spent more than week trying to find out how. And the only way I've managed to do this is to call layoutChildren recursively. This is awful of course.
layout() - doesn't have any effect. I tried it with runLater() and placed it inside timer call. No way!
requestLayout() - also makes no sense.
Is it possible just UPDATE or REDRAW or MARK CONTROL TREE AS DIRTY in JAVAFX ???
Ok well, try this way
first gaining the focus, then try relayout options..
blah.requestFocus();
blah.layout();
Well. layout() works. But it shouldn't be placed inside Platform.runLater().
In simple example everything is fine. Then I suggest I have something wrong with my controls.
Thanks.

Child window not getting invalidated when the parent window has CLIP_CHILDREN and CLIP_SIBLINGS style

In my Application, there is a modeless dialog box which has one static control and some customized controls - Edit box, buttons. Actually we are enhancing the functionality of this dialog and added 2 more static controls. The dialog box has CLIP_SIBLINGS and CLIP_CHILDREN styles.
The Problem I am facing is in WinXP, when some other window gets overlapped on this dialog, every other control is getting painted properly except the newly added static controls. But there is no particular difference between the existing static controls and the ones I added.
This is solved with explicitly calling Invalidate method of the static control in dialog's OnPaint() method, but still I didn't get why the existing controls are painted fine.
I tried removing CLIP_CHILDREN style, then it worked fine but there is a lot of flickering.
Please help me understand the same, I have gone through so many threads relating to the same but I didn't find the answer.

OnTouchListener for a view in Jelly Bean

I have a game Activity, which contains a SurfaceView that fills the whole screen.
The app is declared as fullscreen, and appears as such.
My SurfaceView has an OnTouchListener, which feeds a GestureDetector, with a functionality that works fine on most devices.
The listener is set as simply as:
surface.setOnTouchListener(listener);
However, on Jelly Bean (Nexus 4) , touching the soft buttons (back, home, etc.) generates a touch event in coordinates that are irrelevant to my SurfaceView.
This currently generates weird behaviors.
I can workaround that by simply doing a check on touch events and see if they fit the surface size.
However, I was wondering if there is a more elegant solution - one that will just give me the touch events ONLY from my surface and not from those soft buttons.
This is also crucial in the case that some future devices do different variations of that (putting the soft buttons in the UPPER area, for example).

Magnifier like feature inside popup window....how to?

I need to create a magnifier like feature in my app. Like the "loupe" effect on the iphone !
The problem is that I need to do that inside a popup window and I don't get how to make it work !
The popup window display a grid of colors that I generate and draw one by one using shapeDrawables. What I want is to display that color bigger, zoom on it when the user touch and move his finger around the popup window (color grid). The idea is to create a tracking-zooming effect on the colors so the user can see more clearly under wich color his finger is currently located.
Problems are :
I can't seem to create another popup window on top of this one, Android limitation I think ?
If I modify the current shapeDrawable, resize it, change the boundaries, It needs to re-display the popup window before it takes effect (which is not acceptable of course)
So, anyone knows of a way I could draw over that popup window ?
EDIT :
I've tried solving this issue using a Custom Toast object...But it doesn't quite do the trick. It works, but toast object appears slowly and so the touch motion is not in sync at all with the user movement over the color grid.
I'm not sure if this will help you or not, but you might be able to accomplish this by using a second Activity... this second Activity would use Android's translucent theme if you include the following attribute in your manifest:
<activity android:theme="#android:style/Theme.Translucent">
This second activity will now only contain what you place in your layout. That is... the "real" activity you're running will still be visible behind it (anywhere you don't cover it up with views in the new layout).
You also might prefer Theme.Dialog if you really want to resemble a popup.
Something to keep in mind if you take this approach is you will probably want to override onWindowFocusChanged() in the new activity, and finish() in the event of you losing focus. Additionally, you'll need to figure out how to share your data between the two activities.

Resources