4646import javax .swing .JLabel ;
4747import javax .swing .JOptionPane ;
4848import javax .swing .JProgressBar ;
49+ import javax .swing .UIManager ;
4950import javax .swing .WindowConstants ;
5051import java .awt .Dimension ;
5152import java .awt .GridBagConstraints ;
7677import java .util .concurrent .CompletableFuture ;
7778import java .util .concurrent .ConcurrentHashMap ;
7879import java .util .concurrent .ExecutorService ;
79- import java .util .concurrent .Executors ;
80+ import java .util .concurrent .LinkedBlockingDeque ;
81+ import java .util .concurrent .ThreadPoolExecutor ;
82+ import java .util .concurrent .TimeUnit ;
8083import java .util .concurrent .atomic .AtomicBoolean ;
84+ import java .util .concurrent .atomic .AtomicInteger ;
8185import java .util .concurrent .atomic .AtomicLong ;
8286import java .util .function .Consumer ;
8387import java .util .jar .JarFile ;
@@ -102,11 +106,10 @@ public class DependencyLoaderImpl {
102106 private static final Set <String > localMavenRepositories = new ConcurrentSet <>();
103107 public static final Logger LOG = LogManager .getLogger ("FalsePatternLib DepLoader" );
104108
105- private static final AtomicLong counter = new AtomicLong (0 );
106- private static final ExecutorService executor = Executors .newCachedThreadPool (r -> {
109+ private static final ExecutorService executor = new ThreadPoolExecutor (0 , 4 , 60L , TimeUnit .SECONDS , new LinkedBlockingDeque <>(), r -> {
107110 val thread = new Thread (r );
108111 thread .setDaemon (true );
109- thread .setName ("Dependency Download Thread " + counter . incrementAndGet () );
112+ thread .setName ("Dependency Download Thread" );
110113 return thread ;
111114 });
112115 private static final Path libDir ;
@@ -752,30 +755,38 @@ static ScopeSide current() {
752755 LOG .info ("-----------------------------------------------------------" );
753756 }
754757 JFrame theFrame = null ;
755- val progresses = new HashMap <DependencyLoadTask , JProgressBar >();
758+ JProgressBar bar = null ;
759+ JProgressBar subBar = null ;
756760 if (silent ) {
757761
758762 } else if (SystemUtils .IS_OS_MAC ) {
759763 LOG .info ("MacOS detected, not creating progress window (your OS is buggy)" );
760764 } else {
761765 try {
766+ try {
767+ UIManager .setLookAndFeel (UIManager .getSystemLookAndFeelClassName ());
768+ } catch (Throwable ignored ) {}
762769 val jFrame = new JFrame ("Dependency Download" );
763770 val constraints = new GridBagConstraints ();
764771 jFrame .getContentPane ().setLayout (new GridBagLayout ());
765772 constraints .gridy = 0 ;
766- constraints .gridwidth = 2 ;
767- jFrame .add (new JLabel ("FalsePatternLib is downloading dependencies, please wait!" ), constraints );
773+ constraints .gridx = 0 ;
768774 constraints .gridwidth = 1 ;
769- for (val artifact : artifactMap .entrySet ()) {
770- constraints .gridy ++;
771- jFrame .add (new JLabel (artifact .getKey ()), constraints );
772- val status = new JProgressBar ();
773- status .setIndeterminate (true );
774- status .setStringPainted (true );
775- status .setString ("Waiting..." );
776- progresses .put (artifact .getValue (), status );
777- jFrame .add (status , constraints );
778- }
775+ constraints .gridheight = 1 ;
776+ constraints .fill = GridBagConstraints .HORIZONTAL ;
777+ jFrame .add (new JLabel ("Downloading additional jar files required by the modpack, please wait..." ), constraints );
778+ constraints .gridy ++;
779+ bar = new JProgressBar ();
780+ bar .setIndeterminate (true );
781+ bar .setStringPainted (true );
782+ bar .setString ("Waiting..." );
783+ jFrame .add (bar , constraints );
784+ constraints .gridy ++;
785+ subBar = new JProgressBar ();
786+ subBar .setIndeterminate (true );
787+ subBar .setStringPainted (true );
788+ subBar .setString ("..." );
789+ jFrame .add (subBar , constraints );
779790 jFrame .pack ();
780791 jFrame .setDefaultCloseOperation (WindowConstants .DO_NOTHING_ON_CLOSE );
781792 Dimension dim = Toolkit .getDefaultToolkit ().getScreenSize ();
@@ -784,27 +795,12 @@ static ScopeSide current() {
784795 } catch (Exception ignored ) {
785796 }
786797 }
787- if (theFrame != null ) {
788- for (val task : artifactMap .values ()) {
789- futures .add (CompletableFuture .supplyAsync (() -> {
790- val bar = progresses .get (task );
791- bar .setString ("Downloading..." );
792- val res = task .load ();
793- bar .setMinimum (0 );
794- bar .setMaximum (1 );
795- bar .setValue (1 );
796- bar .setString ("Completed!" );
797- return res ;
798- }, executor ));
799- }
800- } else {
801- for (val task : artifactMap .values ()) {
802- futures .add (CompletableFuture .supplyAsync (task ::load , executor ));
803- }
798+ for (val task : artifactMap .values ()) {
799+ futures .add (CompletableFuture .supplyAsync (task ::load , executor ));
804800 }
805801 AtomicBoolean doViz = new AtomicBoolean (true );
806802 if (theFrame != null ) {
807- final var vizThread = getVizThread (doViz , progresses , theFrame );
803+ final var vizThread = getVizThread (doViz , artifactMap , bar , subBar , theFrame );
808804 vizThread .start ();
809805 }
810806 List <URL > res = new ArrayList <>();
@@ -852,7 +848,7 @@ static ScopeSide current() {
852848 }
853849
854850 @ NotNull
855- private static Thread getVizThread (AtomicBoolean doViz , HashMap < DependencyLoadTask , JProgressBar > progresses , JFrame theFrame ) {
851+ private static Thread getVizThread (AtomicBoolean doViz , Map < String , DependencyLoadTask > progresses , JProgressBar mainProgress , JProgressBar subProgress , JFrame theFrame ) {
856852 val vizThread = new Thread (() -> {
857853 int waitBeforeShowing = 100 ;
858854 while (doViz .get ()) {
@@ -862,19 +858,50 @@ private static Thread getVizThread(AtomicBoolean doViz, HashMap<DependencyLoadTa
862858 theFrame .setVisible (true );
863859 waitBeforeShowing = -1 ;
864860 }
865- for (val progress : progresses .entrySet ()) {
866- val task = progress .getKey ();
867- val bar = progress .getValue ();
868- if (task .contentLength == -1 ) {
869- bar .setIndeterminate (true );
870- } else {
871- bar .setIndeterminate (false );
872- bar .setMinimum (0 );
873- bar .setMaximum ((int ) task .contentLength );
874- bar .setValue ((int ) task .downloaded );
861+ mainProgress .setIndeterminate (false );
862+ mainProgress .setMaximum (0 );
863+ mainProgress .setMaximum (progresses .size () * 100 );
864+ var currentProgress = 0 ;
865+ var pending = progresses .size ();
866+ boolean first = true ;
867+ for (val pair : progresses .entrySet ()) {
868+ val progress = pair .getValue ();
869+ val dls = progress .dlState .get ();
870+ val cl = progress .contentLength .get ();
871+ val dl = progress .downloaded .get ();
872+ switch (dls ) {
873+ case 0 : break ;
874+ case 1 : {
875+ var div = cl == -1 ? dl : cl ;
876+ if (div <= 0 ) {
877+ div = 1 ;
878+ }
879+ val prog = (int ) Math .max (0 , Math .min (100 , dl * 100 / div ));
880+ currentProgress += prog ;
881+ if (first ) {
882+ first = false ;
883+ subProgress .setIndeterminate (false );
884+ subProgress .setString (pair .getKey ());
885+ subProgress .setMinimum (0 );
886+ subProgress .setMaximum (100 );
887+ subProgress .setValue (prog );
888+ }
889+ break ;
890+ }
891+ default : {
892+ currentProgress += 100 ;
893+ pending --;
894+ }
875895 }
876896 }
877- theFrame .repaint ();
897+ if (first ) {
898+ subProgress .setIndeterminate (true );
899+ subProgress .setString ("..." );
900+ }
901+ mainProgress .setString (pending + " files remaining..." );
902+ mainProgress .setValue (currentProgress );
903+ mainProgress .repaint ();
904+ subProgress .repaint ();
878905 try {
879906 Thread .sleep (10 );
880907 } catch (InterruptedException ignored ) {
@@ -941,34 +968,40 @@ private static class DependencyLoadTask {
941968 public volatile String jarName ;
942969 private Path file ;
943970
944- public volatile long contentLength = -1 ;
945- public volatile long downloaded = 0 ;
971+ public final AtomicLong contentLength = new AtomicLong (-1 );
972+ public final AtomicLong downloaded = new AtomicLong (0 );
973+ public final AtomicInteger dlState = new AtomicInteger (0 );
946974
947975 private @ Nullable URL load () {
948976 setupLibraryNames ();
949977 if (loadedLibraries .containsKey (artifact )) {
950978 alreadyLoaded (false );
979+ dlState .set (3 );
951980 return null ;
952981 }
953982 if (isMod && loadedModIds .containsKey (modId )) {
954983 alreadyLoaded (true );
984+ dlState .set (3 );
955985 return null ;
956986 }
957987 setupPaths ();
958988 for (val repo : localMavenRepositories ) {
959989 val url = tryDownloadFromMaven (repo , true );
960990 if (url != null ) {
991+ dlState .set (3 );
961992 return url ;
962993 }
963994 }
964995 val existingUrl = tryLoadingExistingFile ();
965996 if (existingUrl != null ) {
997+ dlState .set (3 );
966998 return existingUrl ;
967999 }
9681000 validateDownloadsAllowed ();
9691001 for (var repo : remoteMavenRepositories ) {
9701002 val url = tryDownloadFromMaven (repo , false );
9711003 if (url != null ) {
1004+ dlState .set (3 );
9721005 return url ;
9731006 }
9741007 }
@@ -1121,18 +1154,18 @@ private void validateDownloadsAllowed() {
11211154 if (Files .exists (tmpFile )) {
11221155 Files .delete (tmpFile );
11231156 }
1157+ dlState .set (1 );
11241158 Internet .connect (new URL (url ),
11251159 ex -> LOG .debug ("Artifact {} could not be downloaded from repo {}: {}" ,
11261160 artifactLogName ,
11271161 finalRepo ,
11281162 ex .getMessage ()),
11291163 input -> {
11301164 LOG .debug ("Downloading {} from {}" , artifactLogName , finalRepo );
1131- download (input , tmpFile , d -> downloaded += d );
1165+ download (input , tmpFile , downloaded :: getAndAdd );
11321166 LOG .debug ("Downloaded {} from {}" , artifactLogName , finalRepo );
11331167 success .set (true );
1134- },
1135- contentLength -> this .contentLength = contentLength );
1168+ }, this .contentLength ::getAndAdd );
11361169 if (success .get ()) {
11371170 if (FileUtils .contentEquals (tmpFile .toFile (), file .toFile ())) {
11381171 Files .delete (tmpFile );
@@ -1171,11 +1204,13 @@ private void validateDownloadsAllowed() {
11711204 loadedModIds .put (modId , preferredVersion );
11721205 loadedModIdMods .put (modId , loadingModId );
11731206 }
1207+ dlState .set (2 );
11741208 return diskUrl ;
11751209 }
11761210 }
11771211 } catch (IOException ignored ) {
11781212 }
1213+ dlState .set (2 );
11791214 return null ;
11801215 }
11811216 }
0 commit comments