mirror of
https://github.com/JFormDesigner/FlatLaf.git
synced 2026-02-11 06:27:13 -06:00
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:
@@ -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" )
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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 )
|
||||
|
||||
Reference in New Issue
Block a user