javaswingjinternalframe

How to iconify a internal frame inside a container to a specific position


i want to iconify my internal frame to an adjacent panel of the main frame than the default left bottom corner of the main frame.

i am using a jdesktopframe and inside it internal frames.

https://i.sstatic.net/S5xi5.jpg

i want to iconify the connection detail which is an interal frame the iconified icon should be present where the minimize button is and should not be at the left bottom of the main frame.

this is a sample code:

import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.HeadlessException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyVetoException;
import javax.swing.JButton;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.plaf.basic.BasicInternalFrameTitlePane;
import javax.swing.plaf.basic.BasicInternalFrameUI;


public class MinPanel {

    public MinPanel() throws HeadlessException, PropertyVetoException {
        createAndShowGUI();
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    new MinPanel();
                } catch (HeadlessException ex) {
                } catch (PropertyVetoException ex) {
                }

            }
        });
    }

    private void createAndShowGUI() throws HeadlessException, PropertyVetoException {
        JFrame frame = new JFrame();
        frame.setResizable(true);
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

        final JDesktopPane jdp = new JDesktopPane() {
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(400, 200);
            }
        };

        frame.setContentPane(jdp);
        frame.pack();

        createAndAddInternalFrame(jdp, 0, 0);
        createAndAddfixedpanel(jdp,200,0);

        frame.setVisible(true);
    }

    private void createAndAddInternalFrame(final JDesktopPane jdp, int x, int y) throws PropertyVetoException {
        final JInternalFrame jInternalFrame = new JInternalFrame("Test1", false, false, false, false);
        jInternalFrame.setLocation(x, y);

        jInternalFrame.setLayout(new GridLayout(2, 2));
        jInternalFrame.setSize(200, 200);//testing
        JButton jb = new JButton("min");
        jInternalFrame.add(jb);
        jb.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent ae) {
                try {
                    jInternalFrame.setIcon(true);
                } catch (PropertyVetoException ex) {
                }

            }
        });
       BasicInternalFrameTitlePane titlePane = (BasicInternalFrameTitlePane) ((BasicInternalFrameUI) jInternalFrame.getUI()).getNorthPane();
      jInternalFrame.remove(titlePane);


        jInternalFrame.setVisible(true);
        jdp.add(jInternalFrame);
    }
     private void createAndAddfixedpanel(final JDesktopPane jdp, int x, int y)
     { JPanel panel = new JPanel();
      panel.setLocation(x, y);
        panel.setLayout(new FlowLayout());  
         panel.setSize(200, 200);
        JLabel label = new JLabel("JFrame By Example");  
        JButton button = new JButton();  
        button.setText("Button");  
        panel.add(label);  
        panel.add(button);  

         panel.setVisible(true);
     jdp.add(panel);  

     }
}

I would also like to resize the main frame when the internal frame is minimizes and maximized


Solution

  • The trick is that you don't do the setLocation() or setBounds() stuff on the JInternalFrame object. This would move the pane, which is not be visible anymore when you "iconified" the internal frame. But instead you change the Icon which is now visible when you "iconified" the internal frame. To get the icon you use the getDesktopIcon() method on the JInternalFrame class. After that it's a simple call to the setLocation() call on the received JInternalFrame.JDesktopIcon object. You can use it like this:

    frame.addInternalFrameListener(new InternalFrameAdapter() {
        @Override
        public void internalFrameIconified(InternalFrameEvent e) {
            frame.getDesktopIcon().setLocation(frame.getLocation().x, frame.getLocation().y);
        }
    });
    

    Obviously you have to calculate the correct position for yourself, where you want to have the icon positioned. This example only shows how to move the icon to the correct position, so it doesn't get opened in the bottom left corner.

    You might want to add a similar event handler for the opposite internalFrameDeiconified event to open the original JInternalFrame panel where the icon is, not where the panel was before it was "iconified".