Theme Editor:

- open all .properties files in passed directory in tabs
- basic menu bar added (Save, Exit)
- auto-save files on window deactivation and app exit
This commit is contained in:
Karl Tauber
2020-12-28 20:38:48 +01:00
parent 4c885c5e7b
commit 678b879a01
4 changed files with 235 additions and 44 deletions

View File

@@ -18,10 +18,18 @@ plugins {
`java-library`
}
repositories {
maven {
// for using MigLayout snapshot
url = uri( "https://oss.sonatype.org/content/repositories/snapshots/" )
}
}
dependencies {
implementation( project( ":flatlaf-core" ) )
implementation( project( ":flatlaf-extras" ) )
implementation( "com.miglayout:miglayout-swing:5.3-SNAPSHOT" )
implementation( "com.fifesoft:rsyntaxtextarea:3.1.1" )
implementation( "com.fifesoft:autocomplete:3.1.0" )
}

View File

@@ -31,6 +31,7 @@ import org.fife.ui.autocomplete.CompletionProvider;
import org.fife.ui.rsyntaxtextarea.AbstractTokenMakerFactory;
import org.fife.ui.rsyntaxtextarea.FileLocation;
import org.fife.ui.rsyntaxtextarea.SyntaxScheme;
import org.fife.ui.rsyntaxtextarea.TextEditorPane;
import org.fife.ui.rsyntaxtextarea.Theme;
import org.fife.ui.rsyntaxtextarea.TokenMakerFactory;
import org.fife.ui.rtextarea.RTextScrollPane;
@@ -44,6 +45,8 @@ import com.formdev.flatlaf.util.UIScale;
class FlatThemeEditorPane
extends JPanel
{
static final String DIRTY_PROPERTY = TextEditorPane.DIRTY_PROPERTY;
private static final String FLATLAF_STYLE = "text/flatlaf";
private final RTextScrollPane scrollPane;
@@ -63,6 +66,10 @@ class FlatThemeEditorPane
textArea.addParser( new FlatThemeParser() );
// textArea.setUseColorOfColorTokens( true );
textArea.addPropertyChangeListener( TextEditorPane.DIRTY_PROPERTY, e -> {
firePropertyChange( DIRTY_PROPERTY, e.getOldValue(), e.getNewValue() );
} );
// theme
try( InputStream in = getClass().getResourceAsStream( "light.xml" ) ) {
Theme theme = Theme.load( in );
@@ -117,11 +124,15 @@ class FlatThemeEditorPane
textArea.load( loc, StandardCharsets.ISO_8859_1 );
}
void save() {
try {
textArea.save();
} catch( IOException ex ) {
ex.printStackTrace(); // TODO
}
void save() throws IOException {
textArea.save();
}
String getFileName() {
return textArea.getFileName();
}
boolean isDirty() {
return textArea.isDirty();
}
}

View File

@@ -20,16 +20,19 @@ import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.KeyEvent;
import java.awt.event.*;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Arrays;
import java.util.function.Supplier;
import javax.swing.*;
import com.formdev.flatlaf.extras.components.*;
import net.miginfocom.swing.*;
import org.fife.ui.rsyntaxtextarea.FileLocation;
import com.formdev.flatlaf.FlatLightLaf;
import com.formdev.flatlaf.extras.FlatInspector;
import com.formdev.flatlaf.extras.FlatUIDefaultsInspector;
import com.formdev.flatlaf.util.StringUtils;
import com.formdev.flatlaf.util.UIScale;
/**
@@ -41,13 +44,9 @@ public class FlatThemeFileEditor
extends JFrame
{
public static void main( String[] args ) {
File file = new File( args.length > 0
File dir = new File( args.length > 0
? args[0]
: "theme-editor-test.properties" ); // TODO
List<File> baseFiles = new ArrayList<>();
for( int i = 1; i < args.length; i++ )
baseFiles.add( new File( args[i] ) );
: "." );
SwingUtilities.invokeLater( () -> {
FlatLightLaf.install();
@@ -56,18 +55,7 @@ public class FlatThemeFileEditor
FlatThemeFileEditor frame = new FlatThemeFileEditor();
frame.themeEditorArea.setBaseFiles( baseFiles );
try {
frame.themeEditorArea.load( FileLocation.create( file ) );
} catch( IOException ex ) {
ex.printStackTrace();
}
int menuShortcutKeyMask = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
((JComponent)frame.getContentPane()).registerKeyboardAction(
e -> frame.themeEditorArea.save(),
KeyStroke.getKeyStroke( KeyEvent.VK_S, menuShortcutKeyMask ),
JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT );
frame.loadDirectory( dir );
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
frame.setSize( Math.min( UIScale.scale( 800 ), screenSize.width ),
@@ -81,28 +69,169 @@ public class FlatThemeFileEditor
initComponents();
}
public void loadDirectory( File dir ) {
try {
directoryField.setText( dir.getCanonicalPath() );
} catch( IOException ex ) {
directoryField.setText( dir.getAbsolutePath() );
}
File[] propertiesFiles = dir.listFiles( (d, name) -> {
return name.endsWith( ".properties" );
} );
Arrays.sort( propertiesFiles );
for( File file : propertiesFiles )
openFile( file );
}
public void openFile( File file ) {
FlatThemeEditorPane themeEditorArea = new FlatThemeEditorPane();
try {
themeEditorArea.load( FileLocation.create( file ) );
} catch( IOException ex ) {
ex.printStackTrace(); // TODO
}
Supplier<String> titleFun = () -> {
return (themeEditorArea.isDirty() ? "*" : "")
+ StringUtils.removeTrailing( themeEditorArea.getFileName(), ".properties" );
};
themeEditorArea.addPropertyChangeListener( FlatThemeEditorPane.DIRTY_PROPERTY, e -> {
int index = tabbedPane.indexOfComponent( themeEditorArea );
if( index >= 0 )
tabbedPane.setTitleAt( index, titleFun.get() );
} );
tabbedPane.addTab( titleFun.get(), null, themeEditorArea, file.getAbsolutePath() );
}
private boolean saveAll() {
for( FlatThemeEditorPane themeEditorPane : getThemeEditorPanes() ) {
try {
if( themeEditorPane.isDirty() )
themeEditorPane.save();
} catch( IOException ex ) {
JOptionPane.showMessageDialog( this,
"Failed to save '" + themeEditorPane.getFileName() + "'\n\nReason: " + ex.getMessage(),
getTitle(), JOptionPane.WARNING_MESSAGE );
return false;
}
}
return true;
}
private void exit() {
if( saveAll() )
System.exit( 0 );
}
private void windowClosing() {
exit();
}
private void windowDeactivated() {
saveAll();
}
private FlatThemeEditorPane[] getThemeEditorPanes() {
FlatThemeEditorPane[] result = new FlatThemeEditorPane[tabbedPane.getTabCount()];
for( int i = 0; i < result.length; i++ )
result[i] = (FlatThemeEditorPane) tabbedPane.getComponentAt( i );
return result;
}
private void initComponents() {
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
dialogPane = new JPanel();
themeEditorArea = new FlatThemeEditorPane();
menuBar = new JMenuBar();
fileMenu = new JMenu();
saveAllMenuItem = new JMenuItem();
exitMenuItem = new JMenuItem();
controlPanel = new JPanel();
directoryLabel = new JLabel();
directoryField = new JTextField();
tabbedPane = new FlatTabbedPane();
//======== this ========
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
setTitle("FlatLaf Theme Editor");
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
FlatThemeFileEditor.this.windowClosing();
}
@Override
public void windowDeactivated(WindowEvent e) {
FlatThemeFileEditor.this.windowDeactivated();
}
});
Container contentPane = getContentPane();
contentPane.setLayout(new BorderLayout());
//======== dialogPane ========
//======== menuBar ========
{
dialogPane.setLayout(new BorderLayout());
dialogPane.add(themeEditorArea, BorderLayout.CENTER);
//======== fileMenu ========
{
fileMenu.setText("File");
//---- saveAllMenuItem ----
saveAllMenuItem.setText("Save All");
saveAllMenuItem.setMnemonic('S');
saveAllMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
saveAllMenuItem.addActionListener(e -> saveAll());
fileMenu.add(saveAllMenuItem);
fileMenu.addSeparator();
//---- exitMenuItem ----
exitMenuItem.setText("Exit");
exitMenuItem.setMnemonic('X');
exitMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
exitMenuItem.addActionListener(e -> exit());
fileMenu.add(exitMenuItem);
}
menuBar.add(fileMenu);
}
contentPane.add(dialogPane, BorderLayout.CENTER);
setJMenuBar(menuBar);
//======== controlPanel ========
{
controlPanel.setLayout(new MigLayout(
"hidemode 3",
// columns
"[fill]" +
"[grow,fill]",
// rows
"[]"));
//---- directoryLabel ----
directoryLabel.setText("Directory:");
controlPanel.add(directoryLabel, "cell 0 0");
//---- directoryField ----
directoryField.setEditable(false);
controlPanel.add(directoryField, "cell 1 0");
}
contentPane.add(controlPanel, BorderLayout.NORTH);
//======== tabbedPane ========
{
tabbedPane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
}
contentPane.add(tabbedPane, BorderLayout.CENTER);
// JFormDesigner - End of component initialization //GEN-END:initComponents
}
// JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables
private JPanel dialogPane;
private FlatThemeEditorPane themeEditorArea;
private JMenuBar menuBar;
private JMenu fileMenu;
private JMenuItem saveAllMenuItem;
private JMenuItem exitMenuItem;
private JPanel controlPanel;
private JLabel directoryLabel;
private JTextField directoryField;
private FlatTabbedPane tabbedPane;
// JFormDesigner - End of variables declaration //GEN-END:variables
}

View File

@@ -1,4 +1,4 @@
JFDML JFormDesigner: "7.0.2.0.298" Java: "14" encoding: "UTF-8"
JFDML JFormDesigner: "7.0.3.1.342" Java: "15" encoding: "UTF-8"
new FormModel {
contentType: "form/swing"
@@ -7,18 +7,61 @@ new FormModel {
name: "this"
"$locationPolicy": 2
"$sizePolicy": 2
"defaultCloseOperation": 3
"defaultCloseOperation": 0
"title": "FlatLaf Theme Editor"
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class java.awt.BorderLayout ) ) {
name: "dialogPane"
add( new FormComponent( "com.formdev.flatlaf.themeeditor.FlatThemeEditorPane" ) {
name: "themeEditorArea"
}, new FormLayoutConstraints( class java.lang.String ) {
"value": "Center"
addEvent( new FormEvent( "java.awt.event.WindowListener", "windowClosing", "windowClosing", false ) )
addEvent( new FormEvent( "java.awt.event.WindowListener", "windowDeactivated", "windowDeactivated", false ) )
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
"$layoutConstraints": "hidemode 3"
"$columnConstraints": "[fill][grow,fill]"
"$rowConstraints": "[]"
} ) {
name: "controlPanel"
add( new FormComponent( "javax.swing.JLabel" ) {
name: "directoryLabel"
"text": "Directory:"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 0"
} )
add( new FormComponent( "javax.swing.JTextField" ) {
name: "directoryField"
"editable": false
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 0"
} )
}, new FormLayoutConstraints( class java.lang.String ) {
"value": "North"
} )
add( new FormContainer( "com.formdev.flatlaf.extras.components.FlatTabbedPane", new FormLayoutManager( class javax.swing.JTabbedPane ) ) {
name: "tabbedPane"
"tabLayoutPolicy": 1
}, new FormLayoutConstraints( class java.lang.String ) {
"value": "Center"
} )
menuBar: new FormContainer( "javax.swing.JMenuBar", new FormLayoutManager( class javax.swing.JMenuBar ) ) {
name: "menuBar"
add( new FormContainer( "javax.swing.JMenu", new FormLayoutManager( class javax.swing.JMenu ) ) {
name: "fileMenu"
"text": "File"
add( new FormComponent( "javax.swing.JMenuItem" ) {
name: "saveAllMenuItem"
"text": "Save All"
"mnemonic": 83
"accelerator": static javax.swing.KeyStroke getKeyStroke( 83, 4226, false )
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "saveAll", false ) )
} )
add( new FormComponent( "javax.swing.JPopupMenu$Separator" ) {
name: "separator1"
} )
add( new FormComponent( "javax.swing.JMenuItem" ) {
name: "exitMenuItem"
"text": "Exit"
"mnemonic": 88
"accelerator": static javax.swing.KeyStroke getKeyStroke( 81, 4226, false )
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "exit", false ) )
} )
} )
}
}, new FormLayoutConstraints( null ) {
"location": new java.awt.Point( 0, 0 )
"size": new java.awt.Dimension( 535, 300 )