Максимизация JInternalFrame Windows Look and Feel максимизирует все JInternalFrame

В SSCCE ниже, вы можете увидеть, что если вы максимизируете один из JInternalFrameс, то это максимизирует их обоих. Это только (AFAIK) происходит с "Windows" LookAndFeel (если вы опустите LookAndFeel код, работает как положено).

Воспроизвести:

  1. Запустите SSCCE ниже.
  2. Максимизировать один из JInternalFrames.
  3. Закройте (X) тот, который вы максимизировали
  4. Заметьте, что другой был максимизирован.

Есть ли способ остановить это поведение? Это ошибка?

SSCCE:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JLabel;
import javax.swing.SwingConstants;

class Test2 {
    public static void main(String[] args) {
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Windows".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | javax.swing.UnsupportedLookAndFeelException e) {
            e.printStackTrace();
        }
        JFrame frame = new JFrame();
        JDesktopPane jdp = new JDesktopPane();
        jdp.setBackground(Color.gray);
        frame.add(jdp);
        jdp.setVisible(true);
        frame.setExtendedState(frame.getExtendedState()|JFrame.MAXIMIZED_BOTH );
        frame.setVisible(true);

        JInternalFrame jiffy1 = new JInternalFrame("Jiffy1", true, true, true, true);
        jdp.add(jiffy1);
        JLabel jiffy1_label = new JLabel("Jiffy1");
        jiffy1_label.setHorizontalAlignment(SwingConstants.CENTER);
        jiffy1_label.setFont(new Font("Tahoma", 0, 50));
        jiffy1.add(jiffy1_label);
        jiffy1.setPreferredSize(new Dimension(300,300));
        jiffy1.setVisible(true);
        jiffy1.pack();
        centerJIF(jdp, jiffy1);

        JInternalFrame jiffy2 = new JInternalFrame("Jiffy2", true, true, true, true);
        jdp.add(jiffy2);
        JLabel jiffy2_label = new JLabel("Jiffy2");
        jiffy2_label.setHorizontalAlignment(SwingConstants.CENTER);
        jiffy2_label.setFont(new Font("Tahoma", 0, 50));
        jiffy2.add(jiffy2_label);
        jiffy2.setPreferredSize(new Dimension(200,200));
        jiffy2.setVisible(true);
        jiffy2.pack();
        centerJIF(jdp, jiffy2);

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    private static void centerJIF(JDesktopPane jdp, JInternalFrame jiffy) {
        Dimension desktopSize = jdp.getSize();
        Dimension VInternalFrameSize = jiffy.getSize();
        int width = (desktopSize.width - VInternalFrameSize.width) / 2;
        int height = (desktopSize.height - VInternalFrameSize.height) / 2;
        jiffy.setLocation(width, height);
    }
}

1 ответ

Решение

В Windows DesktopManager есть функция (на мой взгляд, ошибка...), которая максимизирует все кадры, когда вы максимизируете один кадр.

из WindowsDesktopManager.java (Java 7) из строки 62

... 
public void activateFrame(JInternalFrame f) {
    JInternalFrame currentFrame = currentFrameRef != null ? 
        currentFrameRef.get() : null;
    try {
        super.activateFrame(f);
        if (currentFrame != null && f != currentFrame) {
            // If the current frame is maximized, transfer that 
            // attribute to the frame being activated.
            if (currentFrame.isMaximum() &&
        (f.getClientProperty("JInternalFrame.frameType") !=
        "optionDialog") ) {
                //Special case.  If key binding was used to select next
                //frame instead of minimizing the icon via the minimize
                //icon.
                if (!currentFrame.isIcon()) {
                    currentFrame.setMaximum(false);
                    if (f.isMaximizable()) {
                        if (!f.isMaximum()) {
                            f.setMaximum(true);
                        } else if (f.isMaximum() && f.isIcon()) {
                            f.setIcon(false);
                        } else {
                            f.setMaximum(false);
                        }
                    }
                }
            }
            if (currentFrame.isSelected()) {
                currentFrame.setSelected(false);
            }
        }

        if (!f.isSelected()) {
            f.setSelected(true);
        }
    } catch (PropertyVetoException e) {}
    if (f != currentFrame) {
        currentFrameRef = new WeakReference(f);
    }
}
...

так что вы можете переустановить DefaultDesktopManager вместо WindowsDesktopManager и решить проблему:

JDesktopPane jdp = new JDesktopPane();
jdp.setDesktopManager(new DefaultDesktopManager());
Другие вопросы по тегам