66
77import java .awt .Color ;
88import java .awt .Cursor ;
9+ import java .lang .reflect .InvocationTargetException ;
910import java .util .Collections ;
1011import java .util .HashMap ;
1112import java .util .List ;
1213import java .util .Map ;
13- import java .util .Set ;
14+ import java .util .concurrent . atomic . AtomicBoolean ;
1415
1516import javax .swing .ImageIcon ;
17+ import javax .swing .SwingUtilities ;
1618import javax .swing .SwingWorker ;
1719
1820import org .apache .commons .lang3 .StringUtils ;
21+ import org .apache .logging .log4j .LogManager ;
22+ import org .apache .logging .log4j .Logger ;
1923
2024import com .mirth .connect .client .core .Client ;
2125import com .mirth .connect .client .core .ClientException ;
2630import com .mirth .connect .model .LoginStatus ;
2731import com .mirth .connect .plugins .MultiFactorAuthenticationClientPlugin ;
2832
29- public class DefaultLoginPanel extends AbstractLoginPanel {
33+ class DefaultLoginPanel extends javax . swing . JFrame implements LoginPanel {
3034
35+ private static final Logger logger = LogManager .getLogger (DefaultLoginPanel .class );
3136 private static final String ERROR_MESSAGE = "There was an error connecting to the server at the specified address. Please verify that the server is up and running." ;
3237
33- public DefaultLoginPanel () {
38+ private LoginSuccessHandler onSuccess ;
39+
40+ DefaultLoginPanel () {
3441 initComponents ();
3542 DisplayUtil .setResizable (this , false );
3643 jLabel2 .setForeground (UIConstants .HEADER_TITLE_TEXT_COLOR );
@@ -69,12 +76,21 @@ public void mouseClicked(java.awt.event.MouseEvent evt) {
6976 }
7077
7178 @ Override
72- public void initialize (String mirthServer , String version , String user , String pass ) {
79+ public void initialize (String mirthServer , String version , String user , String pass , LoginSuccessHandler onSuccess ) {
80+ if (SwingUtilities .isEventDispatchThread ()) {
81+ doInitialize (mirthServer , version , user , pass , onSuccess );
82+ } else {
83+ SwingUtilities .invokeLater (() -> doInitialize (mirthServer , version , user , pass , onSuccess ));
84+ }
85+ }
86+
87+ private void doInitialize (String mirthServer , String version , String user , String pass , LoginSuccessHandler onSuccess ) {
7388 synchronized (this ) {
7489 // Do not initialize another login window if one is already visible
7590 if (isVisible ()) {
7691 return ;
7792 }
93+ this .onSuccess = onSuccess ;
7894
7995 setTitle (String .format ("%s %s - Login" , BrandingConstants .PRODUCT_NAME , version ));
8096 setIconImage (BrandingConstants .FAVICON .getImage ());
@@ -392,7 +408,7 @@ private void passwordActionPerformed(java.awt.event.ActionEvent evt)// GEN-FIRST
392408 private void loginButtonActionPerformed (java .awt .event .ActionEvent evt )// GEN-FIRST:event_loginButtonActionPerformed
393409 {// GEN-HEADEREND:event_loginButtonActionPerformed
394410 errorPane .setVisible (false );
395- LoginPanel loginPanel = this ;
411+ DefaultLoginPanel loginPanel = this ;
396412
397413 SwingWorker <Void , Void > worker = new SwingWorker <Void , Void >() {
398414
@@ -425,9 +441,9 @@ public Void doInBackground() {
425441
426442 // If SUCCESS or SUCCESS_GRACE_PERIOD
427443 if (loginStatus != null && loginStatus .isSuccess ()) {
428- if (!Mirth . handleLoginSuccess (client , loginStatus , username .getText ())) {
444+ if (!onSuccess . handle (client , loginStatus , username .getText ())) {
429445 loginPanel .setVisible (false );
430- loginPanel .initialize (PlatformUI .SERVER_URL , PlatformUI .CLIENT_VERSION , "" , "" );
446+ loginPanel .initialize (PlatformUI .SERVER_URL , PlatformUI .CLIENT_VERSION , "" , "" , onSuccess );
431447 }
432448 } else {
433449 // Assume failure unless overridden by a plugin
@@ -444,9 +460,9 @@ public Void doInBackground() {
444460
445461 if (loginStatus != null && loginStatus .isSuccess ()) {
446462 errorOccurred = false ;
447- if (!Mirth . handleLoginSuccess (client , loginStatus , username .getText ())) {
463+ if (!onSuccess . handle (client , loginStatus , username .getText ())) {
448464 loginPanel .setVisible (false );
449- loginPanel .initialize (PlatformUI .SERVER_URL , PlatformUI .CLIENT_VERSION , "" , "" );
465+ loginPanel .initialize (PlatformUI .SERVER_URL , PlatformUI .CLIENT_VERSION , "" , "" , onSuccess );
450466 }
451467 }
452468 }
@@ -487,18 +503,48 @@ private void closeButtonActionPerformed(java.awt.event.ActionEvent evt)// GEN-FI
487503 System .exit (0 );
488504 }// GEN-LAST:event_closeButtonActionPerformed
489505
506+ @ Override
507+ public void setVisible (boolean visible ) {
508+ if (SwingUtilities .isEventDispatchThread ()) {
509+ super .setVisible (visible );
510+ } else {
511+ SwingUtilities .invokeLater (() -> super .setVisible (visible ));
512+ }
513+ }
514+
490515 @ Override
491516 public void setStatus (String status ) {
492- this .status .setText ("Please wait: " + status );
517+ SwingUtilities . invokeLater (() -> this .status .setText ("Please wait: " + status ) );
493518 }
494519
495- public void setError (String status ) {
496- errorTextArea .setText (status );
497- errorPane .setVisible (true );
498- loggingIn .setVisible (false );
499- loginMain .setVisible (true );
500- loginProgress .setIndeterminate (false );
501- password .grabFocus ();
520+ private void setError (String status ) {
521+ SwingUtilities .invokeLater (() -> {
522+ errorTextArea .setText (status );
523+ errorPane .setVisible (true );
524+ loggingIn .setVisible (false );
525+ loginMain .setVisible (true );
526+ loginProgress .setIndeterminate (false );
527+ password .grabFocus ();
528+ });
529+ }
530+
531+ @ Override
532+ public boolean showLoginNotification (String title , String message ) {
533+ // Called from a background thread (SwingWorker.doInBackground via handleLoginSuccess).
534+ // Swing dialogs must be created and shown on the EDT to avoid deadlocks.
535+ final AtomicBoolean accepted = new AtomicBoolean (false );
536+ try {
537+ SwingUtilities .invokeAndWait (() -> {
538+ CustomBannerPanelDialog dialog = new CustomBannerPanelDialog (this , title , message );
539+ accepted .set (dialog .isAccepted ());
540+ });
541+ } catch (InterruptedException e ) {
542+ logger .warn ("Login notification dialog interrupted; treating as declined" );
543+ Thread .currentThread ().interrupt ();
544+ } catch (InvocationTargetException e ) {
545+ throw new RuntimeException (e .getCause ());
546+ }
547+ return accepted .get ();
502548 }
503549
504550 // Variables declaration - do not modify//GEN-BEGIN:variables
0 commit comments