Java Fullscreen Modal Dialogs

2019-07-18 06:30发布

问题:

How does one create a custom modal JDialog that can be used as an internal dialog? For use in FullscreenExclusiveMode.

I have a JScrollPane (with a huge scrollbar) full of huge buttons like so:

+----------------------+------+
|         FOO          |  /\  |
|______________________+------+
|                      |______|
|         BAR          |      |
|______________________|  ==  |
|                      |______|
|         BIZ          |      |
+______________________+------+
|                      |  \/  |
|----------------------+------+

I need the user to use the giant scrollbar to scroll through and tap a particular button to select it and close the dialog. The dialog is in fullscreen exclusive mode. The close button needs to be disabled and it needs to not have okay or cancel buttons, whichever button they click needs to update a value and then call frame.dispose() on the dialog.

Right now I'm using an internal frame but the frame isn't popping up in front of everything else because I'm not using a JDesktop. I've also tried JDialog but it minimizes the app.

JOptionPane.showInternalDialog() works but how do I construct my own internal dialogs in the same fashion so that they can be shown? If I make an internal frame and then add it to a component it just sits within that component and not on top of everything.

EDIT: Looked through those classes and tried the popup factory but the popups don't seem to work reliably in fullscreen.

EDIT: Trying JOptionPane.createInternalFrame() here is the demo I'm working with but it doesn't seem to be working yet.

public class FullscreenDialog {

    public static final void main(final String[] args) throws Exception {
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());//uses os window manager

        JPanel panel = new JPanel();
        panel.setPreferredSize(new Dimension(800,600));

        final JLabel label = new JLabel("Something to say.");
        panel.add(label);
        final JFrame fullscreenFrame = new JFrame();
        fullscreenFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        fullscreenFrame.setUndecorated(true);//To remove the bars around the frame.
        fullscreenFrame.setResizable(false);//resizability causes unsafe operations.
        fullscreenFrame.setContentPane(panel);
        fullscreenFrame.validate();
        GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().setFullScreenWindow(fullscreenFrame);//actually applies the fullscreen.

        final JOptionPane optionPane = new JOptionPane();
        optionPane.add(new JLabel("Some alert"));
        final JButton button = new JButton();
        button.setText("Press me.");
        button.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e) {
                label.setText("worked");
                optionPane.setValue(button);
            }
        });
        JInternalFrame frame  = optionPane.createInternalFrame(panel, "Internal Dialog");
        frame.setVisible(true);
    }
}

回答1:

The message argument to the JOptionPane constructor can be a Component as well as a string, e.g. it could be your JScrollPane.

To remove the standard buttons from the option pane, call setOptions(Object[]) with an empty array.



回答2:

JOptionPane.showXXXDialog(...) allows for a lot of customizations in creating a custom internal dialog.



回答3:

try this..

.
.
.
            final JOptionPane optionPane = new JOptionPane();
            optionPane.add(new JLabel("Some alert"));
            final JButton button = new JButton();
            button.setText("Press me.");
            button.addActionListener(new ActionListener(){
                public void actionPerformed(ActionEvent e) {
                    label.setText("worked");
                    fullscreenFrame.invalidate();
                    fullscreenFrame.repaint();
                    optionPane.setValue(button);
                }
            });
            JInternalFrame frame  = optionPane.createInternalFrame(panel, "Internal Dialog");
            frame.getContentPane().removeAll();
            JPanel pnl = new JPanel(new BorderLayout());
            pnl.add( button, BorderLayout.SOUTH );
            pnl.add( new JScrollBar(), BorderLayout.CENTER );
            frame.getContentPane().add( pnl );
            frame.setVisible(true);