Modal JDialog without execution lock

Is there a way to use the dialogue in Swing that prohibits any gui activity under it, but at the same time DOES NOT stop execution in the thread where it was set to visible?

+4
source share
4 answers

Yes, it can be done.

dlg.setModal(false);

or

dlg.setModalityType(Dialog.ModalityType.MODELESS);

where dlg is an instance of your JDialog.

+5
source

JDialog IS , . - , , . , JDialog, .

+1

, . MadProgrammer , Swing EDT, JDialogs, , , ( , EDT, ).

, . , SwingUtilities.invokeLater(Runnable) (doc).

import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JProgressBar;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

public class BlockingDialogDemo extends JFrame {

    private Timer timer;
    private JDialog blocker;

    public BlockingDialogDemo() {
        setTitle("Blocking Dialog");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(300, 200);
        setLocationRelativeTo(null);

        blocker = new JDialog(this, true);
        blocker.setLayout(new FlowLayout());
        blocker.setUndecorated(true);
        blocker.getRootPane().setBorder(BorderFactory.createMatteBorder(1, 1, 1, 1, Color.black));
        blocker.add(new JLabel("I'm blocking EDT!"));    
        JProgressBar progress = new JProgressBar();
        progress.setIndeterminate(true);
        blocker.add(progress);
        blocker.pack();

        timer = new Timer(3000, new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                doSomeWork();
            }
        });
        timer.setRepeats(false);
        timer.start();
    }

    private void doSomeWork() {
        // this executes on-EDT
        Runnable runnable = new Runnable() {

            public void run() {
                // this executes off-EDT - never ever access Swing components here
                showBlocker();
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException ex) {
                    System.out.println("Ummm.. I was sleeping here!");
                } finally {                
                    hideBlocker();
                }
            }
        };
        new Thread(runnable).start();
    }

    private void showBlocker() {
        // this executes off-EDT                
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                // this executes on-EDT
                blocker.setLocationRelativeTo(BlockingDialogDemo.this);
                blocker.setVisible(true);
            }
        });
    }

    private void hideBlocker() {
        // this executes off-EDT
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                // this executes on-EDT
                blocker.setVisible(false);
                timer.restart();
            }
        });
    }

    public static void main(String[] args) {
        // this is called off-EDT
        SwingUtilities.invokeLater(new Runnable() {

            public void run() {
                // this is called on-EDT
                new BlockingDialogDemo().setVisible(true);
            }
        });
    }

}
+1

... :

public class NonBlockingModalDialogDemo extends JFrame{

    JButton btnDoIt;

    public NonBlockingModalDialogDemo() {
        setTitle("NonBlockingModalDialog Demo");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(300,300);
        setLayout(new FlowLayout());

        btnDoIt = new JButton("Non-Blocking Notify");
        btnDoIt.addActionListener( new ActionListener(){
            @Override
            public void actionPerformed(ActionEvent arg0) {
                JDialog asyncDialog = createNonBlockingModalDialog("Please wait while we do some work", "Please wait");

                doWork(50);
                //Once your done, just dispose the dialog to allow access to GUI
                asyncDialog.dispose();
            }

        });

        this.add(btnDoIt);
    }

    private JDialog createNonBlockingModalDialog(String message, String title)
    {
        final JDialog dialog = new JDialog();
        dialog.setLayout(new FlowLayout());
        dialog.add(new JLabel(message));
        dialog.setTitle(title);
        dialog.setModal(true);
        dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
        dialog.setAlwaysOnTop(true);
        dialog.pack();

        Runnable dialogDisplayThread = new Runnable() {
            public void run() {
                dialog.setVisible(true);
            }};

        new Thread(dialogDisplayThread).start();

        //Need to wait until dialog is fully visible and then paint it
        //or else it doesn't show up right
        while(!dialog.isVisible()){/*Busy wait*/}
        dialog.paint(dialog.getGraphics());

        return dialog;
    }

    private void doWork(int amount) {
        for(int i = 0; i < amount; i++)
        {
            System.out.println("Doing work step number " + i);
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {}
        }

        System.out.println("done");
    }

    public static void main(String[] args) {
        new NonBlockingModalDialogDemo().setVisible(true);
    }
}

, , , , . , , .

: - , - , , , , .

, , , " ", -.

Perhaps instead of trying to continue the work you need to do on the EDT, perhaps you should try something like this: fooobar.com/questions/1060541 / ... which uses SwingWorker to create a new thread, and then allows you update the GUI components when you are done.

-1
source

Source: https://habr.com/ru/post/1543051/


All Articles