package jalview.gui;
+import java.awt.AWTEvent;
+import java.awt.ActiveEvent;
import java.awt.Component;
+import java.awt.Container;
import java.awt.Dialog.ModalityType;
+import java.awt.EventQueue;
import java.awt.HeadlessException;
+import java.awt.MenuComponent;
+import java.awt.Toolkit;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseMotionAdapter;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JInternalFrame;
+import javax.swing.JLayeredPane;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.UIManager;
+import javax.swing.event.InternalFrameEvent;
+import javax.swing.event.InternalFrameListener;
+import jalview.util.ChannelProperties;
import jalview.util.Platform;
import jalview.util.dialogrunner.DialogRunnerI;
public JvOptionPane(final Component parent)
{
this.parentComponent = Platform.isJS() ? this : parent;
+ this.setIcon(null);
}
public static int showConfirmDialog(Component parentComponent,
ArrayList<JButton> options_btns = new ArrayList<>();
Object initialValue_btn = null;
- if (!Platform.isJS()) // JalviewJS already uses callback, don't need to add them here
+ if (!Platform.isJS()) // JalviewJS already uses callback, don't need to
+ // add them here
{
for (int i = 0; i < options.length && i < 3; i++)
{
Platform.isJS() ? initialValue : initialValue_btn);
JDialog dialog = joptionpane.createDialog(parentComponent, title);
+ dialog.setIconImages(ChannelProperties.getIconList());
dialog.setModalityType(modal ? ModalityType.APPLICATION_MODAL
: ModalityType.MODELESS);
dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
handleResponse(getMockResponse());
}
+ // need to set these separately so we can set the title bar icon later
+ this.setOptionType(yesNoCancelOption);
+ this.setMessageType(questionMessage);
+ this.setIcon(icon);
+ this.setInitialValue(initresponse);
+ this.setOptions(options);
+ this.setMessage(mainPanel);
+
ourOptions = Arrays.asList(options);
- int response;
if (parentComponent != this)
{
- response = JOptionPane.showInternalOptionDialog(parentComponent,
- mainPanel, title, yesNoCancelOption, questionMessage, icon,
- options, initresponse);
+ JInternalFrame jif = this.createInternalFrame(parentComponent, title);
+ jif.setFrameIcon(null);
+ jif.addInternalFrameListener(new InternalFrameListener()
+ {
+ @Override
+ public void internalFrameActivated(InternalFrameEvent arg0)
+ {
+ }
+
+ @Override
+ public void internalFrameClosed(InternalFrameEvent arg0)
+ {
+ JvOptionPane.this.internalDialogHandleResponse();
+ }
+
+ @Override
+ public void internalFrameClosing(InternalFrameEvent arg0)
+ {
+ }
+
+ @Override
+ public void internalFrameDeactivated(InternalFrameEvent arg0)
+ {
+ }
+
+ @Override
+ public void internalFrameDeiconified(InternalFrameEvent arg0)
+ {
+ }
+
+ @Override
+ public void internalFrameIconified(InternalFrameEvent arg0)
+ {
+ }
+
+ @Override
+ public void internalFrameOpened(InternalFrameEvent arg0)
+ {
+ }
+ });
+ jif.setVisible(true);
+ startModal(jif);
+ return;
}
else
{
- response = JOptionPane.showOptionDialog(parentComponent, mainPanel,
- title, yesNoCancelOption, questionMessage, icon, options,
- initresponse);
+ JDialog dialog = this.createDialog(parentComponent, title);
+ dialog.setIconImages(ChannelProperties.getIconList());
+ dialog.setVisible(true); // blocking
+ this.internalDialogHandleResponse();
+ return;
}
+ }
+
+ private void internalDialogHandleResponse()
+ {
+ String responseString = (String) this.getValue();
+ int response = ourOptions.indexOf(responseString);
+
if (!Platform.isJS())
/**
* Java only
parentComponent.requestFocus();
}
}
+
+ /**
+ * This helper method makes the JInternalFrame wait until it is notified by an
+ * InternalFrameClosing event. This method also adds the given JOptionPane to
+ * the JInternalFrame and sizes it according to the JInternalFrame's preferred
+ * size.
+ *
+ * @param f
+ * The JInternalFrame to make modal.
+ */
+ private static void startModal(JInternalFrame f)
+ {
+ // We need to add an additional glasspane-like component directly
+ // below the frame, which intercepts all mouse events that are not
+ // directed at the frame itself.
+ JPanel modalInterceptor = new JPanel();
+ modalInterceptor.setOpaque(false);
+ JLayeredPane lp = JLayeredPane.getLayeredPaneAbove(f);
+ lp.setLayer(modalInterceptor, JLayeredPane.MODAL_LAYER.intValue());
+ modalInterceptor.setBounds(0, 0, lp.getWidth(), lp.getHeight());
+ modalInterceptor.addMouseListener(new MouseAdapter()
+ {
+ });
+ modalInterceptor.addMouseMotionListener(new MouseMotionAdapter()
+ {
+ });
+ lp.add(modalInterceptor);
+ f.toFront();
+
+ // We need to explicitly dispatch events when we are blocking the event
+ // dispatch thread.
+ EventQueue queue = Toolkit.getDefaultToolkit().getSystemEventQueue();
+ try
+ {
+ while (!f.isClosed())
+ {
+ if (EventQueue.isDispatchThread())
+ {
+ // The getNextEventMethod() issues wait() when no
+ // event is available, so we don't need do explicitly wait().
+ AWTEvent ev = queue.getNextEvent();
+ // This mimics EventQueue.dispatchEvent(). We can't use
+ // EventQueue.dispatchEvent() directly, because it is
+ // protected, unfortunately.
+ if (ev instanceof ActiveEvent)
+ ((ActiveEvent) ev).dispatch();
+ else if (ev.getSource() instanceof Component)
+ ((Component) ev.getSource()).dispatchEvent(ev);
+ else if (ev.getSource() instanceof MenuComponent)
+ ((MenuComponent) ev.getSource()).dispatchEvent(ev);
+ // Other events are ignored as per spec in
+ // EventQueue.dispatchEvent
+ }
+ else
+ {
+ // Give other threads a chance to become active.
+ Thread.yield();
+ }
+ }
+ } catch (InterruptedException ex)
+ {
+ // If we get interrupted, then leave the modal state.
+ } finally
+ {
+ // Clean up the modal interceptor.
+ lp.remove(modalInterceptor);
+
+ // Remove the internal frame from its parent, so it is no longer
+ // lurking around and clogging memory.
+ Container parent = f.getParent();
+ if (parent != null)
+ parent.remove(f);
+ }
+ }
}