A maximizable dialog with a parent in Swing
Asked Answered
B

1

-1

I'm collaborating on a mature desktop Swing application

A customer wants a dialog that:

  1. Has a maximize button in the corner (I assume, the other standard frame buttons too, minimize and close)
  2. Has a relationship with the "root frame". For example, the root frame shouldn't be minimizable while the dialog is still visible

I reimplemented the dialog, which used to be a JDialog, to be a JFrame subclass. It solved the first problem, but now it's totally oblivious to any root frames at all as JFrames don't have parents

They say adding a maximize button to a JDialog is possible but not a good idea (though, I'm not sure why). The app is used in medical facilities, I don't want to take any chances

How do I meet the customer's expectations?

UPD: Abra suggested calling JDialog.setDefaultLookAndFeelDecorated(true). There are a number of problems with that approach:

  1. Still no maximize button
  2. The look-and-feel will not match the global settings
public class Main {
    public static void main(String[] args) {
        JFrame mainFrame = new JFrame("Main Frame");
        JButton popupButton = new JButton("Open Popup");
        JDialog.setDefaultLookAndFeelDecorated(true);
        popupButton.addActionListener(e -> {
            JDialog popupDialog = new JDialog(mainFrame, "Popup Dialog");
            popupDialog.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            popupDialog.setSize(200, 200);
            popupDialog.setLocationRelativeTo(null);
            popupDialog.setModalityType(Dialog.ModalityType.APPLICATION_MODAL);
            popupDialog.setVisible(true);
        });
        mainFrame.add(popupButton);
        mainFrame.pack();
        mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        mainFrame.setLocationRelativeTo(null);
        mainFrame.setVisible(true);
    }
}

enter image description here

By the way, the "unsafe" option (see the link above) has the same problem

    public static void main(String[] args) {
        JFrame mainFrame = new JFrame("Main Frame");
        JButton popupButton = new JButton("Open Popup");
        //JDialog.setDefaultLookAndFeelDecorated(true);
        popupButton.addActionListener(e -> {
            JDialog popupDialog = new JDialog(mainFrame, "Popup Dialog");
            popupDialog.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            popupDialog.setSize(200, 200);
            popupDialog.setLocationRelativeTo(null);
            popupDialog.setUndecorated(true);
            popupDialog.getRootPane().setWindowDecorationStyle(JRootPane.FRAME);
            popupDialog.setModalityType(Dialog.ModalityType.APPLICATION_MODAL);
            popupDialog.setVisible(true);
        });
        mainFrame.add(popupButton);
        mainFrame.pack();
        mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        mainFrame.setLocationRelativeTo(null);
        mainFrame.setVisible(true);
    }
Bathesda answered 7/5 at 12:5 Comment(10)
I welcome any thoughts in the comment section tooBathesda
@Hylophagous I don't know. It has a form, so perhaps they find it more convenient to edit it full screenBathesda
@Hylophagous I'm not sure how an example would help, franklyBathesda
Did you try setDefaultLookAndFeelDecorated ?Operation
I reimplemented the dialog, which used to be a JDialog, to be a JFrame subclass That's not going to fly, as a JFrame can't be made modal (afaik), which is what you needLuzern
You don't see how an example is useful? As in you can have a small program that runs and demonstrates the problem, and somebody can fix that program specifically. You don't see how that is helpful? "Has a relationship with the "root frame". For example, the root frame shouldn't be minimizable while the dialog is still visible" how can this be an issue if you're working full screen?Hylophagous
@Hylophagous it's not really a debugging question. It's a "how do I do X" question. MREs are applicable to debugging questions. I'll add a small example, but it's mainly to illustrate how Abra's suggestion works (not so well)Bathesda
@Hylophagous "how can this be an issue if you're working full screen?" It should only have the option of being maximized. It should not be full-screen by defaultBathesda
It's odd popupDialog.getRootPane().setWindowDecorationStyle(JRootPane.FRAME); that doesn't work because it seems like it should. How do you feel about hiding all of the decorations and re-drawing them?Hylophagous
This solution might be interesting for you, https://mcmap.net/q/278369/-how-to-make-a-jframe-modal-in-swing-javaHylophagous
E
0

Here's one crude but effective way to maximize a JDialog. I worked off of Abra's example.

I was surprised to find out that JDialog doesn't have a setExtendedState, so I did it manually. The JDialog has a maximize/normal JButton, which changes the size of the JDialog.

Here's the complete runnable code.

import java.awt.BorderLayout;
import java.awt.Dialog;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class MaximizeDialog implements Runnable {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new MaximizeDialog());
    }

    private JDialog popupDialog;

    @Override
    public void run() {
        JFrame mainFrame = new JFrame("Main Frame");
        mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        mainFrame.add(createButtonPanel(mainFrame), BorderLayout.CENTER);

        mainFrame.pack();
        mainFrame.setLocationByPlatform(true);
        mainFrame.setVisible(true);
    }

    private JPanel createButtonPanel(JFrame mainFrame) {
        JPanel panel = new JPanel(new FlowLayout());
        panel.setBorder(BorderFactory.createEmptyBorder(50, 150, 50, 150));

        JButton popupButton = new JButton("Open Popup");
        panel.add(popupButton);

        popupButton.addActionListener(e -> {
            createDialog(mainFrame);
        });

        return panel;
    }

    private void createDialog(JFrame mainFrame) {
        popupDialog = new JDialog(mainFrame, "Popup Dialog");
        popupDialog.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        popupDialog.add(createDialogButtonPanel(), BorderLayout.SOUTH);
        popupDialog.setSize(200, 200);
        popupDialog.setLocationRelativeTo(mainFrame);
        popupDialog.setModalityType(Dialog.ModalityType.APPLICATION_MODAL);
        popupDialog.setVisible(true);
    }

    private JPanel createDialogButtonPanel() {
        JPanel panel = new JPanel(new FlowLayout());
        panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));

        JButton maximizeButton = new JButton("Maximize");
        panel.add(maximizeButton);

        maximizeButton.addActionListener(e -> {
            maximizeDialog(e);
        });

        return panel;
    }

    private void maximizeDialog(ActionEvent event) {
        JButton button = (JButton) event.getSource();
        String text = button.getText();
        if (text.equals("Maximize")) {
            popupDialog.setSize(1000, 1000);
            button.setText("Normal");
        } else {
            popupDialog.setSize(200, 200);
            button.setText("Maximize");
        }
    }

}
Enchilada answered 7/5 at 14:26 Comment(2)
Thank you! Unfortunately, it's not what the customer wants (note the question said "in the corner"). They want a regular maximize button in the top right corner, as it is with regular windowsBathesda
@Powet: Good luck extending JFrame to include the modality of a JDialog. Be sure to publish your results so others may benefit.Enchilada

© 2022 - 2024 — McMap. All rights reserved.