tacitus
unread,Feb 21, 2008, 2:22:54 PM2/21/08Sign in to reply to author
Sign in to forward
You do not have permission to delete messages in this group
Sign in to report message
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
to Google Web Toolkit
The basic problem is that if the keyboard focus is somewhere within a
ScrollPanel, when a user presses the UP, DOWN, PAGEUP, PAGEDOWN, etc,
arrow keys the ScrollPanel widget scrolls the panel whether you want
it to or not. I'm looking for a way to prevent the ScrollPanel from
doing this. I only want the panel to scroll when I decide it's really
necessary!
I have attached a working example of the problem. It is a simpler
version of the table widget I am playing with, where the keyboard can
be used to scroll through a long list of items.
The code inserts 100 HorizontalPanels into a VerticalPanel which has
been subclassed to add a KeyboadListener so that the user can scroll
through the items using the UP and DOWN arrow keys. The VerticalPanel
is placed inside a ScrollPanel, hence the scrollbar on the right of
the table.
If you run the example and click on the body of the panel to give it
the input focus, you can use the up and down arrow keys to change the
current selection (indicated by the "------>" text). First press the
up arrow a few times. You will see the selected item change as the
selection moves up towards the top of the panel. Nothing scrolls,
only the selection changes, which is as it should be.
Now press the down arrow key. The selection will change, moving down
the list, *but* the scrollbar will also move, scrolling the whole
window upwards. If the selected item is near the top of the window,
it will scroll off the top of the panel. Obviously the keystrokes are
being intercepted by the ScrollPanel and being used to scroll the
window. In this case, it is not necessary because I don't want the
window to scroll upwards until the currently selected item is right at
the bottom of the window. This is how MS Excel and countless other
applications scroll tables, and if you look at the Table examples in
the MyGWT widget, it can be done in GWT too, but I have no idea how.
What I want is for the ScrollPanel to ignore any keystrokes being sent
to the widgets contained within it, and then I can tell it to scroll
when I decide it is necessary. Does anyone know how to do this or
know how the MyGWT
does it? The answer seems to be buried deep in the GWT implementation
since I don't believe there is a simple subclass or override that can
do it, or am I missing a trick?
Thanks for any assistance or pointers!
Mike
--------------------------------------
Here's the code:
public void onModuleLoad() {
ScrollPanel scroll = new ScrollPanel();
scroll.setSize("80%", "30em");
VP panel = new VP();
panel.setWidth("95%");
for (int i = 0; i < 100; i++) {
addItem(panel, i);
}
scroll.add(panel);
RootPanel.get().add(scroll);
panel.selectItem(15);
}
private void addItem(VerticalPanel panel, int i) {
HorizontalPanel item = new HorizontalPanel();
item.add(new Label("Item number " + i));
panel.add(item);
}
private class VP extends VerticalPanel implements
SourcesKeyboardEvents {
KeyboardListenerCollection listeners = new
KeyboardListenerCollection();
int item = 0;
KeyboardListenerAdapter keyListener = new
KeyboardListenerAdapter() {
public void onKeyDown(Widget sender, char keyCode, int
modifiers) {
switch (keyCode) {
case KeyboardListener.KEY_DOWN:
if (item < VP.this.getWidgetCount() - 1) {
selectItem(item + 1);
}
break;
case KeyboardListener.KEY_UP:
if (item > 0) {
selectItem(item - 1);
}
break;
}
}
};
VP() {
sinkEvents(Event.KEYEVENTS);
addKeyboardListener(keyListener);
}
public void selectItem(int index) {
if (((HorizontalPanel)getWidget(item)).getWidgetCount() >
1) {
((HorizontalPanel)getWidget(item)).remove(0);
}
item = index;
((HorizontalPanel)getWidget(item)).insert(new Label("---
>"), 0);
}
public void addKeyboardListener(KeyboardListener listener) {
listeners.add(listener);
}
public void removeKeyboardListener(KeyboardListener listener)
{
listeners.remove(listener);
}
public void onBrowserEvent(Event event) {
switch (DOM.eventGetType(event)) {
case Event.ONKEYDOWN:
case Event.ONKEYUP:
case Event.ONKEYPRESS:
if (listeners != null) {
listeners.fireKeyboardEvent(this, event);
}
break;
}
}
}
}