Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 381
  • Last Modified:

Taking into account the size of the taskbar

We are making a little messenger for a Java student project.  We want to have a graphic(a window) popup in the lower right hand corner whenever someone log's in.  We notice when you maximize a window java knows the position of the taskbar.  So I was wondering if i could do a getTaskBarSize or something in order to align the bottom of my window to the top of the taskbar.
0
turtletimer
Asked:
turtletimer
  • 4
  • 2
1 Solution
 
CEHJCommented:
A kludgy way would be to get the screen size and then shorten it a bit:

http://javaalmanac.com/egs/java.awt/screen_ScreenSize.html
0
 
aozarovCommented:
I think to get the size of the taskbar you will need to use JNI (or use a third party library that uses JNI to achive it).
Though, maybe you can achive by maximize your Window and then substrcut the hight of window from the Screen hight (see above reference).
0
 
aozarovCommented:
Actually instead of the "maximize trick" you might be able to subtruct

GraphicsEnvironment.getLocalGraphicsEnvironment() .getMaximumWindowBounds().getHeight()
from
GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDisplayMode().getHeight()
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
Jim CakalicSenior Developer/ArchitectCommented:
Hi,

This is a rather long post as it incorporates information from an answer I gave previously. Here's an example using JNI (may or may not compile ...)

----- (1) Using JNI directly -----
One option is to use JNI to wrap a call to the Win32 API function that will report the size of the work area on the primary display. The work area is the portion of the screen not obscured by the system taskbar or by application desktop toolbars.

Here is the essential Java and C++ code necessary.

---------- SystemParametersInfo.java ----------
public class SystemParametersInfo {

    // do not permit this class to be instantiated
    private SystemParametersInfo() {}

    // native method to get WORKAREA
    public static native java.awt.Dimension getWorkArea();

    // static initializer to load the JNI dll
    static {
        System.loadLibrary("SysParamInfo");
    }

}
---------- end ----------

---------- SysParamInfo.cpp ----------
#include <windows.h>
#include "SystemParametersInfo.h"

JNIEXPORT jobject JNICALL
Java_SystemParametersInfo_getWorkArea(JNIEnv *env, jobject java_this) {
    // do the native work
    RECT workArea;
    SystemParametersInfo(SPI_WORKAREA, 0, &workArea, 0);
    jint width = workArea.right - workArea.left;
    jint height = workArea.bottom - workArea.top;

    // return the result as a java.awt.Dimension object
    jclass clazz = env->FindClass("java.awt.Dimension");
    jmethodID mid = env->GetMethodID(clazz, "<init>", "(II)V");
    jobject size = env->NewObject(clazz, mid, width, height);
    return jobject;
}
---------- end ----------
   
The build steps are:
1) Compile the java source.
2) Run javah to generate the native header file from the class file.
3) Compile the native code.
4) Link the native code as a Win32 DLL.
 
I'm having a little trouble building right now. The primary reason is that I don't have Visual C++ on my system. I'm trying to build using Cygwin gcc. I'm getting through step 3 okay but haven't been able to get past the DLL build business. In case it helps, here is a modification of a batch file that I had which demonstrates the necessary command-line incantations to compile using Visual C++ on Windows NT 4.0.

---------- make.bat ----------
javac SystemParametersInfo.java

javah SystemParametersInfo

SET JDK_HOME=c:\jdk1.3

CL /nologo  /I %JDK_HOME%\include /I %JDK+HOME%\include\win32 /MD /W3 /GX /O2 /FD /c /D "NDEBUG" -DWINVER=0x400  -D_DLL -DWIN32 /D "_WINDOWS" SysParamInfo.cpp

LINK /subsystem:windows /INCREMENTAL:NO /dll /out:"SysParamInfo.dll" SysParamInfo.OBJ advapi32.lib
---------- end ----------

Assuming this all compiles and links, you should now be able to use it something like this:

    JFrame frame = new JFrame("Full Screen Frame");
    Dimension d = SystemParametersInfo.getWorkArea();
    frame.setSize(d);


----- (2) Using a commercial product -----
The package I tried is called xFunction from Excelsior
    http://www.excelsior-usa.com/xfunction.html

It seems to work pretty well actually. I posted the Java code below so you could try it if you download the eval package. The full version costs $99 I think.

---------- WinRect.java ----------
import com.excelsior.xFunction.*;
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;

public class WinRect extends Structure {
    int left;
    int top;
    int right;
    int bottom;

    public String defineLayout() {
        return "int left, int top, int right, int bottom";
    }
    public String toString() {
        return "WinRect["+left+","+top+","+right+","+bottom+"]";
    }

    public static void main(String[] args) {
     try {
            xFunction f = new xFunction("kernel32", "int Beep(int,int)");
            f.invoke(new Argument(1770), new Argument(100));
        } catch (Exception e) {
            e.printStackTrace();
        }

        WinRect rect = new WinRect();
        System.out.println("Before call: " + rect);
        try {
            /* The following is equivalent to the JNI:
                 RECT workArea;
                 SystemParametersInfo(SPI_WORKAREA, 0, &workArea, 0);
                 jint width = workArea.right - workArea.left;
                 jint height = workArea.bottom - workArea.top;
            */
            String sig = "int SystemParametersInfoA(int,int,WinRect*,int)";
            xFunction f = new xFunction("user32", sig);
            Argument arg1 = new Argument(48);
            Argument arg2 = new Argument(0);
            Pointer arg3 = Pointer.createPointerTo(rect);
            Argument arg4 = new Argument(0);
            Integer val = (Integer)f.invoke(arg1, arg2, arg3, arg4);
            rect = (WinRect)arg3.deref();
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(0);
        }
        System.out.println("After call: " + rect);

     int width = rect.right - rect.left;
     int height = rect.bottom - rect.top;
     System.out.println("Work area = " + width + "x" + height);

     JFrame frame = new JFrame("Maximum Work Area");
        frame.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
        frame.setSize(new Dimension(width, height));
        frame.setLocation(rect.left, rect.top);
        frame.show();
    }
}
---------- end ----------

There is a free package called coroutine that claims to do the same thing. I might be able to rewrite using that one ...


Regards,
Jim Cakalic
0
 
aozarovCommented:
jim_cakalic, did you try my pure Java suggestion above your solution. it seems to be working for me correctly. Am I missing something?
0
 
Jim CakalicSenior Developer/ArchitectCommented:
No, aozarov. I didn't try it because my experience has mostly been with Java 1.3 in an application server environment. Although I did have a need to do this a couple years ago and JNI was the only way to go at that time.

The maximum window bounds must have been new in Java 1.4. And with a little experimentation it seems it is even easier than what you suggested:

        GraphicsEnvironment lge = GraphicsEnvironment.getLocalGraphicsEnvironment();
        int maxh = (int)lge.getMaximumWindowBounds().getHeight();
        int maxw = (int)lge.getMaximumWindowBounds().getWidth();
        frame.setSize(maxw, maxh);
        frame.show();

One thing I noticed is that this doesn't seem to work (the result isn't what I expected) when the taskbar isn't configured to stay on top of other windows. In this case the above maximizes the window to include the space allocated to the taskbar. The JNI solution, as I recall, _always_ accounts for the size of the taskbar.

Jim
0
 
aozarovCommented:
>> And with a little experimentation it seems it is even easier than what you suggested..
Did you look at my second suggestion? (it uses the same API you mentioned to find the height of the taskbar [instead of using this value for setting the frame height]).
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

  • 4
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now