3

我在一个容器中有三个组件和其中的按钮。当我点击最小化按钮时,组件被最小化到容器的底部,当我点击最小化的组件时,它被最大化。

假设三个组件位于底部,如果我最大化第二个组件,那么它会被最大化并且第三个最小化的组件不会占据第二个的位置,这仍然是空间。

截屏
在此处输入图像描述

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);
    }
}
4

2 回答 2

2

我已经用 Metal 和 Windows L&F 测试过这个,你可能需要用其他一些测试它。

基本上,当组件无效并doLayout调用方法时,我们会检查是否存在任何JInternalFrame.JDesktopIcon组件。然后我们把它们拿出来,按照我们喜欢的方式布置出来……

public class TestInternalFrame {

    public static void main(String[] args) {
        new TestInternalFrame();
    }

    private int xpos = 0;
    private int ypos = 0;

    public TestInternalFrame() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (Exception exp) {
                    exp.printStackTrace();
                }
                DesktopPane pane = new DesktopPane();
                pane.add(newInternalFrame());
                pane.add(newInternalFrame());
                pane.add(newInternalFrame());

                JFrame frame = new JFrame();
                frame.add(pane);
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setSize(400, 400);
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);

            }
        });
    }

    public JInternalFrame newInternalFrame() {
        JInternalFrame inf = new JInternalFrame("Blah", true, true, true, true);
        inf.setLocation(xpos, ypos);
        inf.setSize(100, 100);
        inf.setVisible(true);

        xpos += 50;
        ypos += 50;

        return inf;
    }

    public class DesktopPane extends JDesktopPane {

        @Override
        public void doLayout() {
            super.doLayout();
            List<Component> icons = new ArrayList<Component>(25);
            for (Component comp : getComponents()) {
                if (comp instanceof JInternalFrame.JDesktopIcon) {
                    icons.add(comp);
                }
            }

            int x = 0;
            for (Component icon : icons) {

                int y = getHeight() - icon.getHeight();
                icon.setLocation(x, y);
                x += icon.getWidth();

            }
        }
    }
}

别搞错了,这是一个粗略的 hack

更新

int x = 0;
for (Component icon : icons) {
    int y = getHeight() - icon.getHeight();
    icon.setLocation(x, y);
    x += icon.getWidth();
    setLayer(icon, 10); // <--- Add me
}

对于您的另一个问题,您只需将图标移动到更高的层。问题在于,您实际上需要找到足够高的层。您可以使用Integer.MAX_VALUE,但这有点苛刻(并且您可能希望在其之上有一些东西),相反,您可以计算最大层并将 +1 放在其之上...

public void doLayout() {
    super.doLayout();
    List<Component> icons = new ArrayList<Component>(25);
    int maxLayer = 0;
    for (Component comp : getComponents()) {
        if (comp instanceof JInternalFrame.JDesktopIcon) {
            icons.add(comp);
            maxLayer = Math.max(getLayer(comp), maxLayer);
        }
    }

    maxLayer++;
    int x = 0;
    for (Component icon : icons) {

        int y = getHeight() - icon.getHeight();
        icon.setLocation(x, y);
        x += icon.getWidth();
        setLayer(icon, maxLayer);

    }
}

你真的需要花时间学习如何使用内部框架如何使用分层窗格,因为(至少最后一部分)在这些......

于 2013-02-15T07:37:50.380 回答
1

像这样的东西:

jdp.setDesktopManager( new DefaultDesktopManager(){
    @Override
    public void deiconifyFrame(JInternalFrame f) {
        super.deiconifyFrame(f);
        JDesktopPane d = f.getDesktopPane();
         JInternalFrame[] frames = d.getAllFrames();
         for(JInternalFrame frame : frames ) {
             Rectangle bounds = getBoundsForIconOf(frame);
              // relayout all frames
         }
    }
});
于 2013-02-15T07:14:07.550 回答