4

I would like to create a JFrame with two specifal features:

  1. JFrame should not grab focus while maximized from minimized state.
  2. When a JFrame created or became maximized from minimized state, it should flash in the Windows bar until a user will grant a focus to it. (like as in ICQ clients alt text).

Does anybody know how the second requirement can be implemented?

Little self-explained example:

import javax.swing.*;
import java.awt.event.*;
import java.awt.*;

public class JFrameTest {
    private static JFrame childFrame;
    public static Container getParentContentPane() {
        JPanel panel = new JPanel();
        JButton button = new JButton("Create\\Restore child frame");
        button.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e) {
                createOrRestoreChildFrame();
            }
        });
        panel.add(button);
        return panel;
    }

    private static void createOrRestoreChildFrame() {
        if (childFrame == null) {
            childFrame = new JFrame("Child Frame");
            childFrame.setLocation(200, 200);
            childFrame.add(new JLabel("Child Frame"));
            childFrame.pack();
            setChildFrameVisible();
        } else {
            setChildFrameVisible();
        }
    }

    private static void setChildFrameVisible() {
        childFrame.setFocusableWindowState(false);
        childFrame.setVisible(true);
        flashInWindowsBar(childFrame);
        childFrame.toFront();
        childFrame.setFocusableWindowState(true);
    }

    /**
     * Should Make child frame flash in Windows bar.
     * Currently, it does not work for me.
     * Could anybody help me to fix this please? ) 
     */
    private static void flashInWindowsBar(JFrame childFrame) {
        childFrame.setState(JFrame.ICONIFIED);
        childFrame.toFront();
    }

    private static void createAndShowGUI() {
        JFrame parentFrame = new JFrame("JFrame Demo");
        parentFrame.setLocation(100, 100);
        parentFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        parentFrame.setContentPane(getParentContentPane());
        parentFrame.pack();
        parentFrame.setVisible(true);
    }

    public static void main(String[] args) {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }
}

Thanks!

Ted
  • 41
  • 1
  • 3

3 Answers3

1

The following code worked for me exactly as you described:

    f.setState(JFrame.ICONIFIED);
    f.toFront();

f is a JFrame.

AlexR
  • 114,158
  • 16
  • 130
  • 208
1

Unfortunately, this isn't something that you can do natively under any Java platform. Anyone who manages to get it working by using the kind of 'trickery' that you've shown, will be disappointed to find that it is unlikely to work on another version of Windows, or even another computer with the same version of Windows. The only times I've ever seen a Java window flash is due to some glitch in Swing when minimizing all windows to the taskbar.

As this article on making Java applications feel native shows, it's the same on Mac OS.

Your best bet is to use the techniques described in the above article to make a JNI which does the Windows API call, or get a license for JNIWrapper (search for it) which does it all for you (best option if you are making a commercial app, or making it for a client who is willing to pay for such a feature). It looks like you can get a 30-day trial for that.

The only other thing I could suggest is create a poor-man's equivalent of a pop-up notification system. When you want to alert the user, create a Frame without a border, put it in the bottom-right corner of the screen, make it non-focusable and show it for a brief period of time.

BoffinBrain
  • 6,337
  • 6
  • 33
  • 59
1

The JPanel does not flash. Try it instead of JFrame.