views:

107

answers:

5

I have a JFrame object, and i need to support two JVM 1.5 on Mac OS X and 1.6 on Windows. On windows I need to use setIconImages function to set multiple icon sized for the application but this function is not availible on 1.5. Is it possible to call this function inside JFrame with reflection?

Application extends JFrame{
.
.
.
  void init(){
   //check version
   //call setIconImages 
  }

}
A: 

It looks like javax.swing.JFrame in java 1.5 has a setIconImage() function. Why do you need to set multiple images?

KitsuneYMG
Windows 7 uses multiple application icons. if i use setIconImage() they get resized for different sizes, messes the icons.
Hamza Yerlikaya
+1  A: 

I would do something like the following (wont' compile, but should get you started):

create a class called FrameUtils and give it the following method:

public static void setIconImages(final java.awt.Window window, 
                                 final List<? extends Image> icons) 
{
    try
    {
        Method setIconImagesMethod;

        setIconImagesMethod = // use reflection to get the setIconImages method. 
        setIconImagesMethod.invoke(window, icons);
    }
    catch(final NoSuchMethodException ex)
    {
        // fall back to the single image method
        window.setIconImage(icons.get(0));
    }
}

This link shows you how to get the method and call it via reflection.

TofuBeer
// use reflection to get the setIconImages method.this is actually what i am asking sorry if i couldn't make it clear how can i get a Method object for a method in the object i am in.
Hamza Yerlikaya
+1  A: 

Since you have to compile on both versions of jdk separately, probably the best solution would be to have an interface for things that don't work on old jdk and have two implementations of it. Then load implementation you need at startup.

tulskiy
+1 - this approach is better than reflection because it naturally isolates the difference between the JDK versions. It is also more efficient (and less error prone) than using reflection in most cases.
Stephen C
A: 

yes, reflection is the way to go for this purpose.

I've seen this trick on some libraries where "backward comparability" is needed. the binary must work on older VM, so newer APIs must be accessed through reflection.

irreputable
hmm... I think I said some stupid things. In your case, just call the method normally anyway and compile it under 1.6. when deployed to 1.5, it runs fine until the method is invoked; just catch and ignore NoSuchMethodException
irreputable
last time I ran a 1.6 compiled class on 1.5, it didn't run. You have to compile it using -target and 1.5 bootstrap classes.
tulskiy
A: 

If you can compile with Java 1.6, a simple way to do it by catching NoSuchMethodError. Following is an example from my code which gets the screen bounds accounting for the taskbar, but falls back to the entire bounds if the Java version is too early:

try {
    sb=wnd.getGraphicsConfiguration().getBounds();
    }
catch(NoSuchMethodError thr) {
    Dimension ss;
    ss=wnd.getToolkit().getScreenSize();
    sb=new Rectangle(0,0,ss.width,ss.height);
    }

If you need to use reflection (because J6 changed the class version and you must compile to J5) then you just need to extract the J6 method with reflection, and catch MethodNotFoundException to execute the fallback call.

Software Monkey