I have this code
#Inject
#DataField("table-col")
SimplePanel tableContainer;
#PostConstruct
public void build() {
scroll(tableContainer.getElement(), this);
tableContainer.addHandler(new ScrollHandler() {
#Override
public void onScroll(ScrollEvent scrollEvent) {
// TODO - Does not trigger
Window.alert("Scroll");
}
}, ScrollEvent.getType());
}
My question is why the tableContainer Scroll handler does now work when the similar Javascript (JSNI) handler works:
public static native void scroll(Element elem, TablePage instance) /*-{
$wnd.$( elem ).scroll(function() {
if (elem.scrollTop >= (elem.scrollHeight - elem.offsetHeight)) {
instance.#com.mygwtapp.app.TablePage::scrolledToBottom()();
}
});
}-*/;
What could be wrong here?
The SimplePanel doesn't actually listen to ScrollEvent, if you want a panel with scroll support you can use ScrollPanel (which is a simple panel with scrolling support).
ScrollPanel scrollPanel = new ScrollPanel();
scrollPanel.addScrollHandler(new ScrollHandler() {
#Override
public void onScroll(ScrollEvent scrollEvent) {
// TODO - Does not trigger
Window.alert("Scroll");
}
});
In your second way, you're actually adding the event to the element itself, and waiting the event to fired from browser to call your handler. In both ways the event is fired from the browser, but the first one doesn't actually listen to it while the second one listens to it.
Related
When I create my TableViewer in my dialog class. I am adding a ListChangeListener. This listener listens to a ObservableList in my Data Model Class.
This is my createTableViewer method in the dialog class.
private void createTableViewer(Composite parent) {
viewer = new AplotDataTableViewer(parent, SWT.BORDER|SWT.V_SCROLL|SWT.FULL_SELECTION);
IObservableList iob = AplotDataModel.getInstance().getObservableList();
viewer.setInput(iob);
iob.addListChangeListener(new IListChangeListener() {
#Override
public void handleListChange(ListChangeEvent event) {
updateTableViewer();
}
});
}
So what is happening. When a user Closes the dialog using the Window Close Button (Red X).
That is disposing all the widgets and closing the window. When the Dialog is opened back.
The ListChangeListener is looking to the updateTableViewer, but the widgets in the update is already disposed.
Right now there are 2 ways to close the dialog.
1. Red X - maybe doing a Window.close()
2. My close button on the form.
#Override
protected void createButtonsForButtonBar(Composite parent) {
createButton(parent, IDialogConstants.OK_ID, "Close Aplot",
true);
}
#Override
protected void okPressed() {
getShell().setVisible(false);
}
Which is using okPressed and hiding the shell.
What I would like is to have both methods of closing the dialog the same.
Is it possible to add a listener to the Shell and in the handleEvent method. Have a call to the okPressed method?
getShell().addListener(SWT.Close, new Listener() {
#Override
public void handleEvent(Event e) {
okPressed();
}
});
Instead of SWT.Close should I be using Window.Close?
Should I be using Close_ID instead of ok_ID
#Override
protected void createButtonsForButtonBar(Composite parent) {
createButton(parent, IDialogConstants.CLOSE_ID, "Close Aplot",
true);
}
#Override
protected void closePressed() {
getShell().setVisible(false);
}
Is there a way to get my active ListChangeListener and remove it?
protected void closePressed() {
AplotDataModel.getInstance().getObservableList().removeListChangeListener(this);
}
I am not sure how to get active listeners?
I want to Close the Dialog either using the Windows Close Button (Red X) or the Close Button on the form. If possible I wish both actions would use the same code to remove the active Listener from my IObservableList and close the dialog.
Have you tried adding a DisposeListener to the window? The dispose listener can then unregister any event listeners you set on its controls. This will happen regardless of how the window is closed, either from the red X or by calling shell.close() in the okPressed() method.
For example:
private void createTableViewer(Composite parent) {
viewer = new AplotDataTableViewer(parent, SWT.BORDER|SWT.V_SCROLL|SWT.FULL_SELECTION);
final IObservableList iob = AplotDataModel.getInstance().getObservableList();
viewer.setInput(iob);
final IListChangeListener listener = new IListChangeListener() {
#Override
public void handleListChange(ListChangeEvent event) {
updateTableViewer();
}
};
iob.addListChangeListener(listener);
getShell().addDisposeListener(
new DisposeListener() {
#Override public void widgetDisposed(DisposeEvent e) {
iob.removeListChangeListener(listener);
}
});
}
I am trying to execute the following code:
SwingUtilities.invokeLater(new Runnable() {
public void run() {
if (frame.getExtendedState() == Frame.ICONIFIED)
frame.setExtendedState(Frame.NORMAL);
frame.getGlassPane().setVisible(!frame.getGlassPane().isVisible());
frame.toFront();
frame.repaint();
}
});
Unfortunately this does not bring it to the front from behind other windows... Any solutions?
Per the API documentation for setExtendedState:
If the frame is currently visible on the screen (the
Window.isShowing() method returns true), the developer should examine
the return value of the WindowEvent.getNewState() method of the
WindowEvent received through the WindowStateListener to determine that
the state has actually been changed.
If the frame is not visible on the screen, the events may or may not
be generated. In this case the developer may assume that the state
changes immediately after this method returns. Later, when the
setVisible(true) method is invoked, the frame will attempt to apply
this state. Receiving any WindowEvent.WINDOW_STATE_CHANGED events is
not guaranteed in this case also.
However, there is also a windowDeiconified callback you can hook into on WindowListener:
SwingUtilities.invokeLater(new Runnable() {
private final WindowListener l = new WindowAdapter() {
#Override
public void void windowDeiconified(WindowEvent e) {
// Window now deiconified so bring it to the front.
bringToFront();
// Remove "one-shot" WindowListener to prevent memory leak.
frame.removeWindowListener(this);
}
};
public void run() {
if (frame.getExtendedState() == Frame.ICONIFIED) {
// Add listener and await callback once window has been deiconified.
frame.addWindowListener(l);
frame.setExtendedState(Frame.NORMAL);
} else {
// Bring to front synchronously.
bringToFront();
}
}
private void bringToFront() {
frame.getGlassPane().setVisible(!frame.getGlassPane().isVisible());
frame.toFront();
// Note: Calling repaint explicitly should not be necessary.
}
});
I found that the following workaround for toFront() on a JDialog works on Windows 7 (haven't tested other platforms yet):
boolean aot = dialog.isAlwaysOnTop();
dialog.setAlwaysOnTop(true);
dialog.setAlwaysOnTop(aot);
Paul van Bemmelen
I want to show a small popup menu when you right-click a tab, now this is working fine but when you right click it also selects that tab which is unwanted.
So my idea was to make a new class, extend JTabbedPane and recode those mouse events. Problem is that I have no idea where to start, I was browsing its source but I can't find what part is handeling the mouseEvents.
Tabs.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent me) {
if(me.getButton()==3){
int tabNr = ((TabbedPaneUI)Tabs.getUI()).tabForCoordinate(Tabs, me.getX(), me.getY());
Component clickedTab = EventsConfig.window.MainTabs.getComponentAt(tabNr);
newMenu(clickedTab, me.getX(), me.getY());
}
}
});
Beware: dirty hack ahead! The only reason I recommend it, is that I consider the behaviour (select on right press) a bug in the BasicTabbedPaneUI's Handler.
The basic idea is to grab the listener installed by the ui, remove it, wrap into a custom listener which delegates everything except a right pressed to the original and add that to the pane:
private void installMouseListenerWrapper(JComponent tabbedPane) {
MouseListener handler = findUIMouseListener(tabbedPane);
tabbedPane.removeMouseListener(handler);
tabbedPane.addMouseListener(new MouseListenerWrapper(handler));
}
private MouseListener findUIMouseListener(JComponent tabbedPane) {
MouseListener[] listeners = tabbedPane.getMouseListeners();
for (MouseListener l : listeners) {
if (l.getClass().getName().contains("$Handler")) {
return l;
}
}
return null;
}
public static class MouseListenerWrapper implements MouseListener {
private MouseListener delegate;
public MouseListenerWrapper(MouseListener delegate) {
this.delegate = delegate;
}
#Override
public void mouseClicked(MouseEvent e) {
delegate.mouseClicked(e);
}
#Override
public void mousePressed(MouseEvent e) {
if (SwingUtilities.isRightMouseButton(e)) return;
delegate.mousePressed(e);
}
#Override
public void mouseReleased(MouseEvent e) {
delegate.mouseReleased(e);
}
#Override
public void mouseEntered(MouseEvent e) {
delegate.mouseEntered(e);
}
#Override
public void mouseExited(MouseEvent e) {
delegate.mouseExited(e);
}
}
then you have to add JPopupMenu (or JToolTip on MouseHoverOver ) to the JTabbedPane
A possible workaround is to set your custom tab component for each tab - see JTabbedPane#setTabComponentAt(...). Add a mouse handler to your custom tab component and redispatch left click events to the tabbedPane as described at http://www.jyloo.com/news/?pubId=1315817317000.
The custom tab component can be a simple JLabel (used for the tab title) or a container for multiple components. Depending on your requirements you can e.g. add an arrow button which will open a popup menu by left clicking the related button.
This article will helpful for removing unwanted tab selection when you click right mouse button.
Stop right click Event on JTabbedPane
I liked to add more about removing Mouse Listeners.
Try to override the method rather than removing it. It's better for future code updates.
The problem is BasicTabbedPaneUI's have inner class called Handler. That handler class override Mouse Listener.
To stop right click tab selection and show pop up menu; we need to override this method in BasicTabbedPaneUI,
protected MouseListener createMouseListener() {
return getHandler();
}
To get better look and feel we should override SynthTabbedPaneUI class.
SynthTabbedPaneUI is extends BasicTabbedPaneUI.
So our inner class is like this,
private class SynthTabbedPaneUIWrapper extends SynthTabbedPaneUI
{
private MouseAdapter menuAdapter;
private MouseAdapter getMenuAdapter()
{
if (menuAdapter == null)
{
menuAdapter =
new MouseAdapter()
{
#Override
public void mouseReleased(final MouseEvent e)
{
//implement to stop right click tab selection
//implement to show pop up menu
}
};
}
}
#Override
protected MouseListener createMouseListener()
{
return getMenuAdapter();
}
}
After that we can set our custom UI object into TabbedPane.
tabbedPane.setUI(new SynthTabbedPaneUIWrapper());
I don't know how to show another page on button click in blackberry using java.
I assume you have a ButtonField added to some kind of Screen. You need to set the FieldChangeListener for the ButtonField:
class YourScreen extends FullScreen {
public YourScreen() {
super();
ButtonField btn = new ButtonField("mybutton");
btn.setChangeListener(new FieldChangeListener() {
public void fieldChanged(Field field, int context) {
synchronized (UiApplication.getApplication().getEventLock()) {
UiApplication.getUiApplication().pushScreen(new FullScreen());
}
}
});
add(btn);
}
}
Also note that you need to either get the event lock before pushing the screen or pass UiApplication.invokeLater a Runnable like so:
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
UiApplication.getUiApplication().pushScreen(new FullScreen());
}
});
Some basics on UI threading issue on BB here: http://www.thinkingblackberry.com/archives/182
UiApplication.getUiApplication.pushScreen(new Screen());
http://www.blackberry.com/developers/docs/4.5.0api/index.html
Now that I am able to set the content of my second wizard's page depending on the first page selection, I am looking for a way to give the focus to my 2nd page's content when the user clicks the next button on the first page.
By default, when the user click the next button, the focus is given to the button composite (next, back or finish button depending on the wizard configuration)
The only way I found to give focus to my page's content is the following one:
public class FilterWizardDialog extends WizardDialog {
public FilterWizardDialog(Shell parentShell, IWizard newWizard) {
super(parentShell, newWizard);
}
#Override
protected void nextPressed() {
super.nextPressed();
getContents().setFocus();
}
}
To me it's a little bit "boring and heavy" to have to override the WizardDialog class in order to implement this behavior. More over, the WizardDialog javadoc says:
Clients may subclass WizardDialog, although this is rarely required.
What do you think about this solution ? Is there any easier and cleaner solution to do that job ?
This thread suggests:
In your wizard page, use the inherited setVisible() method that is called automatically before your page is shown :
public void setVisible(boolean visible) {
super.setVisible(visible);
// Set the initial field focus
if (visible) {
field.postSetFocusOnDialogField(getShell().getDisplay());
}
}
The postSetFocusOnDialogField method contains :
/**
* Posts <code>setFocus</code> to the display event queue.
*/
public void postSetFocusOnDialogField(Display display) {
if (display != null) {
display.asyncExec(
new Runnable() {
public void run() {
setFocus();
}
}
);
}
}
VonC's answer works great, I personally found it to be a little easier to work with like this though:
#Override
public void setVisible(boolean visible) {
super.setVisible(visible);
if (visible) {
Control control = getControl();
if (!control.setFocus()) {
postSetFocus(control);
}
}
}
private void postSetFocus(final Control control) {
Display display = control.getDisplay();
if (display != null) {
display.asyncExec(new Runnable() {
#Override
public void run() {
control.setFocus();
}
});
}
}