I need the iconable/minimize feature of JInternalFrame to collapse the frame (which it does), but also maintain the JInternalFrame's position within its parent component. Currently, when I press the minimize button of a JInternalFrame, java places the component at the bottom of its container. Is there a way to maintain the location whilst minimizing? If there is no obvious solution, how might I observe the iconable icon and remove the default listener? Thank you.
To modify this behavior you would want to create an implementation of javax.swing.DesktopManager
. To get the majority of the default behavior already available I'd suggest subclassing javax.swing.DefaultDesktopManager
.
In DefaultDesktopManager the method iconifyFrame(JInternalFrame f)
controls the complete behavior but internally uses the method protected Rectangle getBoundsForIconOf(JInternalFrame f)
to determine the bounds for the icon of the frame being minimized. Here you can return the bounds for the icon of the internal frame that you'd like to use. The problem is those values are cached so if you want it to move every time you would need to do something like the following.
import javax.swing.DefaultDesktopManager;
import javax.swing.DesktopManager;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.SwingUtilities;
import java.awt.BorderLayout;
import java.awt.Dimension;
public class CustomDesktopManager extends DefaultDesktopManager {
@Override
public void iconifyFrame(JInternalFrame f) {
super.iconifyFrame(f);
JInternalFrame.JDesktopIcon icon = f.getDesktopIcon();
Dimension prefSize = icon.getPreferredSize();
icon.setBounds(f.getX(), f.getY(), prefSize.width, prefSize.height);
}
public static void main(String args[]) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JDesktopPane desktopPane = new JDesktopPane();
DesktopManager dm = new CustomDesktopManager();
desktopPane.setDesktopManager(dm);
JInternalFrame internalFrame = new JInternalFrame("Test Internal Frame", true, false, true, true);
internalFrame.setSize(200, 150);
internalFrame.setVisible(true);
desktopPane.add(internalFrame);
frame.add(desktopPane, BorderLayout.CENTER);
frame.setSize(800, 600);
frame.setVisible(true);
}
});
}
}