JFrame transition effect - when called setState(Frame.ICONIFIED) it just goes to Taskbar without animation

独自空忆成欢 提交于 2019-12-01 03:40:39

问题


I have a problem now - when I call frame.setState(Frame.ICONIFIED) with my custom button (I'm not using default JFrame minimize button - JFrame set to setUndecorated(true) ), the JFrame just goes to Taskbar without any animation. In normal situation it should gradually go to Taskbar minimizing itself. But if I press iconfied JFrame on Taskbar, it restores with animation to normal size. The situation is on Windows XP, not tested on other systems, but I suppose it would behave in the same way.


回答1:


If what you are saying is true, and your undecorated windows do in fact animate when clicking the icons in the task bar. Then you can trigger that same action in your code using JNA.

For this solution to work, you'll need to include jna.jar and jna-platform.jar in your classpath.

This isn't a JNA tutorial, there are plenty of those around. This is just code that uses JNA to call the user32.dll functions CloseWindow and OpenIcon; These are the functions that Windows calls when you click the application's tray icon -- (truth be told I'm not certain that these are the actual functions, but they react the same).

import java.awt.Component;
import java.awt.Window;
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.platform.win32.WinDef.HWND;

public class IconifyUtilityClass
{
    public static void minimize(Window window)
    {
        HWND hWnd = getHWND(window);
        User32dll.INSTANCE.CloseWindow(hWnd); //call CloseWindow with this windows handle
    }

    public static void restore(Window window)
    {
        HWND hWnd = getHWND(window);
        User32dll.INSTANCE.OpenIcon(hWnd); //call OpenIcon with this windows handle
    }

    private interface User32dll extends Library
    {
        User32dll INSTANCE = (User32dll) Native.loadLibrary("user32.dll", User32dll.class);
        boolean OpenIcon(HWND hWnd);
        boolean CloseWindow(HWND hWnd);
    }

    private static HWND getHWND(Component comp)
    {
        return new HWND(Native.getComponentPointer(comp));
    }
}

To call the code just pass in your frame or dialog like so

JFrame frame = new JFrame();
...
IconifyUtilityClass.minimize(frame); //minimize your frame
...
IconifyUtilityClass.restore(frame); //restore your frame

It's worth noting that in Windows 7 undecorated frames don't animate at all (even using the user32.dll AnimateWindow function). So if your goal is to get your frames to animate anywhere, you are right, you'll have to do it yourself. JavaFx has some really nice animation stuff that would help with this.




回答2:


Since you want it to be platform independent, my other answer will not work for you. Also, each platform will react differently when you minimize or hide a window. You mentioned it would be nice to see a Java code fragment that would give you a consistent animation. Here's some code for you.

import java.util.Timer;
import java.util.TimerTask;
import javax.swing.JFrame;

public class FadeUtilityClass
{
    private static final int TIME = 200;
    private static final int MILLIS_PER_FRAME = 33;
    private static final float DELTA = MILLIS_PER_FRAME / (float)TIME; //how much the opacity will change on each tick

    /**
     * @param frame the frame to fade in or out
     * @param in true if you are fading in, false if you're fading out
     */
    public static void fade(final JFrame frame, final boolean in)
    {
        frame.setOpacity(in ? 0f : 1f); //if we're fading in, make sure our opacity is 0, and 1 if we're fading out
        if (in) //set the state back to normal because we might have been minimized
            frame.setState(JFrame.NORMAL); 
        final Timer timer = new Timer();
        TimerTask timerTask = new TimerTask()
        {
            float opacity = in ? 0f : 1f;
            float delta = in ? DELTA : -DELTA;

            @Override
            public void run()
            {
                opacity += delta; //tweak the opacity
                if (opacity < 0) //we're invisible now
                {
                    frame.setState(JFrame.ICONIFIED); //hide frame
                    frame.setOpacity(1f); //then make it opaque again, so it'll reappear properly if they click the taskbar 
                    timer.cancel(); //stop the timer
                }
                else if (opacity > 1) //we're fully visible now
                {
                    frame.setOpacity(1f); //make the opacity an even 1.0f
                    timer.cancel(); //stop the timer
                }
                else
                    frame.setOpacity(opacity);
            }
        };
        timer.scheduleAtFixedRate(timerTask, MILLIS_PER_FRAME, MILLIS_PER_FRAME);
    }
}

It's a utility class that will make your undecorated frame fade in or out. Since the location of the taskbar and minimized window changes based on the platform and you would need to use platform specific api's to find that, I just made the animation fade the window out without shrinking it down to where the taskbar might be.

Hope this helps!




回答3:


by calling

myJFrame.setUndecorated( true )

You're disabling any frame decorations for your JFrame. This includes the animations on maximizing and minimizing your JFrame.

If you skip this call or change it to

myJFrame.setUndecorated( false )

then the animations will be visible again, even by minimizing the frame with a call to

myJFrame.setState( Frame.ICONIFIED );

AFAIK, there is no way to animate an undecorated frame. :(

Please find my full code sample here:

    JFrame frame = new JFrame();
    frame.setSize( 800, 600 );
    frame.setUndecorated( false );  // will enable animations
    frame.setVisible( true );
    try { Thread.sleep( 3000 ); } catch ( Throwable t ) {}
    frame.setState( Frame.ICONIFIED );

Greetings

Christopher



来源:https://stackoverflow.com/questions/17761134/jframe-transition-effect-when-called-setstateframe-iconified-it-just-goes-to

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!