Refactored modorder as modsTableState
This commit is contained in:
parent
1a5bf935df
commit
e25799a78e
3 changed files with 110 additions and 47 deletions
|
@ -79,6 +79,7 @@ import net.vhati.modmanager.ui.SlipstreamConfigDialog;
|
||||||
import net.vhati.modmanager.ui.Statusbar;
|
import net.vhati.modmanager.ui.Statusbar;
|
||||||
import net.vhati.modmanager.ui.StatusbarMouseListener;
|
import net.vhati.modmanager.ui.StatusbarMouseListener;
|
||||||
import net.vhati.modmanager.ui.table.ChecklistTablePanel;
|
import net.vhati.modmanager.ui.table.ChecklistTablePanel;
|
||||||
|
import net.vhati.modmanager.ui.table.ListState;
|
||||||
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
@ -94,7 +95,7 @@ public class ManagerFrame extends JFrame implements ActionListener, ModsScanObse
|
||||||
private File backupDir = new File( "./backup/" );
|
private File backupDir = new File( "./backup/" );
|
||||||
private File modsDir = new File( "./mods/" );
|
private File modsDir = new File( "./mods/" );
|
||||||
|
|
||||||
private File modorderFile = new File( modsDir, "modorder.txt" );
|
private File modsTableStateFile = new File( modsDir, "modorder.txt" );
|
||||||
|
|
||||||
private File metadataFile = new File( backupDir, "cached_metadata.json" );
|
private File metadataFile = new File( backupDir, "cached_metadata.json" );
|
||||||
|
|
||||||
|
@ -260,8 +261,8 @@ public class ManagerFrame extends JFrame implements ActionListener, ModsScanObse
|
||||||
public void windowClosed( WindowEvent e ) {
|
public void windowClosed( WindowEvent e ) {
|
||||||
// dispose() was called.
|
// dispose() was called.
|
||||||
|
|
||||||
List<ModFileInfo> sortedMods = modsTablePanel.getAllItems();
|
ListState<ModFileInfo> tableState = getCurrentModsTableState();
|
||||||
saveModOrder( sortedMods );
|
saveModsTableState( tableState );
|
||||||
|
|
||||||
SlipstreamConfig appConfig = ManagerFrame.this.appConfig;
|
SlipstreamConfig appConfig = ManagerFrame.this.appConfig;
|
||||||
|
|
||||||
|
@ -395,7 +396,8 @@ public class ManagerFrame extends JFrame implements ActionListener, ModsScanObse
|
||||||
|
|
||||||
ManagerInitThread initThread = new ManagerInitThread( this,
|
ManagerInitThread initThread = new ManagerInitThread( this,
|
||||||
new SlipstreamConfig( appConfig ),
|
new SlipstreamConfig( appConfig ),
|
||||||
modorderFile,
|
modsDir,
|
||||||
|
modsTableStateFile,
|
||||||
metadataFile,
|
metadataFile,
|
||||||
catalogFile,
|
catalogFile,
|
||||||
catalogETagFile,
|
catalogETagFile,
|
||||||
|
@ -409,48 +411,60 @@ public class ManagerFrame extends JFrame implements ActionListener, ModsScanObse
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a mod list with names sorted in a preferred order.
|
* Returns a ListState describing content in the mods table.
|
||||||
*
|
|
||||||
* Mods not mentioned in the name list appear at the end, alphabetically.
|
|
||||||
*/
|
*/
|
||||||
private List<ModFileInfo> reorderMods( List<ModFileInfo> unsortedMods, List<String> preferredOrder ) {
|
public ListState<ModFileInfo> getCurrentModsTableState() {
|
||||||
List<ModFileInfo> sortedMods = new ArrayList<ModFileInfo>();
|
ListState<ModFileInfo> tableState = new ListState<ModFileInfo>();
|
||||||
|
|
||||||
|
for ( ModFileInfo modFileInfo : modsTablePanel.getAllItems() ) {
|
||||||
|
tableState.addItem( modFileInfo );
|
||||||
|
}
|
||||||
|
|
||||||
|
return tableState;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Synchronizes a mods table state with a pool of available items.
|
||||||
|
*
|
||||||
|
* Items in the table that also are in the pool are unchanged.
|
||||||
|
* Items in the table that aren't in the pool are pruned.
|
||||||
|
* Items in the pool that weren't in the table are appended in ascending
|
||||||
|
* order.
|
||||||
|
*
|
||||||
|
* @param tableState an existing state to amend
|
||||||
|
* @param unsortedMods the pool of currently available local mods
|
||||||
|
*/
|
||||||
|
public void amendModsTableState( ListState<ModFileInfo> tableState, List<ModFileInfo> unsortedMods ) {
|
||||||
List<ModFileInfo> availableMods = new ArrayList<ModFileInfo>( unsortedMods );
|
List<ModFileInfo> availableMods = new ArrayList<ModFileInfo>( unsortedMods );
|
||||||
Collections.sort( availableMods );
|
Collections.sort( availableMods );
|
||||||
|
|
||||||
if ( preferredOrder != null ) {
|
for ( ModFileInfo modFileInfo : availableMods ) {
|
||||||
for ( String name : preferredOrder ) {
|
if ( !tableState.containsItem( modFileInfo ) ) {
|
||||||
Iterator<ModFileInfo> it = availableMods.iterator();
|
tableState.addItem( modFileInfo );
|
||||||
while ( it.hasNext() ) {
|
|
||||||
ModFileInfo modFileInfo = it.next();
|
|
||||||
if ( modFileInfo.getName().equals( name ) ) {
|
|
||||||
it.remove();
|
|
||||||
sortedMods.add( modFileInfo );
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for ( ModFileInfo modFileInfo : tableState.getItems() ) {
|
||||||
|
if ( !availableMods.contains( modFileInfo ) ) {
|
||||||
|
tableState.removeItem( modFileInfo );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sortedMods.addAll( availableMods );
|
|
||||||
|
|
||||||
return sortedMods;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void saveModOrder( List<ModFileInfo> sortedMods ) {
|
private void saveModsTableState( ListState<ModFileInfo> tableState ) {
|
||||||
BufferedWriter bw = null;
|
BufferedWriter bw = null;
|
||||||
try {
|
try {
|
||||||
FileOutputStream os = new FileOutputStream( modorderFile );
|
FileOutputStream os = new FileOutputStream( modsTableStateFile );
|
||||||
bw = new BufferedWriter(new OutputStreamWriter( os, Charset.forName("UTF-8") ));
|
bw = new BufferedWriter(new OutputStreamWriter( os, Charset.forName("UTF-8") ));
|
||||||
|
|
||||||
for ( ModFileInfo modFileInfo : sortedMods ) {
|
for ( ModFileInfo modFileInfo : tableState.getItems() ) {
|
||||||
bw.write( modFileInfo.getName() );
|
bw.write( modFileInfo.getName() );
|
||||||
bw.write( "\r\n" );
|
bw.write( "\r\n" );
|
||||||
}
|
}
|
||||||
bw.flush();
|
bw.flush();
|
||||||
}
|
}
|
||||||
catch ( IOException e ) {
|
catch ( IOException e ) {
|
||||||
log.error( String.format( "Error writing \"%s\".", modorderFile.getName() ), e );
|
log.error( String.format( "Error writing \"%s\".", modsTableStateFile.getName() ), e );
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
try {if (bw != null) bw.close();}
|
try {if (bw != null) bw.close();}
|
||||||
|
@ -460,9 +474,10 @@ public class ManagerFrame extends JFrame implements ActionListener, ModsScanObse
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clears and syncs the mods list with mods/ dir, then starts a new hash thread.
|
* Clears and syncs the mods list with mods/ dir, then starts a new hash
|
||||||
|
* thread.
|
||||||
*/
|
*/
|
||||||
public void rescanMods( List<String> preferredOrder ) {
|
public void rescanMods( ListState<ModFileInfo> tableState ) {
|
||||||
managerLock.lock();
|
managerLock.lock();
|
||||||
try {
|
try {
|
||||||
scanning = true;
|
scanning = true;
|
||||||
|
@ -484,9 +499,9 @@ public class ManagerFrame extends JFrame implements ActionListener, ModsScanObse
|
||||||
ModFileInfo modFileInfo = new ModFileInfo( f );
|
ModFileInfo modFileInfo = new ModFileInfo( f );
|
||||||
unsortedMods.add( modFileInfo );
|
unsortedMods.add( modFileInfo );
|
||||||
}
|
}
|
||||||
|
amendModsTableState( tableState, unsortedMods );
|
||||||
|
|
||||||
List<ModFileInfo> sortedMods = reorderMods( unsortedMods, preferredOrder );
|
for ( ModFileInfo modFileInfo : tableState.getItems() ) {
|
||||||
for ( ModFileInfo modFileInfo : sortedMods ) {
|
|
||||||
modsTablePanel.getTableModel().addItem( modFileInfo );
|
modsTablePanel.getTableModel().addItem( modFileInfo );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -732,12 +747,8 @@ public class ManagerFrame extends JFrame implements ActionListener, ModsScanObse
|
||||||
setStatusText( "" );
|
setStatusText( "" );
|
||||||
if ( rescanMenuItem.isEnabled() == false ) return;
|
if ( rescanMenuItem.isEnabled() == false ) return;
|
||||||
|
|
||||||
List<String> preferredOrder = new ArrayList<String>();
|
ListState<ModFileInfo> tableState = getCurrentModsTableState();
|
||||||
|
rescanMods( tableState );
|
||||||
for ( ModFileInfo modFileInfo : modsTablePanel.getAllItems() ) {
|
|
||||||
preferredOrder.add( modFileInfo.getName() );
|
|
||||||
}
|
|
||||||
rescanMods( preferredOrder );
|
|
||||||
}
|
}
|
||||||
else if ( source == extractDatsMenuItem ) {
|
else if ( source == extractDatsMenuItem ) {
|
||||||
setStatusText( "" );
|
setStatusText( "" );
|
||||||
|
|
|
@ -17,11 +17,13 @@ import javax.swing.SwingUtilities;
|
||||||
|
|
||||||
import net.vhati.modmanager.core.AutoUpdateInfo;
|
import net.vhati.modmanager.core.AutoUpdateInfo;
|
||||||
import net.vhati.modmanager.core.ModDB;
|
import net.vhati.modmanager.core.ModDB;
|
||||||
|
import net.vhati.modmanager.core.ModFileInfo;
|
||||||
import net.vhati.modmanager.core.SlipstreamConfig;
|
import net.vhati.modmanager.core.SlipstreamConfig;
|
||||||
import net.vhati.modmanager.json.JacksonAutoUpdateReader;
|
import net.vhati.modmanager.json.JacksonAutoUpdateReader;
|
||||||
import net.vhati.modmanager.json.JacksonCatalogReader;
|
import net.vhati.modmanager.json.JacksonCatalogReader;
|
||||||
import net.vhati.modmanager.json.URLFetcher;
|
import net.vhati.modmanager.json.URLFetcher;
|
||||||
import net.vhati.modmanager.ui.ManagerFrame;
|
import net.vhati.modmanager.ui.ManagerFrame;
|
||||||
|
import net.vhati.modmanager.ui.table.ListState;
|
||||||
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
@ -41,7 +43,8 @@ public class ManagerInitThread extends Thread {
|
||||||
|
|
||||||
private final ManagerFrame frame;
|
private final ManagerFrame frame;
|
||||||
private final SlipstreamConfig appConfig;
|
private final SlipstreamConfig appConfig;
|
||||||
private final File modorderFile;
|
private final File modsDir;
|
||||||
|
private final File modsTableStateFile;
|
||||||
private final File metadataFile;
|
private final File metadataFile;
|
||||||
private final File catalogFile;
|
private final File catalogFile;
|
||||||
private final File catalogETagFile;
|
private final File catalogETagFile;
|
||||||
|
@ -49,10 +52,11 @@ public class ManagerInitThread extends Thread {
|
||||||
private final File appUpdateETagFile;
|
private final File appUpdateETagFile;
|
||||||
|
|
||||||
|
|
||||||
public ManagerInitThread( ManagerFrame frame, SlipstreamConfig appConfig, File modorderFile, File metadataFile, File catalogFile, File catalogETagFile, File appUpdateFile, File appUpdateETagFile ) {
|
public ManagerInitThread( ManagerFrame frame, SlipstreamConfig appConfig, File modsDir, File modsTableStateFile, File metadataFile, File catalogFile, File catalogETagFile, File appUpdateFile, File appUpdateETagFile ) {
|
||||||
this.frame = frame;
|
this.frame = frame;
|
||||||
this.appConfig = appConfig;
|
this.appConfig = appConfig;
|
||||||
this.modorderFile = modorderFile;
|
this.modsDir = modsDir;
|
||||||
|
this.modsTableStateFile = modsTableStateFile;
|
||||||
this.metadataFile = metadataFile;
|
this.metadataFile = metadataFile;
|
||||||
this.catalogFile = catalogFile;
|
this.catalogFile = catalogFile;
|
||||||
this.catalogETagFile = catalogETagFile;
|
this.catalogETagFile = catalogETagFile;
|
||||||
|
@ -79,14 +83,14 @@ public class ManagerInitThread extends Thread {
|
||||||
if ( cachedDB != null ) frame.setLocalModDB( cachedDB );
|
if ( cachedDB != null ) frame.setLocalModDB( cachedDB );
|
||||||
}
|
}
|
||||||
|
|
||||||
final List<String> preferredOrder = loadModOrder();
|
final ListState<ModFileInfo> tableState = loadModsTableState();
|
||||||
|
|
||||||
Lock managerLock = frame.getLock();
|
Lock managerLock = frame.getLock();
|
||||||
managerLock.lock();
|
managerLock.lock();
|
||||||
try {
|
try {
|
||||||
SwingUtilities.invokeLater(new Runnable() {
|
SwingUtilities.invokeLater(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() { frame.rescanMods( preferredOrder ); }
|
public void run() { frame.rescanMods( tableState ); }
|
||||||
});
|
});
|
||||||
|
|
||||||
// Wait until notified that "mods/" has been scanned.
|
// Wait until notified that "mods/" has been scanned.
|
||||||
|
@ -167,28 +171,37 @@ public class ManagerInitThread extends Thread {
|
||||||
/**
|
/**
|
||||||
* Reads modorder.txt and returns a list of mod names in preferred order.
|
* Reads modorder.txt and returns a list of mod names in preferred order.
|
||||||
*/
|
*/
|
||||||
private List<String> loadModOrder() {
|
private ListState<ModFileInfo> loadModsTableState() {
|
||||||
List<String> result = new ArrayList<String>();
|
List<String> fileNames = new ArrayList<String>();
|
||||||
|
|
||||||
BufferedReader br = null;
|
BufferedReader br = null;
|
||||||
try {
|
try {
|
||||||
FileInputStream is = new FileInputStream( modorderFile );
|
FileInputStream is = new FileInputStream( modsTableStateFile );
|
||||||
br = new BufferedReader(new InputStreamReader( is, Charset.forName("UTF-8") ));
|
br = new BufferedReader(new InputStreamReader( is, Charset.forName("UTF-8") ));
|
||||||
String line;
|
String line;
|
||||||
while ( (line = br.readLine()) != null ) {
|
while ( (line = br.readLine()) != null ) {
|
||||||
result.add( line );
|
fileNames.add( line );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch ( FileNotFoundException e ) {
|
catch ( FileNotFoundException e ) {
|
||||||
}
|
}
|
||||||
catch ( IOException e ) {
|
catch ( IOException e ) {
|
||||||
log.error( String.format( "Error reading \"%s\".", modorderFile.getName() ), e );
|
log.error( String.format( "Error reading \"%s\".", modsTableStateFile.getName() ), e );
|
||||||
|
fileNames.clear();
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
try {if ( br != null ) br.close();}
|
try {if ( br != null ) br.close();}
|
||||||
catch ( Exception e ) {}
|
catch ( Exception e ) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ListState<ModFileInfo> result = new ListState<ModFileInfo>();
|
||||||
|
|
||||||
|
for ( String fileName : fileNames ) {
|
||||||
|
File modFile = new File( modsDir, fileName );
|
||||||
|
ModFileInfo modFileInfo = new ModFileInfo( modFile );
|
||||||
|
result.addItem( modFileInfo );
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
39
src/main/java/net/vhati/modmanager/ui/table/ListState.java
Normal file
39
src/main/java/net/vhati/modmanager/ui/table/ListState.java
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
package net.vhati.modmanager.ui.table;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An implementation-agnostic model to pass between the GUI thread and the
|
||||||
|
* (de)serializer.
|
||||||
|
*/
|
||||||
|
public class ListState<T> {
|
||||||
|
|
||||||
|
protected List<T> items = new ArrayList<T>();
|
||||||
|
|
||||||
|
|
||||||
|
public ListState() {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void addItem( T item ) {
|
||||||
|
items.add( item );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a new list containing items in this state.
|
||||||
|
*/
|
||||||
|
public List<T> getItems() {
|
||||||
|
return new ArrayList<T>( items );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeItem( T item ) {
|
||||||
|
items.remove( item );
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean containsItem( T item ) {
|
||||||
|
return items.contains( item );
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue