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.StatusbarMouseListener;
|
||||
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.Logger;
|
||||
|
@ -94,7 +95,7 @@ public class ManagerFrame extends JFrame implements ActionListener, ModsScanObse
|
|||
private File backupDir = new File( "./backup/" );
|
||||
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" );
|
||||
|
||||
|
@ -260,8 +261,8 @@ public class ManagerFrame extends JFrame implements ActionListener, ModsScanObse
|
|||
public void windowClosed( WindowEvent e ) {
|
||||
// dispose() was called.
|
||||
|
||||
List<ModFileInfo> sortedMods = modsTablePanel.getAllItems();
|
||||
saveModOrder( sortedMods );
|
||||
ListState<ModFileInfo> tableState = getCurrentModsTableState();
|
||||
saveModsTableState( tableState );
|
||||
|
||||
SlipstreamConfig appConfig = ManagerFrame.this.appConfig;
|
||||
|
||||
|
@ -395,7 +396,8 @@ public class ManagerFrame extends JFrame implements ActionListener, ModsScanObse
|
|||
|
||||
ManagerInitThread initThread = new ManagerInitThread( this,
|
||||
new SlipstreamConfig( appConfig ),
|
||||
modorderFile,
|
||||
modsDir,
|
||||
modsTableStateFile,
|
||||
metadataFile,
|
||||
catalogFile,
|
||||
catalogETagFile,
|
||||
|
@ -409,48 +411,60 @@ public class ManagerFrame extends JFrame implements ActionListener, ModsScanObse
|
|||
|
||||
|
||||
/**
|
||||
* Returns a mod list with names sorted in a preferred order.
|
||||
*
|
||||
* Mods not mentioned in the name list appear at the end, alphabetically.
|
||||
* Returns a ListState describing content in the mods table.
|
||||
*/
|
||||
private List<ModFileInfo> reorderMods( List<ModFileInfo> unsortedMods, List<String> preferredOrder ) {
|
||||
List<ModFileInfo> sortedMods = new ArrayList<ModFileInfo>();
|
||||
public ListState<ModFileInfo> getCurrentModsTableState() {
|
||||
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 );
|
||||
Collections.sort( availableMods );
|
||||
|
||||
if ( preferredOrder != null ) {
|
||||
for ( String name : preferredOrder ) {
|
||||
Iterator<ModFileInfo> it = availableMods.iterator();
|
||||
while ( it.hasNext() ) {
|
||||
ModFileInfo modFileInfo = it.next();
|
||||
if ( modFileInfo.getName().equals( name ) ) {
|
||||
it.remove();
|
||||
sortedMods.add( modFileInfo );
|
||||
break;
|
||||
for ( ModFileInfo modFileInfo : availableMods ) {
|
||||
if ( !tableState.containsItem( modFileInfo ) ) {
|
||||
tableState.addItem( modFileInfo );
|
||||
}
|
||||
}
|
||||
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;
|
||||
try {
|
||||
FileOutputStream os = new FileOutputStream( modorderFile );
|
||||
FileOutputStream os = new FileOutputStream( modsTableStateFile );
|
||||
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( "\r\n" );
|
||||
}
|
||||
bw.flush();
|
||||
}
|
||||
catch ( IOException e ) {
|
||||
log.error( String.format( "Error writing \"%s\".", modorderFile.getName() ), e );
|
||||
log.error( String.format( "Error writing \"%s\".", modsTableStateFile.getName() ), e );
|
||||
}
|
||||
finally {
|
||||
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();
|
||||
try {
|
||||
scanning = true;
|
||||
|
@ -484,9 +499,9 @@ public class ManagerFrame extends JFrame implements ActionListener, ModsScanObse
|
|||
ModFileInfo modFileInfo = new ModFileInfo( f );
|
||||
unsortedMods.add( modFileInfo );
|
||||
}
|
||||
amendModsTableState( tableState, unsortedMods );
|
||||
|
||||
List<ModFileInfo> sortedMods = reorderMods( unsortedMods, preferredOrder );
|
||||
for ( ModFileInfo modFileInfo : sortedMods ) {
|
||||
for ( ModFileInfo modFileInfo : tableState.getItems() ) {
|
||||
modsTablePanel.getTableModel().addItem( modFileInfo );
|
||||
}
|
||||
|
||||
|
@ -732,12 +747,8 @@ public class ManagerFrame extends JFrame implements ActionListener, ModsScanObse
|
|||
setStatusText( "" );
|
||||
if ( rescanMenuItem.isEnabled() == false ) return;
|
||||
|
||||
List<String> preferredOrder = new ArrayList<String>();
|
||||
|
||||
for ( ModFileInfo modFileInfo : modsTablePanel.getAllItems() ) {
|
||||
preferredOrder.add( modFileInfo.getName() );
|
||||
}
|
||||
rescanMods( preferredOrder );
|
||||
ListState<ModFileInfo> tableState = getCurrentModsTableState();
|
||||
rescanMods( tableState );
|
||||
}
|
||||
else if ( source == extractDatsMenuItem ) {
|
||||
setStatusText( "" );
|
||||
|
|
|
@ -17,11 +17,13 @@ import javax.swing.SwingUtilities;
|
|||
|
||||
import net.vhati.modmanager.core.AutoUpdateInfo;
|
||||
import net.vhati.modmanager.core.ModDB;
|
||||
import net.vhati.modmanager.core.ModFileInfo;
|
||||
import net.vhati.modmanager.core.SlipstreamConfig;
|
||||
import net.vhati.modmanager.json.JacksonAutoUpdateReader;
|
||||
import net.vhati.modmanager.json.JacksonCatalogReader;
|
||||
import net.vhati.modmanager.json.URLFetcher;
|
||||
import net.vhati.modmanager.ui.ManagerFrame;
|
||||
import net.vhati.modmanager.ui.table.ListState;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
@ -41,7 +43,8 @@ public class ManagerInitThread extends Thread {
|
|||
|
||||
private final ManagerFrame frame;
|
||||
private final SlipstreamConfig appConfig;
|
||||
private final File modorderFile;
|
||||
private final File modsDir;
|
||||
private final File modsTableStateFile;
|
||||
private final File metadataFile;
|
||||
private final File catalogFile;
|
||||
private final File catalogETagFile;
|
||||
|
@ -49,10 +52,11 @@ public class ManagerInitThread extends Thread {
|
|||
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.appConfig = appConfig;
|
||||
this.modorderFile = modorderFile;
|
||||
this.modsDir = modsDir;
|
||||
this.modsTableStateFile = modsTableStateFile;
|
||||
this.metadataFile = metadataFile;
|
||||
this.catalogFile = catalogFile;
|
||||
this.catalogETagFile = catalogETagFile;
|
||||
|
@ -79,14 +83,14 @@ public class ManagerInitThread extends Thread {
|
|||
if ( cachedDB != null ) frame.setLocalModDB( cachedDB );
|
||||
}
|
||||
|
||||
final List<String> preferredOrder = loadModOrder();
|
||||
final ListState<ModFileInfo> tableState = loadModsTableState();
|
||||
|
||||
Lock managerLock = frame.getLock();
|
||||
managerLock.lock();
|
||||
try {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() { frame.rescanMods( preferredOrder ); }
|
||||
public void run() { frame.rescanMods( tableState ); }
|
||||
});
|
||||
|
||||
// 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.
|
||||
*/
|
||||
private List<String> loadModOrder() {
|
||||
List<String> result = new ArrayList<String>();
|
||||
private ListState<ModFileInfo> loadModsTableState() {
|
||||
List<String> fileNames = new ArrayList<String>();
|
||||
|
||||
BufferedReader br = null;
|
||||
try {
|
||||
FileInputStream is = new FileInputStream( modorderFile );
|
||||
FileInputStream is = new FileInputStream( modsTableStateFile );
|
||||
br = new BufferedReader(new InputStreamReader( is, Charset.forName("UTF-8") ));
|
||||
String line;
|
||||
while ( (line = br.readLine()) != null ) {
|
||||
result.add( line );
|
||||
fileNames.add( line );
|
||||
}
|
||||
}
|
||||
catch ( FileNotFoundException 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 {
|
||||
try {if ( br != null ) br.close();}
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
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