Friday, 29 December 2017

Detect user activity in a windows system using Java.

When I was working on a project to shut down the systems that were left turn on after use by students in a computer lab, then I searched a lot of Java code to detect mouse and keyboard activity by users. Since you all know that you can detect mouse and keyboard by Java Code but it is limited to only frame that is focused.
Robot class lets you know the somehow the pointer position, but it is hard to ignore the keyboard.
After a long search on Internet I found  zOlive code (post) very useful to detect user inactivity on windows system.
I applied whole java source code of zOlive in my project.

See how I applied the zOlive code to detect user inactivity and shutdown the system.
As said by zOlive  in his post:-
To run this code you require jna.jar file from JNA website.
Go to the directory where jna.jar was saved and create the file Win32IdleTime.java in it.
Open cmd.exe and go to the directory. Compile with
javac -classpath jna.jar Win32IdleTime.java
Run with
  • java -cp jna.jar;. Win32IdleTime
    (replace “;” by “:” on Unix systems).

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import com.sun.jna.*;
import com.sun.jna.win32.*;
/**
 * Utility method to retrieve the idle time on Windows and sample code to test it.
 * JNA shall be present in your classpath for this to work (and compile).
 * @author ochafik
 */
public class Win32IdleTime {
        public interface Kernel32 extends StdCallLibrary {
                Kernel32 INSTANCE = (Kernel32)Native.loadLibrary("kernel32", Kernel32.class);
                /**
                 * Retrieves the number of milliseconds that have elapsed since the system was started.
                 * @see http://msdn2.microsoft.com/en-us/library/ms724408.aspx
                 * @return number of milliseconds that have elapsed since the system was started.
                 */
                public int GetTickCount();
        };
        public interface User32 extends StdCallLibrary {
                User32 INSTANCE = (User32)Native.loadLibrary("user32", User32.class);
                /**
                 * Contains the time of the last input.
                 * @see http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/userinput/keyboardinput/keyboardinputreference/keyboardinputstructures/lastinputinfo.asp
                 */
                public static class LASTINPUTINFO extends Structure {
                        public int cbSize = 8;
                        /// Tick count of when the last input event was received.
                        public int dwTime;
                }
                /**
                 * Retrieves the time of the last input event.
                 * @see http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/userinput/keyboardinput/keyboardinputreference/keyboardinputfunctions/getlastinputinfo.asp
                 * @return time of the last input event, in milliseconds
                 */
                public boolean GetLastInputInfo(LASTINPUTINFO result);
        };
        /**
         * Get the amount of milliseconds that have elapsed since the last input event
         * (mouse or keyboard)
         * @return idle time in milliseconds
         */
        public static int getIdleTimeMillisWin32() {
                User32.LASTINPUTINFO lastInputInfo = new User32.LASTINPUTINFO();
                User32.INSTANCE.GetLastInputInfo(lastInputInfo);
                return Kernel32.INSTANCE.GetTickCount() - lastInputInfo.dwTime;
        }
        enum State {
                UNKNOWN, ONLINE, IDLE, AWAY
        };
        public static void main(String[] args) {
                if (!System.getProperty("os.name").contains("Windows")) {
                        System.err.println("ERROR: Only implemented on Windows");
                        System.exit(1);
                }
                State state = State.UNKNOWN;
                DateFormat dateFormat = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss");
                for (;;) {
                        int idleSec = getIdleTimeMillisWin32() / 1000;
                        State newState =
                                idleSec < 30 ? State.ONLINE :
                                idleSec > 5 * 60 ? State.AWAY : State.IDLE;
                        if (newState != state) {
                                                                          // You can put your code here according to newstate
                                state = newState;
                                System.out.println(dateFormat.format(new Date()) + " # " + state);
                        }
                        try { Thread.sleep(1000); } catch (Exception ex) {}
                }
        }
}

Say thanks to zOlive to post such a nice post.
You may also find the MAC OSx version and Linux version of this code in his post.

Sunday, 3 December 2017

How to customize JOptionPane in Java/Swing

JOptionPane is pop up window to show any information, confirm any action or user input in Java. We can use JOptionPane class simply to show dialogue boxes for users. But it has default size, text and icons and some time we feel that, can we customise the properties of this dialogue box, like its window size, its text size, colour and type and many more?

So, obviously answer is yes, we can customise the properties of JOptionPane. Let see how?

To create dialogue box using JOptionPane, we simply use -

JOptionPane.showConfirmDialog(null,"Text Message", "Window Title",JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
 
Output looks like -

Now If you want to customise the message text, we require to use label(JLabel), because we can customize the JLabel text and can apply css and HTML on it. See this post.

 JLabel label = new JLabel("<html><p><h1>Text Message</h1></p><html>");

JOptionPane.showConfirmDialog(null,"Text Message", "Window Title",JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);

Output looks like -

above we have changed the text colour and size.

 You can also customise JLabel text by using code like -

label.setFont(new Font("Arial", Font.BOLD, 18));

To change default image you can use code like -

ImageIcon icon = new ImageIcon(Pane.class.getResource("ss.jpg"));

JOptionPane.showConfirmDialog(null,"Text Message", "Window Title",JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, icon);

Output will look like -

To change the window size, you can use code like -

UIManager.put("OptionPane.minimumSize",new Dimension(500,500));

JLabel label = new JLabel("<html><p><h1 style=color:green>Text Message</h1></p><html>");

ImageIcon icon = new ImageIcon(Pane.class.getResource("ss.jpg"));

JOptionPane.showConfirmDialog(null,label, "Window Title",JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE,icon);

Output looks like -

You can also do many more experience with JOptionPane customisation.

Change image source dynamically on hyperlink

 Changing image source dynamically using JQuery. Here in this example I have created there hyperlink and stored all images in the same folde...