Categories
discuss

Adding Javascript EventListener only if no other listener is present?

I’m a relative tyro in the Javascript programming arena, so please go easy on me. 🙂

I am trying to add an eventListener to various DOM elements on a page. However, some of the elements I’m adding my event to already have an eventListener, and I don’t want to supersede that one; I only want to add my event to an element that doesn’t already have an event associated with it.

I’ve looked through a bunch of stuff relating to addEventListener, event.StopPropagation, event bubbling, and so forth, but haven’t figured out any way to accomplish this yet.

Is there a way to detect other event listeners on a given element, or some other way to get where I want?

Answer

You can check if the on[event] property of that given element is set by using:

if (typeof(document.getElementById("element-id").onclick) == "undefined") {
  // event undefined
}

if (typeof(document.getElementById("element-id").onclick) == "function") {
  // event defined
}

Notice that this won’t work if a javascript library such as jQuery were used to define the event (e.g. by using $("#element-id").click()). I’d recommend you to use jQuery, you can handle events easily with it.

edit: uh, well, afaik it doesn’t work if you’re using addEventHandler too. It only works if you set your event by using yourElement.onclick = anyFunction

Categories
discuss

Debugging in Eclipse (Java); can’t hover over a variable when breaking to view the value

I’m using Eclipse to code Java (for Android) and I’m trying to debug the code as I normally do (i normally do C# though).

From what I can tell, debugging in Eclipse is really bad. I don’t know if I’m doing something wrong, but it seems to be just awful.

This is the code that is being run, I get some sort of exception and I want to see what the Exception is, by breaking in the “catch”-clause and viewing the variable “e”:

try
{
    ConnectivityManager connectivityManager = (ConnectivityManager) this.getSystemService( Context.CONNECTIVITY_SERVICE );
    NetworkInfo activeNetInfo = connectivityManager.getActiveNetworkInfo();
    NetworkInfo mobNetInfo = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
    NetworkInfo.State state = mobNetInfo.getState();
}
catch(Exception e)
{
    Log.v("MyAp", e.toString()); // I break on this line, and want to see what e is
}

The problem is that I cannot see “e” by holding my mouse over it (as I can in my beloved Visual Studio).

Now, I know that I can bring up the tab “Variables” which lists all variables accessible from when I’m breaking, but that’s not optimal.

Just so I know – Eclipse has no way of “hovering” over the variable you are interested in, as in Visual Studio?

Edit

Thanks for the answers. However, still have the same problem =(

Answer

As far as I can tell, you have to be in Debug view in order to hover over objects and see their properties. At least that’s how my copy of Eclipse 3.4 works.

Of course, you also need to be in Debug view to have the Step Into, Step Over, Continues, etc… buttons…

Categories
discuss

How to stop window unloading?

when user click a another link or refresh the page, the window will unload, how to prevent/confirm it?

Answer

From here http://bytes.com/topic/javascript/insights/825556-using-onbeforeunload-javascript-event

<script type="text/javascript">
     window.onbeforeunload = function(){ return 'Your Returned String Goes Here';}
</script>
Categories
discuss

Run code for x seconds in Java?

I’d like to write a java while loop that will iterate for 15 seconds. One way I thought to do this would be to store the current system time + 15sec and then compare that to the current time in the while loop signature.

Is there a better way?

Answer

The design of this depends on what you want doing for 15s. The two most plausible cases are “do this every X for 15s” or “wait for X to happen or 15s whichever comes sooner”, which will lead to very different code.

Just waiting

Thread.sleep(15000)

This doesn’t iterate, but if you want to do nothing for 15s is much more efficient (it wastes less CPU on doing nothing).

Repeat some code for 15s

If you really want to loop for 15s then your solution is fine, as long as your code doesn’t take too long. Something like:

long t= System.currentTimeMillis();
long end = t+15000;
while(System.currentTimeMillis() < end) {
  // do something
  // pause to avoid churning
  Thread.sleep( xxx );
}

Wait for 15s or some other condition

If you want your code to be interrupted after exactly 15s whatever it is doing you’ll need a multi-threaded solution. Look at java.util.concurrent for lots of useful objects. Most methods which lock (like wait() ) have a timeout argument. A semaphore might do exactly what you need.

Categories
discuss

Java Sockets and Dropped Connections

What’s the most appropriate way to detect if a socket has been dropped or not? Or whether a packet did actually get sent?

I have a library for sending Apple Push Notifications to iPhones through the Apple gatways (available on GitHub). Clients need to open a socket and send a binary representation of each message; but unfortunately Apple doesn’t return any acknowledgement whatsoever. The connection can be reused to send multiple messages as well. I’m using the simple Java Socket connections. The relevant code is:

Socket socket = socket();   // returns an reused open socket, or a new one
socket.getOutputStream().write(m.marshall());
socket.getOutputStream().flush();
logger.debug("Message "{}" sent", m);

In some cases, if a connection is dropped while a message is sent or right before; Socket.getOutputStream().write() finishes successfully though. I expect it’s due to the TCP window isn’t exhausted yet.

Is there a way that I can tell for sure whether a packet actually got in the network or not? I experimented with the following two solutions:

  1. Insert an additional socket.getInputStream().read() operation with a 250ms timeout. This forces a read operation that fails when the connection was dropped, but hangs otherwise for 250ms.

  2. set the TCP sending buffer size (e.g. Socket.setSendBufferSize()) to the message binary size.

Both of the methods work, but they significantly degrade the quality of the service; throughput goes from a 100 messages/second to about 10 messages/second at most.

Any suggestions?

UPDATE:

Challenged by multiple answers questioning the possibility of the described. I constructed “unit” tests of the behavior I’m describing. Check out the unit cases at Gist 273786.

Both unit tests have two threads, a server and a client. The server closes while the client is sending data without an IOException thrown anyway. Here is the main method:

public static void main(String[] args) throws Throwable {
    final int PORT = 8005;
    final int FIRST_BUF_SIZE = 5;

    final Throwable[] errors = new Throwable[1];
    final Semaphore serverClosing = new Semaphore(0);
    final Semaphore messageFlushed = new Semaphore(0);

    class ServerThread extends Thread {
        public void run() {
            try {
                ServerSocket ssocket = new ServerSocket(PORT);
                Socket socket = ssocket.accept();
                InputStream s = socket.getInputStream();
                s.read(new byte[FIRST_BUF_SIZE]);

                messageFlushed.acquire();

                socket.close();
                ssocket.close();
                System.out.println("Closed socket");

                serverClosing.release();
            } catch (Throwable e) {
                errors[0] = e;
            }
        }
    }

    class ClientThread extends Thread {
        public void run() {
            try {
                Socket socket = new Socket("localhost", PORT);
                OutputStream st = socket.getOutputStream();
                st.write(new byte[FIRST_BUF_SIZE]);
                st.flush();

                messageFlushed.release();
                serverClosing.acquire(1);

                System.out.println("writing new packets");

                // sending more packets while server already
                // closed connection
                st.write(32);
                st.flush();
                st.close();

                System.out.println("Sent");
            } catch (Throwable e) {
                errors[0] = e;
            }
        }
    }

    Thread thread1 = new ServerThread();
    Thread thread2 = new ClientThread();

    thread1.start();
    thread2.start();

    thread1.join();
    thread2.join();

    if (errors[0] != null)
        throw errors[0];
    System.out.println("Run without any errors");
}

[Incidentally, I also have a concurrency testing library, that makes the setup a bit better and clearer. Checkout the sample at gist as well].

When run I get the following output:

Closed socket
writing new packets
Finished writing
Run without any errors

Answer

This not be of much help to you, but technically both of your proposed solutions are incorrect. OutputStream.flush() and whatever else API calls you can think of are not going to do what you need.

The only portable and reliable way to determine if a packet has been received by the peer is to wait for a confirmation from the peer. This confirmation can either be an actual response, or a graceful socket shutdown. End of story – there really is no other way, and this not Java specific – it is fundamental network programming.

If this is not a persistent connection – that is, if you just send something and then close the connection – the way you do it is you catch all IOExceptions (any of them indicate an error) and you perform a graceful socket shutdown:

1. socket.shutdownOutput();
2. wait for inputStream.read() to return -1, indicating the peer has also shutdown its socket
Source: stackoverflow
Text is available under the Creative Commons Attribution-ShareAlike License; additional terms may apply. By using this site, you agree to the Privacy Policy, and Copyright Policy. Content is available under CC BY-SA 3.0 unless otherwise noted. The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 © No Copyrights, All Questions are retrived from public domain..