How can I close a JInternalFrame by doubleclicking on the icon in the upper left corner?

Jon Wingfield

The way the Internal Frame title bar responds to events is controlled by the installed LookAndFeel. The BasicLookAndFeel class BasicInternalFrameUI delegates much of this responsibility to BasicInternalFrameTitlePane. This component does not show an Icon when painted but its sub-classes (eg MetalInternalFrameTitlePane) may do so. In other words there is no way to get a reference to the Icon.
The BasicInternalFrameUI uses a protected class BorderListener to respond to mouse clicks in the Title Pane. It is this listener which deIconifies minimized frames and toggles the maximum state of the frame when the title is double-clicked. Due to the interaction between BasicInternalFrameUI and BasicInternalFrameTitlePane the proper solution would be to sub-class both classes to ensure the correct behaviour.
A simpler solution, but one that makes more assumptions about the UI, is to just sub-class the InternalFrameUI. A sub-class of the BasicInternalFrameUI can use a sub-class of BorderListener to close the window for double-clicks in the Icon region:

public class CustomInternalFrameUI extends MetalInternalFrameUI {

    public CustomInternalFrameUI(JInternalFrame b)   {

    public static ComponentUI createUI(JComponent c)    {
        return new CustomInternalFrameUI( (JInternalFrame) c);

    protected MouseInputAdapter createBorderListener(JInternalFrame w) {
        final JInternalFrame f = w;
        // create an anonymous sub-class of BorderListener
        return new BorderListener() {
            public void mouseClicked(MouseEvent e) {
                if(e.getClickCount() > 1 && e.getSource() == getNorthPane()) {
                    // double-click in the title pane
                    Icon ico = f.getFrameIcon(); 
                            && e.getX()<=(ico==null?0:ico.getIconWidth()+5)) {
                        // mouse click in icon region, attempt to close the frame 
                    } else {
                } else {
To use this UI call the following in the constructor of your internal frame.

setUI(new CustomInternalFrameUI(this));

Note: The use of custom UI classes in this way inhibits the pluggability of LookAndFeels. Caution is required, especially if you are allowing the user to switch the LookAndFeel at runtime. To ensure the LAF remains pluggable see The 'LookandFeel' Class Reference