Add listener to SpanElement - java

I wanna add mouse over listener to SpanElement, which i created by:
SpanElement span = Document.get().createSpanElement();
span.setInnerText("my text");
I found in google how to do it with Label-wrapper, but I wanna to do it without any wrappers. Is it possible?
Thank you.

It is possible without JSNI too.
So with your element:
SpanElement span = Document.get().createSpanElement();
span.setInnerText("my text");
to add event listener directly to element:
Event.sinkEvents(span, Event.ONCLICK);
Event.setEventListener(span, new EventListener() {
#Override
public void onBrowserEvent(Event event) {
if(Event.ONCLICK == event.getTypeInt()) {
//do your on click action
}
}
});
...and it looks really ugly ;)
as you notice - the event listener is "common" for all dom events conceived by this element. so to make sure you handle the proper event you should check event type when you sink more than one Event type (this time it's overhead - as we sinked only CLICK event's bit). And as to sinking -> this initializes the element to take part in gwt global dom event dispatching system - the event are handled globaly to decrease number of closures so minimize memory leaks in older IE browsers.
on one more thing. you can set only one event listener per element - if you set a new one it overwrites the previous one. So i assuming somwehere later you want to add MOUSEOVER listener to your span and not to clear off allready added CLICK listener you might do something like this:
//add mouseover event bit to existing sunk event bits
Event.sinkEvents(span, Event.getEventsSunk(span) | Event.ONMOUSEOVER);
final EventListener oldListener = Event.getEventListener(span);
Event.setEventListener(span, new EventListener() {
#Override
public void onBrowserEvent(Event event) {
if(Event.ONMOUSEOVER == event.getTypeInt()) {
//your mouseover action
}
if(oldListener != null) {
oldListener.onBrowserEvent(event);
}
}
});
or adding more events at once:
//add mouseover event bit to existing sunk event bits
Event.sinkEvents(span, Event.ONCLICK | Event.ONMOUSEOVER | Event.ONMOUSEOUT);
Event.setEventListener(span, new EventListener() {
#Override
public void onBrowserEvent(Event event) {
switch(event.getTypeInt()) {
case Event.ONCLICK:
break;
case Event.ONMOUSEOVER:
break;
case Event.ONMOUSEOUT:
break;
}
}
});
so after saying that all you probably aprecciate using a label widget wrapping your span ;)
Label.wrap(span).addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
//do your on click action
}
});
And last thing do not be afraid of widget even if you want to do DOM programming- look at them as something like jquery node wrapper object. they're not heavy but give much power.
you can also wrap widgets directly over existing DOM elements without attaching them to "panel infrastructure" .

Related

Mouse click to boolean

Hello from novice java developer, I created a MouseListener and MouseAdapter in a thread to control mouse action for mouse pressed, released and drag action. Each action will do specific things but i could not assign each MouseEvent e from each action to a variable.
So, how can deal with this problem? I also wonder if the method parameter MouseEvent e is specific to each method?
Here is my code:
Thread thread = new Thread() {
public void run() {
addMouseListener(new MouseAdapter() {
//#override deleted because i want to use e as a different action.
public void mouseaction(MouseEvent e) {
/* In here i want to control MouseEvent e action
(drag, pressed and released) and do specific things in with e event
and if e changes state should be changed in code during while(true) */
}
}
}
You can get all this information from the mouseEvent by calling the method getModifiersEx(), for example:
int eventType = e.getModifiersEx();
if (eventType & MOUSE_DRAGGED > 0) {
// Code to be executed when mouse is dragged
}
if (eventType & MOUSE_PRESSED > 0) {
// Code to be executed when mouse button is pressed
}
...
Note that the eventType is a bit field where multiple bits can be activated simultaneously.
//#override deleted because i want to use e as a different action.
public void mouseaction(MouseEvent e)
You can't just make up method names. You need to implement the methods of the listener. You need to handle the mousePressed, mouseReleased methods separately. For the mouseDragged you need to implement the MouseMotionListener.
Read the section from the Swing tutorial on Implementing Listener. You can find sections on:
How to Implement a MouseListener
How to Implement a MouseMotionListener
which both contain working examples.
I'll address this concern:
I also wonder if the method parameter MouseEvent e is specific to each method?
Every time this method is invoked by Swing, a new Event is generated. Your #Override annotation makes no difference.
So when user clicks somewhere, a MouseEvent N°2556 is generated for it, and the method is invoked with that event as a parameter.
When user drags the mouse away, a MouseEvent N°2557 is generated, and the method is again invoked with this new event as a parameter.
More broadly: All those MouseEvents will always be different instances. They are immutable, as well.
This means if you want to persist some information for your game loop to see, you need to store the relevant conditions in a field somewhere. And you won't be able to access it from an anonymous class because you won't have a handle to it. Here is a quick and dirty example (shameless reuse of #FrankPuffer's code):
public class MyMouseAdapter extends MouseAdpater {
public boolean isMousePressed = false; // This info is persisted here
public void mouseaction(MouseEvent e) { // This is only triggered upon user input
int eventType = e.getModifiersEx();
if (eventType & MouseEvent.MOUSE_PRESSED) {
isMousePressed = true;
}
if (eventType & MouseEvent.MOUSE_RELEASED) {
isMousePressed = false;
}
}
}
public static void main(String[] argc){
// Before the game loop:
MyMouseAdapter myAdapter = new MyMouseAdapter();
jpanel.addMouseListener(myAdapter);
// In the game loop
while(true) {
if(myAdapter.isMousePressed) { // This info is available anytime now!
// Do something
}
}
}

FocusListener for all controls of a Composite

I've written code for a Composite containing multiple controls (StyledTexts, Buttons, etc.).
I wanted to implement a FocusListener for the whole Composite (not only for one of the controls inside of it), but the FocusListener did not do anything.
I tried to implement it myself, and my attempt was: Add a FocusListener to every Control inside the composite and handle these events.
While trying to do so, I found some problems:
When two controls have a FocusListener and I change the focus from one to the other, the FocusLost event is fired before the FocusGained
So I can't find out if the focus was given to one of the other controls in my composite, or if the composite lost the focus completely.
Note: I tried using Display.getFocusControl() inside the focusLost(...) method, but it only returns the control from which the focus is taken!
My question: Is it possible to find out which control will receive the focus next while being inside the focusLost(...) method?
If not: Is there any other way to implement a FocusListener for a Composite?
At the time the focusLost() event is sent, it isn't yet known which control (if any) will receive the focus.
You can add a display filter that will inform you whenever a control within your entire application gains focus. Within your ' Listener` implementation, you can save the text input whenever a control gains focus that is not contained in the composite. For example:
Listener listener = new Listener() {
#Override
public void handleEvent( Event event ) {
if( event.widget != text || event.widget != fontButton || ... ) {
save();
}
}
};
display.addFilter( SWT.FocusIn, listener );
Make sure to add the listener only while the observed composite is alive. Remove the filter when the composite is disposed of.
display.removeFilter( SWT.FocusIn, listener );
#RüdigerHermanns works pretty good, but for the sake of completeness I'll post my solution here too:
I've written listeners for SWT.Activate and SWT.Deactivate in my composite:
public MyComposite(Composite parent, int style)
{
super(parent, style);
createGuiElements(this);
this.addListener(SWT.Deactivate, new Listener()
{
#Override
public void handleEvent(Event event)
{
for (FocusListener listener : focusListeners) listener.focusLost(new FocusEvent(event));
}
});
this.addListener(SWT.Activate, new Listener()
{
#Override
public void handleEvent(Event event)
{
for (FocusListener listener : focusListeners) listener.focusGained(new FocusEvent(event));
}
});
}
which notify all focusListeners on the Composite.

How to avoid triggering TableViewer when closing in Eclipse

I'm creating a TableViewer which has to respond to selections in other components.
I'm doing some actions in the implemented selectionChanged method.
#Override
public void selectionChanged(IWorkbenchPart part, ISelection selection) {
}
I want to avoid triggering the operations in selectionChanged method when I close the view.
I tried checking the received part:
if(part.getSite().getId()!="myviewid")
{
}
But I always get the part of the previous selection (in my case ResourceNavigator).
How can I check if I selected my view and avoid doing some operations ?
You should remove your selection listener from the selection service when your view part is disposed
#Override
public void dispose()
{
ISelectionService service = (ISelectionService)getSite().getService(ISelectionService.class);
service.removeSelectionListener(myListener);
super.dispose();
}

Can't get ItemListener to work for JCheckBox

I am using this code to create a JCheckBox
private final JCheckBox cbDisplayMessage = new JCheckBox("Display");
cbDisplayMessage.addItemListener(new ItemListener() {
#Override
public void itemStateChanged(ItemEvent e) {
if(e.getItemSelectable() == cbDisplayMessage) {
if(cbDisplayMessage.isSelected()) {
cbDisplayMessage.setSelected(false);
} else {
cbDisplayMessage.setSelected(true);
}
}
}
});
When I run this it causes an StackOverflow error on setSelected(true). Can't figure out what I am doing wrong. Any ideas appreciated....
You can try with ActionListener instead of ItemListener as shown below without causing StackOverflow error.
cbDisplayMessage.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (cbDisplayMessage.isSelected()) {
cbDisplayMessage.setSelected(false);
} else {
cbDisplayMessage.setSelected(true);
}
}
});
There is no need to check the source of the event again because you are sure that you have added this listener on the same object. This is required only if same listener is added for more components.
-- EDIT--
Now Your requirement is clear to me. If you want to toggle the state of the check box then there is no need to do it using listener because that's the default behavior of the check box.
Your listener is called every time the state changes, but you trigger a new state change from within that listener, so each state change results in that listener being called over and over again until your stack is full. Your setup has to be a bit more complicated to do something like that - if you want to change the state of the component you're listening to, you'll want to remove its listener(s), fire your programmatic state change, then re-add them.

Components inside List in CodenameOne

my question is. Is possible to add a component like a button (button has a functionality that triggered when it is clicked) inside a list component?
This image explain better what I refer:
http://2.bp.blogspot.com/-HThpKcgDyRA/URI_FdpffMI/AAAAAAAAAUI/SficZAPXaCw/s1600/1.png
Yes but it requires some handcoding and it will only work for touch (since you won't be able to assign focus to it).
We normally recommend just using Component/Container hierarchies for these cases rather than dealing with lists but obviously this isn't always practical.
The key is to always use the list action listener to trigger events, nothing else. So when you are in the action handling code of the list you would want to know if it was triggered by your button...
If you are in the GUI builder this is pretty easy:
Button b = ((GenericListCellRenderer)list.getRenderer()).extractLastClickedComponent();
if(b != null && b == myButton) {
// your event code here for the button, the selected entry is list.getSelectedItem()/Index()
}
The handcoded approach is pretty similar with one major caveat, you don't have the extractLastClickedComponent method. So assuming you have a component within the renderer just add an action listener to it. Within the action listener just set a flag e.g.:
myButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ev) {
buttonWasClicked = true;
}
});
// within the list listener we do the exact same thing:
if(buttonWasClicked) {
// for next time...
buttonWasClicked = false;
// your event code here for the button, the selected entry is list.getSelectedItem()/Index()
}
Yes!!! Try it, this is pretty easy:....
http://www.codenameone.com/how-do-i---create-a-list-of-items-the-easy-way.html
http://www.codenameone.com/how-do-i---create-a-list-of-items-the-hard-way-gui-builder-renderer.html

Categories