mirror of
https://github.com/JFormDesigner/FlatLaf.git
synced 2026-02-10 22:17:13 -06:00
Theme Editor: re-implemented support loading/resolving base properties from other editors in opened directory
This commit is contained in:
@@ -23,7 +23,6 @@ import java.awt.Window;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.List;
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.InputMap;
|
||||
import javax.swing.JComponent;
|
||||
@@ -49,6 +48,7 @@ import org.fife.ui.rsyntaxtextarea.TokenTypes;
|
||||
import org.fife.ui.rtextarea.Gutter;
|
||||
import org.fife.ui.rtextarea.RTextArea;
|
||||
import org.fife.ui.rtextarea.RTextScrollPane;
|
||||
import com.formdev.flatlaf.util.StringUtils;
|
||||
import com.formdev.flatlaf.util.UIScale;
|
||||
|
||||
/**
|
||||
@@ -168,8 +168,9 @@ class FlatThemeEditorPane
|
||||
return textArea.requestFocusInWindow();
|
||||
}
|
||||
|
||||
void setBaseFiles( List<File> baseFiles ) {
|
||||
textArea.propertiesSupport.setBaseFiles( baseFiles );
|
||||
void initBasePropertyProvider( FlatThemePropertiesBaseManager propertiesBaseManager ) {
|
||||
String name = StringUtils.removeTrailing( file.getName(), ".properties" );
|
||||
textArea.propertiesSupport.setBasePropertyProvider( propertiesBaseManager.create( name, textArea.propertiesSupport ) );
|
||||
}
|
||||
|
||||
File getFile() {
|
||||
|
||||
@@ -68,6 +68,8 @@ public class FlatThemeFileEditor
|
||||
private Preferences state;
|
||||
private boolean inLoadDirectory;
|
||||
|
||||
private final FlatThemePropertiesBaseManager propertiesBaseManager = new FlatThemePropertiesBaseManager();
|
||||
|
||||
public static void main( String[] args ) {
|
||||
File dir = (args.length > 0)
|
||||
? new File( args[0] )
|
||||
@@ -187,6 +189,7 @@ public class FlatThemeFileEditor
|
||||
return;
|
||||
|
||||
this.dir = dir;
|
||||
propertiesBaseManager.clear();
|
||||
|
||||
inLoadDirectory = true;
|
||||
|
||||
@@ -266,6 +269,8 @@ public class FlatThemeFileEditor
|
||||
ex.printStackTrace(); // TODO
|
||||
}
|
||||
|
||||
themeEditorPane.initBasePropertyProvider( propertiesBaseManager );
|
||||
|
||||
Supplier<String> titleFun = () -> {
|
||||
return (themeEditorPane.isDirty() ? "* " : "")
|
||||
+ StringUtils.removeTrailing( themeEditorPane.getFile().getName(), ".properties" );
|
||||
|
||||
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
* Copyright 2021 FormDev Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.formdev.flatlaf.themeeditor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
class FlatThemePropertiesBaseManager
|
||||
{
|
||||
private final Map<String, MyBasePropertyProvider> providers = new HashMap<>();
|
||||
|
||||
FlatThemePropertiesSupport.BasePropertyProvider create( String name, FlatThemePropertiesSupport propertiesSupport ) {
|
||||
MyBasePropertyProvider provider = new MyBasePropertyProvider( name, propertiesSupport );
|
||||
providers.put( name, provider );
|
||||
return provider;
|
||||
}
|
||||
|
||||
void clear() {
|
||||
providers.clear();
|
||||
}
|
||||
|
||||
private static List<String> baseFiles( String name, String baseTheme ) {
|
||||
ArrayList<String> result = new ArrayList<>();
|
||||
|
||||
// core themes
|
||||
switch( name ) {
|
||||
case "FlatLaf":
|
||||
result.add( "FlatLightLaf" );
|
||||
break;
|
||||
|
||||
case "FlatLightLaf":
|
||||
case "FlatDarkLaf":
|
||||
result.add( "FlatLaf" );
|
||||
break;
|
||||
|
||||
case "FlatIntelliJLaf":
|
||||
result.add( "FlatLightLaf" );
|
||||
result.add( "FlatLaf" );
|
||||
break;
|
||||
|
||||
case "FlatDarculaLaf":
|
||||
result.add( "FlatDarkLaf" );
|
||||
result.add( "FlatLaf" );
|
||||
break;
|
||||
}
|
||||
|
||||
// custom themes based on core themes
|
||||
if( result.isEmpty() ) {
|
||||
if( baseTheme == null )
|
||||
baseTheme = "light";
|
||||
|
||||
switch( baseTheme ) {
|
||||
default:
|
||||
case "light":
|
||||
result.add( "FlatLightLaf" );
|
||||
result.add( "FlatLaf" );
|
||||
break;
|
||||
|
||||
case "dark":
|
||||
result.add( "FlatDarkLaf" );
|
||||
result.add( "FlatLaf" );
|
||||
break;
|
||||
|
||||
case "intellij":
|
||||
result.add( "FlatIntelliJLaf" );
|
||||
result.add( "FlatLightLaf" );
|
||||
result.add( "FlatLaf" );
|
||||
break;
|
||||
|
||||
case "darcula":
|
||||
result.add( "FlatDarculaLaf" );
|
||||
result.add( "FlatLightLaf" );
|
||||
result.add( "FlatLaf" );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//---- class MyBasePropertyProvider ---------------------------------------
|
||||
|
||||
private class MyBasePropertyProvider
|
||||
implements FlatThemePropertiesSupport.BasePropertyProvider
|
||||
{
|
||||
private final String name;
|
||||
private final FlatThemePropertiesSupport propertiesSupport;
|
||||
|
||||
private List<String> baseFiles;
|
||||
private String lastBaseTheme;
|
||||
|
||||
MyBasePropertyProvider( String name, FlatThemePropertiesSupport propertiesSupport ) {
|
||||
this.name = name;
|
||||
this.propertiesSupport = propertiesSupport;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProperty( String key, String baseTheme ) {
|
||||
updateBaseFiles( baseTheme );
|
||||
|
||||
for( String baseFile : baseFiles ) {
|
||||
String value = getPropertyFromBase( baseFile, key );
|
||||
if( value != null )
|
||||
return value;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private String getPropertyFromBase( String baseFile, String key ) {
|
||||
MyBasePropertyProvider provider = providers.get( baseFile );
|
||||
return (provider != null)
|
||||
? provider.propertiesSupport.getProperties().getProperty( key )
|
||||
: null;
|
||||
}
|
||||
|
||||
private void updateBaseFiles( String baseTheme ) {
|
||||
if( baseFiles != null && Objects.equals( baseTheme, lastBaseTheme ) )
|
||||
return;
|
||||
|
||||
baseFiles = baseFiles( name, baseTheme );
|
||||
lastBaseTheme = baseTheme;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addAllKeys( Set<String> allKeys, String baseTheme ) {
|
||||
updateBaseFiles( baseTheme );
|
||||
|
||||
for( String baseFile : baseFiles ) {
|
||||
MyBasePropertyProvider provider = providers.get( baseFile );
|
||||
if( provider == null )
|
||||
continue;
|
||||
|
||||
for( Object key : provider.propertiesSupport.getProperties().keySet() )
|
||||
allKeys.add( (String) key );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,14 +17,10 @@
|
||||
package com.formdev.flatlaf.themeeditor;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.StringReader;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
@@ -45,14 +41,16 @@ class FlatThemePropertiesSupport
|
||||
private final FlatSyntaxTextArea textArea;
|
||||
private final Function<String, String> propertiesGetter;
|
||||
private final Function<String, String> resolver;
|
||||
private BasePropertyProvider basePropertyProvider;
|
||||
|
||||
// caches
|
||||
private Properties propertiesCache;
|
||||
private final Map<Integer, Object> parsedValueCache = new HashMap<>();
|
||||
|
||||
private File[] baseFiles;
|
||||
private long[] baseFilesLastModified;
|
||||
private Properties[] basePropertiesCache;
|
||||
|
||||
private Set<String> allKeysCache;
|
||||
private String baseTheme;
|
||||
|
||||
private static long globalCacheInvalidationCounter;
|
||||
private long cacheInvalidationCounter;
|
||||
|
||||
FlatThemePropertiesSupport( FlatSyntaxTextArea textArea ) {
|
||||
this.textArea = textArea;
|
||||
@@ -67,12 +65,8 @@ class FlatThemePropertiesSupport
|
||||
textArea.getDocument().addDocumentListener( this );
|
||||
}
|
||||
|
||||
void setBaseFiles( List<File> baseFiles ) {
|
||||
int size = baseFiles.size();
|
||||
this.baseFiles = baseFiles.toArray( new File[size] );
|
||||
|
||||
baseFilesLastModified = new long[size];
|
||||
basePropertiesCache = new Properties[size];
|
||||
void setBasePropertyProvider( BasePropertyProvider basePropertyProvider ) {
|
||||
this.basePropertyProvider = basePropertyProvider;
|
||||
}
|
||||
|
||||
private String resolveValue( String value ) {
|
||||
@@ -80,6 +74,8 @@ class FlatThemePropertiesSupport
|
||||
}
|
||||
|
||||
Object getParsedValueAtLine( int line ) {
|
||||
autoClearCache();
|
||||
|
||||
Integer lineKey = line;
|
||||
Object parsedValue = parsedValueCache.get( lineKey );
|
||||
if( parsedValue != null )
|
||||
@@ -96,7 +92,7 @@ class FlatThemePropertiesSupport
|
||||
parsedValueCache.put( lineKey, parsedValue );
|
||||
return parsedValue;
|
||||
} catch( Exception ex ) {
|
||||
System.out.println( ex.getMessage() ); //TODO
|
||||
System.out.println( textArea.getFileName() + ": " + ex.getMessage() ); //TODO
|
||||
parsedValueCache.put( lineKey, ex );
|
||||
return null;
|
||||
}
|
||||
@@ -128,20 +124,14 @@ class FlatThemePropertiesSupport
|
||||
if( value != null )
|
||||
return value;
|
||||
|
||||
if( baseFiles == null )
|
||||
if( basePropertyProvider == null )
|
||||
return null;
|
||||
|
||||
// look in base properties files
|
||||
for( int i = 0; i < baseFiles.length; i++ ) {
|
||||
value = getBaseProperties( i ).getProperty( key );
|
||||
if( value != null )
|
||||
return value;
|
||||
}
|
||||
|
||||
return null;
|
||||
return basePropertyProvider.getProperty( key, getBaseTheme() );
|
||||
}
|
||||
|
||||
private Properties getProperties() {
|
||||
Properties getProperties() {
|
||||
if( propertiesCache != null )
|
||||
return propertiesCache;
|
||||
|
||||
@@ -154,23 +144,9 @@ class FlatThemePropertiesSupport
|
||||
return propertiesCache;
|
||||
}
|
||||
|
||||
private Properties getBaseProperties( int index ) {
|
||||
long lastModified = baseFiles[index].lastModified();
|
||||
if( baseFilesLastModified[index] != lastModified || basePropertiesCache[index] == null ) {
|
||||
// (re)load base properties file
|
||||
baseFilesLastModified[index] = lastModified;
|
||||
basePropertiesCache[index] = new Properties();
|
||||
try( InputStream in = new FileInputStream( baseFiles[index] ) ) {
|
||||
basePropertiesCache[index].load( in );
|
||||
} catch( IOException ex ) {
|
||||
ex.printStackTrace(); //TODO
|
||||
}
|
||||
}
|
||||
|
||||
return basePropertiesCache[index];
|
||||
}
|
||||
|
||||
Set<String> getAllKeys() {
|
||||
autoClearCache();
|
||||
|
||||
if( allKeysCache != null )
|
||||
return allKeysCache;
|
||||
|
||||
@@ -179,21 +155,39 @@ class FlatThemePropertiesSupport
|
||||
for( Object key : getProperties().keySet() )
|
||||
allKeysCache.add( (String) key );
|
||||
|
||||
if( baseFiles == null )
|
||||
return allKeysCache;
|
||||
|
||||
for( int i = 0; i < baseFiles.length; i++ ) {
|
||||
for( Object key : getBaseProperties( i ).keySet() )
|
||||
allKeysCache.add( (String) key );
|
||||
}
|
||||
// look in base properties files
|
||||
if( basePropertyProvider != null )
|
||||
basePropertyProvider.addAllKeys( allKeysCache, getBaseTheme() );
|
||||
|
||||
return allKeysCache;
|
||||
}
|
||||
|
||||
private String getBaseTheme() {
|
||||
if( baseTheme == null )
|
||||
baseTheme = getProperties().getProperty( "@baseTheme", "light" );
|
||||
return baseTheme;
|
||||
}
|
||||
|
||||
private void clearCache() {
|
||||
propertiesCache = null;
|
||||
parsedValueCache.clear();
|
||||
allKeysCache = null;
|
||||
baseTheme = null;
|
||||
|
||||
// increase global cache invalidation counter to allow auto-clear caches
|
||||
globalCacheInvalidationCounter++;
|
||||
cacheInvalidationCounter = globalCacheInvalidationCounter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear caches that may depend on other editors if cache of another editor was invalidated.
|
||||
*/
|
||||
private void autoClearCache() {
|
||||
if( cacheInvalidationCounter == globalCacheInvalidationCounter )
|
||||
return;
|
||||
|
||||
parsedValueCache.clear();
|
||||
allKeysCache = null;
|
||||
}
|
||||
|
||||
//---- interface DocumentListener ----
|
||||
@@ -233,4 +227,11 @@ class FlatThemePropertiesSupport
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
//---- interface BasePropertyProvider -------------------------------------
|
||||
|
||||
interface BasePropertyProvider {
|
||||
String getProperty( String key, String baseTheme );
|
||||
void addAllKeys( Set<String> allKeys, String baseTheme );
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user