I have three components in a container and buttons in it. When I hit the minimize button the components gets minimized to the bottom of the container and when I hit the minimized component then it gets maximized.
Suppose three components are lying at the bottom and if I maximize the 2nd component then it gets maximized and the 3rd minimized component does not take the position of the 2nd and this remains as space.
package Project;
import java.awt.Dimension;
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 Test2 {
public Test2() throws HeadlessException, PropertyVetoException {
createAndShowGUI();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
try {
new Test2();
} catch (HeadlessException ex) {
ex.printStackTrace();
} catch (PropertyVetoException ex) {
ex.printStackTrace();
}
}
});
}
private void createAndShowGUI() throws HeadlessException, PropertyVetoException {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
final JDesktopPane jdp = new JDesktopPane() {
@Override
public Dimension getPreferredSize() {
return new Dimension(600, 400);
}
};
frame.setContentPane(jdp);
frame.pack();
createAndAddInternalFrame(jdp, 0, 0);
createAndAddInternalFrame(jdp, 300, 0);
createAndAddInternalFrame(jdp, 1, 200);
frame.setVisible(true);
}
private void createAndAddInternalFrame(final JDesktopPane jdp, int x, int y) throws PropertyVetoException {
final JInternalFrame jInternalFrame = new JInternalFrame("", true, true, true, true);
jInternalFrame.setLocation(x, y);
JPanel jp = new JPanel();
JLabel jl=new JLabel("panel"+x);
JButton jb = new JButton("_");
JButton jb2 = new JButton("[]");
JButton jb3 = new JButton("X");
jInternalFrame.setLayout(new GridLayout(2, 2));
jp.add(jl);
jp.add(jb);
jp.add(jb2);
jp.add(jb3);
jInternalFrame.add(jp);
jb.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
try {
if (jInternalFrame.getLayer() == JDesktopPane.FRAME_CONTENT_LAYER) {
jdp.remove(jInternalFrame);
jdp.add(jInternalFrame, JDesktopPane.DEFAULT_LAYER);
jdp.revalidate();
jdp.repaint();
}
jInternalFrame.pack();
jInternalFrame.setIcon(true);
} catch (PropertyVetoException ex) {
ex.printStackTrace();
}
}
});
jb2.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
try {
if (jInternalFrame.isMaximum()) {//restore
jInternalFrame.pack();
} else {//maximize
jInternalFrame.setMaximum(true);
}
jdp.remove(jInternalFrame);
jdp.add(jInternalFrame, JDesktopPane.FRAME_CONTENT_LAYER);
jdp.revalidate();
jdp.repaint();
} catch (Exception e) {
e.printStackTrace();
}
}
});
jb3.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
try {
jInternalFrame.dispose();
} catch (Exception ex) {
ex.printStackTrace();
}
}
});
BasicInternalFrameTitlePane titlePane = (BasicInternalFrameTitlePane) ((BasicInternalFrameUI) jInternalFrame.getUI()).getNorthPane();
jInternalFrame.remove(titlePane);
jInternalFrame.pack();
jInternalFrame.setVisible(true);
jdp.repaint();
jdp.add(jInternalFrame);
}
}
Something like that:
I've tested this with Metal and Windows L&F, you might need to test it with some others.
Basically, when the component is invalidated and the
doLayout
method is called, we check for the existence of anyJInternalFrame.JDesktopIcon
components. We then take these and layout them out as we like...Make no mistake, this is a rough hack
Updated
To your other problem, you simply need to move the icon to a higher layer. The problem with this, is you actually need to find a layer high enough. You could use
Integer.MAX_VALUE
, but that's a little harsh (and you might want something over the top of the that), instead, you could calculate the maximum layer and sit +1 ontop of that...You really need to take the the time to study How to use Internal Frames and How to use Layered Panes as (at least the last part) is covered in these...