fun ensureVisible(item: T) {
// Gross workaround. Couldn't find any other solution
for (n in children) {
if (n is VirtualFlow<*>) {
n.scrollTo(items.indexOf(item) / getItemsInRow())
break
}
}
}
private fun getItemsInRow(): Int = (skin as GridViewSkin<*>).computeMaxCellsInRow()
I've been using this fairly hacky workaround to scroll a ControlsFX GridView to a specified item, and it served me well up until I packaged my app with JPackage. Everything else works exactly as expected and I don't have any errors, but the behavior is different only when packaged. Normally, when scrolling to the last element, the function scrolls down just far enough that the row containing the Cell is only just in view (e.g. at the bottom of the GridView). However, when my app is packaged with jpackage and I call my ensureVisible(item) function for the last item in the GridView, it scrolls until the last row is at the TOP of the GridView.
For reference, my project is built with maven using:
Windows 10
Kotlin 1.7.10
JDK 17.0.6
JavaFX 19.0.2.1
ControlsFX 11.1.2
I'm using the same packages and modules in my IDE, where it behaves as expected, as I've used in the jpackage'd app. As far as I can tell, there's hardly any information about how to scroll a GridView to a specific element in the first place, and I've found absolutely nothing about this behavior anywhere.
There isn't really an alternative to the ControlsFX GridView, either, as I rely on the recycled cells only generating nodes/views for visible elements.
Is there a better way to scroll to specific items in a GridView? If not, why might this behavior be changing for no apparent reason?
Related
I'm using the Netbeans IDE to create a GUI. The GUI looks great when all elements are visible, however, when I hide some of the elements, everything else moves as well. Is there any way to stop this from happening? I don't think there is any relevant code, but let me know if I should add some.
Screenshot of layout
I am working on an eclipse-plugin which makes use of a custom XMLMultiPageEditor by extending XMLMultiPageEditorPart and XMLTableTreeView by extending XMLTableTreeViewer the second one as well implements a IResourceChangeListener.
I provide this plugin in eclipse-mars and eclipse-neon, however the wired behavior only shows up in eclipse-neon.
The editor works fine so far, the only problem is, that the tree-view is completely blank when a related xml-document is opened with it:
I can even modify the document in the source-view and save it .. the tree-view stays blank.
The only events which bring the tree-view to life are:
re-size the editor-window with the mouse
open some other document and than switch back to the tab of the open xml-doc.
After that, the tree-view works like it should. If I now change the xml in the source-view, the tree-view is updated immediately.
Any ideas how I could trigger a refresh of the tree-view manually ?
Is this maybe a bug in eclipse-neon ?
Ok, the problem seems to be, that the x/y size of the TreeViewer in eclipse-neon is initialized with (0,0). Here a hack to fix that:
...
public class MyXMLTableTreeViewer extends XMLTableTreeViewer implements IResourceChangeListener{
....
public MyXMLTableTreeViewer(Composite parent, IEditorPart parentEditor)
{
super(parent);
....
Point size = getControl().getSize();
size.x = 1000;
getControl().setSize(size);
}
It seems to be sufficient to only set x to some value ... 10 already gives an image, but the "node" section than looks a bit pressed, so I picket 1000.
Even if it is just internal API, it looks like a bug for me. So if you are further interested, take a look to the eclipse bugreport.
Both XMLMultiPageEditorPart and XMLTableTreeViewer are in internal packages. This means that they are not part of the Eclipse APIs and can be changed by the Eclipse developers without warning (see Eclipse API Rules of Engagement).
It may well be the case that something was changed between Eclipse Mars and Neon. You cannot rely on internal classes working the same between releases. It is not an Eclipse bug because you are not using official APIs.
My WL6.1.0.1 hybrid application have an overflow (with css set to -webkit-overflow-scrolling: touch) which scrolls just fine, but I don't see the scroll bar, neither the android feedback when I hit the bottom of the scroll (that glowing light that android have).
Curiously enough if I access the same application via "Common Resources" using the chrome browser on my android device, both the scroll bar and the feedback shows up.
I added the following code to my main java class on the native side (the one that extends WLDroidGap and have the app name)
public void onWLInitCompleted(Bundle savedInstanceState){
super.loadUrl(getWebMainFilePath());
// Add custom initialization code after this line
this.appView.setVerticalScrollBarEnabled(true);
this.appView.setVerticalScrollbarOverlay(true);
}
But it still doesn't work, any ideas?
For the "feedback", you are probably referring to EdgeEffect (when reaching the bottom of the view). If so, it is working for me like this:
public void onWLInitCompleted(Bundle savedInstanceState){
super.loadUrl(getWebMainFilePath());
// Add custom initialization code after this line
this.appView.setOverScrollMode(appView.OVER_SCROLL_ALWAYS);
}
You can set this in the onCreate as well...
For showing the scrollbar, I think you need to use awakenScrollBars() in combination with setVerticalScrollBarEnabled.
That said, I don't know the use case of your app, but typically in an app you would not want a scrollbar unless specifically in a list or something like that (and maybe not even there...).
Additionally, because you are developing a Hybrid app in Worklight and may target additional environments there are alternative solutions instead of delving into native code, such as using iScroll which can take care of much more than just scrolling, but also the "bounce" effect and other things.
Similar question, but not exactly the same.
table.showColumn() is helpful, but the scrolling only has the granularity of the column width. But I want a more precise control of the scroll location.
Consider the following use case. I have two tables that I know are of the same width and have the same column widths. And I want to implement some kind of a scroll synchronizer so that when the user scrolls one table (horizontally), the other table scrolls to the same location.
EDIT:
On the Eclipse forum there seems to be the same question and some working ideas, but no resolution.
EDIT:
I discovered this behavior on Windows
The method setOrigin(x,y) in ScrolledComposite should help:
Scrolls the content so that the specified point in the content is in the top left corner. If no content has been set, nothing will occur. Negative values will be ignored. Values greater than the maximum scroll distance will result in scrolling to the end of the scrollbar.
I'm afraid I can't get a satisfying result in Windows Vista/7 either, but felt I was getting close.
I believe you will have to grab the Table's horizontal scroll bar by using table.getHorizontalBar(). Then, you can specify scrollbar.setSelection() to make it move to a specified position.
This is where I get stuck. Somehow, you have to notify either the Table or the ScrollBar that the value has changed. I've tried everything from update() to notifyListener(), but no dice. It seems that it is merely a matter of laying out, but layout() doesn't have any effect, either.
Incidentally, bear in mind that the ScrollBar's parent (type Scrollable) is not a ScrolledComposite like I had expected, but is actually the Table itself.
I hope this gives you some ideas and helps you find a solution. If so, please let me know, since it's bugging me now, too!
Having poked around in the ScrollBar source a bit, it looks like there are numerous (windows) bugs that have been overcome at one point or another. This may be another, though you didn't mention your OS, nor did Paul, so it's hard to tell.
All the "change the scroll bar position" functions end up calling SetScrollInfo which is package private. I suspect that the intention is for this to actually update things the way you want.
None of that solves your problem. Thankfully the same source also hints at a solution:
Slider.
You'd have to reimplement all the scrollbar behavior within slider, but once done, that should give you the control (har) you want. Hopefully. OTOH, you may run into exactly the same OS bug (if bug it be), and be back at square one.
At THAT point, you definitely register it as an Eclipse UI bug.
PS: Have you searched the Eclipse Bugzilla for anything similar? Poking around a bit turned up this bug related to the scroll bar being out of sync with a tree view in the Navigator (on PC Linux-Motif, but working fine in Windows). I suspect you'll find similar issues if you dig a bit more.
We have implemented a table-based editor with an SWT tree table. It pretty much does what we want it to, except that we can't find a way to ensure that the first few columns remain at their position when the user scrolls horizontally (so that one can identify the row being edited).
There are a number of third-party table controls in various degrees of being incomplete or abandoned, and a snippet that shows how to use two tables (which get out of sync when they're being scrolled vertically).
What's the best way to solve this?
This 'official' SWT snippet does what you want to do, at least on my machine - it does not get out of sync on vertical scroll. But the price is a second scrollbar - way ugly. To prevent this, you can add the style SWT.NO_SCROLL in the constructor of the left table.
To improve the thing you will have to add a Listener on SWT.Traverse to both Tables, which syncs them if the user navigated using keys, something like this:
leftTable.addListener(SWT.Traverse, new Listener() {
public void handleEvent( Event event ) {
rightTable.setTopIndex(leftTable.getTopIndex());
}
});
I wouldn't go with another Table implementation, since you lose the biggest advantage you have with SWT: using a native widget, which looks and feels 'right' in each OS. If you want to do that anyway, Grid from the Nebula project is much more mature than the alpha tag implies. Don't know if it can do what you want, though.
the "syncing problem" only appears on MacOs based SWT. If your target platform is windows you should have no problem with the given SWT-Snippet. There will be more listeners to register on both tables to synchronise all occuring events (collapse, expand, mouse scroll, etc.)