Theme Editor: "Insert Color" dialog now immediately updates editor with new color, which updates "live" preview; also save/restore location of dialog

This commit is contained in:
Karl Tauber
2021-08-23 14:41:53 +02:00
parent 60322be22a
commit 506543281e
2 changed files with 68 additions and 11 deletions

View File

@@ -33,6 +33,7 @@ import org.fife.ui.rsyntaxtextarea.TextEditorPane;
import org.fife.ui.rsyntaxtextarea.Token; import org.fife.ui.rsyntaxtextarea.Token;
import org.fife.ui.rtextarea.RTextArea; import org.fife.ui.rtextarea.RTextArea;
import org.fife.ui.rtextarea.RTextAreaUI; import org.fife.ui.rtextarea.RTextAreaUI;
import org.fife.ui.rtextarea.RUndoManager;
import com.formdev.flatlaf.UIDefaultsLoaderAccessor; import com.formdev.flatlaf.UIDefaultsLoaderAccessor;
import com.formdev.flatlaf.themeeditor.FlatSyntaxTextAreaActions.InsertColorAction; import com.formdev.flatlaf.themeeditor.FlatSyntaxTextAreaActions.InsertColorAction;
import com.formdev.flatlaf.themeeditor.FlatSyntaxTextAreaActions.DuplicateLinesAction; import com.formdev.flatlaf.themeeditor.FlatSyntaxTextAreaActions.DuplicateLinesAction;
@@ -46,6 +47,7 @@ import com.formdev.flatlaf.themeeditor.FlatSyntaxTextAreaActions.IncrementNumber
class FlatSyntaxTextArea class FlatSyntaxTextArea
extends TextEditorPane extends TextEditorPane
{ {
private RUndoManager undoManager;
private boolean useColorOfColorTokens; private boolean useColorOfColorTokens;
final FlatThemePropertiesSupport propertiesSupport = new FlatThemePropertiesSupport( this ); final FlatThemePropertiesSupport propertiesSupport = new FlatThemePropertiesSupport( this );
@@ -84,6 +86,21 @@ class FlatSyntaxTextArea
return new FlatRSyntaxTextAreaUI( this ); return new FlatRSyntaxTextAreaUI( this );
} }
@Override
protected RUndoManager createUndoManager() {
undoManager = super.createUndoManager();
return undoManager;
}
void runWithoutUndo( Runnable runnable ) {
getDocument().removeUndoableEditListener( undoManager );
try {
runnable.run();
} finally {
getDocument().addUndoableEditListener( undoManager );
}
}
boolean isUseColorOfColorTokens() { boolean isUseColorOfColorTokens() {
return useColorOfColorTokens; return useColorOfColorTokens;
} }

View File

@@ -18,8 +18,11 @@ package com.formdev.flatlaf.themeeditor;
import java.awt.Color; import java.awt.Color;
import java.awt.Component; import java.awt.Component;
import java.awt.Point;
import java.awt.Window; import java.awt.Window;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.prefs.Preferences; import java.util.prefs.Preferences;
import javax.swing.JColorChooser; import javax.swing.JColorChooser;
import javax.swing.JDialog; import javax.swing.JDialog;
@@ -277,6 +280,8 @@ class FlatSyntaxTextAreaActions
{ {
private static final String KEY_SELECTED_TAB = "colorchooser.selectedTab"; private static final String KEY_SELECTED_TAB = "colorchooser.selectedTab";
private static Point lastLocation;
InsertColorAction( String name ) { InsertColorAction( String name ) {
super( name ); super( name );
} }
@@ -288,18 +293,19 @@ class FlatSyntaxTextAreaActions
Color currentColor = Color.white; Color currentColor = Color.white;
int caretPosition = textArea.getCaretPosition(); int caretPosition = textArea.getCaretPosition();
int start; int start;
int len; int len = 0;
String oldStr;
int[] result = findColorAt( textArea, caretPosition ); int[] result = findColorAt( textArea, caretPosition );
if( result != null ) { if( result != null ) {
start = result[0]; start = result[0];
len = result[1]; len = result[1];
String str = textArea.getText( start, len ); oldStr = textArea.getText( start, len );
int rgb = UIDefaultsLoaderAccessor.parseColorRGBA( str ); int rgb = UIDefaultsLoaderAccessor.parseColorRGBA( oldStr );
currentColor = new Color( rgb, true ); currentColor = new Color( rgb, true );
} else { } else {
start = caretPosition; start = caretPosition;
len = 0; oldStr = "";
} }
// create color chooser // create color chooser
@@ -310,17 +316,51 @@ class FlatSyntaxTextAreaActions
if( tabbedPane instanceof JTabbedPane && selectedTab >= 0 && selectedTab < ((JTabbedPane)tabbedPane).getTabCount() ) if( tabbedPane instanceof JTabbedPane && selectedTab >= 0 && selectedTab < ((JTabbedPane)tabbedPane).getTabCount() )
((JTabbedPane)tabbedPane).setSelectedIndex( selectedTab ); ((JTabbedPane)tabbedPane).setSelectedIndex( selectedTab );
// update editor immediately for live preview
AtomicInteger length = new AtomicInteger( len );
AtomicBoolean changed = new AtomicBoolean();
chooser.getSelectionModel().addChangeListener( e2 -> {
String str = colorToString( chooser.getColor() );
((FlatSyntaxTextArea)textArea).runWithoutUndo( () -> {
textArea.replaceRange( str, start, start + length.get() );
} );
length.set( str.length() );
changed.set( true );
} );
Runnable restore = () -> {
if( changed.get() ) {
((FlatSyntaxTextArea)textArea).runWithoutUndo( () -> {
textArea.replaceRange( oldStr, start, start + length.get() );
} );
length.set( oldStr.length() );
}
};
// show color chooser dialog // show color chooser dialog
Window window = SwingUtilities.windowForComponent( textArea ); Window window = SwingUtilities.windowForComponent( textArea );
JDialog dialog = JColorChooser.createDialog( window, "Insert Color", true, chooser, e2 -> { JDialog dialog = JColorChooser.createDialog( window, "Insert Color", true, chooser,
// okListener
e2 -> {
// restore original string
restore.run();
// update editor // update editor
textArea.replaceRange( colorToString( chooser.getColor() ), start, start + len ); textArea.replaceRange( colorToString( chooser.getColor() ), start, start + length.get() );
// remember selected tab // remember selected tab
if( tabbedPane instanceof JTabbedPane ) if( tabbedPane instanceof JTabbedPane )
state.putInt( KEY_SELECTED_TAB, ((JTabbedPane)tabbedPane).getSelectedIndex() ); state.putInt( KEY_SELECTED_TAB, ((JTabbedPane)tabbedPane).getSelectedIndex() );
}, null ); },
// cancelListener
e2 -> {
// restore original string
restore.run();
} );
if( lastLocation != null )
dialog.setLocation( lastLocation );
dialog.setVisible( true ); dialog.setVisible( true );
lastLocation = dialog.getLocation();
} catch( BadLocationException | IndexOutOfBoundsException | NumberFormatException ex ) { } catch( BadLocationException | IndexOutOfBoundsException | NumberFormatException ex ) {
ex.printStackTrace(); ex.printStackTrace();
} }