mirror of
https://github.com/JFormDesigner/FlatLaf.git
synced 2025-12-08 15:00:54 +03:00
Theme Editor:
- added "New Properties File" action to "File" menu - added "+" button to tabbed pane - ask to create .properties files when opening a directory that does not contain .properties files - fixed Darcula baseTheme/preview
This commit is contained in:
@@ -26,7 +26,10 @@ import java.awt.Rectangle;
|
|||||||
import java.awt.Toolkit;
|
import java.awt.Toolkit;
|
||||||
import java.awt.event.*;
|
import java.awt.event.*;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStreamWriter;
|
||||||
|
import java.io.Writer;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
@@ -36,9 +39,12 @@ import java.util.Locale;
|
|||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
import java.util.prefs.Preferences;
|
import java.util.prefs.Preferences;
|
||||||
|
import javax.lang.model.SourceVersion;
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import net.miginfocom.swing.*;
|
import net.miginfocom.swing.*;
|
||||||
|
import com.formdev.flatlaf.FlatDarculaLaf;
|
||||||
import com.formdev.flatlaf.FlatDarkLaf;
|
import com.formdev.flatlaf.FlatDarkLaf;
|
||||||
|
import com.formdev.flatlaf.FlatIntelliJLaf;
|
||||||
import com.formdev.flatlaf.FlatLaf;
|
import com.formdev.flatlaf.FlatLaf;
|
||||||
import com.formdev.flatlaf.FlatLightLaf;
|
import com.formdev.flatlaf.FlatLightLaf;
|
||||||
import com.formdev.flatlaf.extras.FlatInspector;
|
import com.formdev.flatlaf.extras.FlatInspector;
|
||||||
@@ -107,6 +113,15 @@ public class FlatThemeFileEditor
|
|||||||
if( UIManager.getLookAndFeel() instanceof FlatDarkLaf )
|
if( UIManager.getLookAndFeel() instanceof FlatDarkLaf )
|
||||||
darkLafMenuItem.setSelected( true );
|
darkLafMenuItem.setSelected( true );
|
||||||
|
|
||||||
|
// add "+" button to tabbed pane
|
||||||
|
JButton newButton = new JButton( new FlatSVGIcon( "com/formdev/flatlaf/themeeditor/icons/add.svg" ) );
|
||||||
|
newButton.setToolTipText( "New Properties File" );
|
||||||
|
newButton.addActionListener( e -> newPropertiesFile() );
|
||||||
|
JToolBar trailingToolBar = new JToolBar();
|
||||||
|
trailingToolBar.setFloatable( false );
|
||||||
|
trailingToolBar.add( newButton );
|
||||||
|
tabbedPane.setTrailingComponent( trailingToolBar );
|
||||||
|
|
||||||
restoreState();
|
restoreState();
|
||||||
restoreWindowBounds();
|
restoreWindowBounds();
|
||||||
|
|
||||||
@@ -158,9 +173,30 @@ public class FlatThemeFileEditor
|
|||||||
}
|
}
|
||||||
|
|
||||||
if( getPropertiesFiles( dir ).length == 0 ) {
|
if( getPropertiesFiles( dir ).length == 0 ) {
|
||||||
|
UIManager.put( "OptionPane.sameSizeButtons", false );
|
||||||
|
int result = JOptionPane.showOptionDialog( parentComponent,
|
||||||
|
"Directory '" + dir + "' does not contain properties files.\n\n"
|
||||||
|
+ "Do you want create a new theme in this directory?\n\n"
|
||||||
|
+ "Or do you want modify/extend core themes and create empty"
|
||||||
|
+ " 'FlatLightLaf.properties' and 'FlatDarkLaf.properties' files in this directory?",
|
||||||
|
getTitle(), JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE, null,
|
||||||
|
new Object[] { "New Theme", "Modify Core Themes", "Cancel" }, null );
|
||||||
|
UIManager.put( "OptionPane.sameSizeButtons", null );
|
||||||
|
|
||||||
|
if( result == 0 )
|
||||||
|
return newPropertiesFile( dir );
|
||||||
|
else if( result == 1 ) {
|
||||||
|
try {
|
||||||
|
new File( dir, "FlatLightLaf.properties" ).createNewFile();
|
||||||
|
new File( dir, "FlatDarkLaf.properties" ).createNewFile();
|
||||||
|
return true;
|
||||||
|
} catch( IOException ex ) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
|
||||||
JOptionPane.showMessageDialog( parentComponent,
|
JOptionPane.showMessageDialog( parentComponent,
|
||||||
"Directory '" + dir + "' does not contain properties files.",
|
"Failed to create 'FlatLightLaf.properties' or 'FlatDarkLaf.properties'." );
|
||||||
getTitle(), JOptionPane.INFORMATION_MESSAGE );
|
}
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -319,6 +355,100 @@ public class FlatThemeFileEditor
|
|||||||
putPrefsString( state, KEY_RECENT_FILE, filename );
|
putPrefsString( state, KEY_RECENT_FILE, filename );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean newPropertiesFile() {
|
||||||
|
return newPropertiesFile( dir );
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean newPropertiesFile( File dir ) {
|
||||||
|
String title = "New Properties File";
|
||||||
|
JTextField themeNameField = new JTextField();
|
||||||
|
JComboBox<String> baseThemeField = new JComboBox<>( new String[] {
|
||||||
|
FlatLightLaf.NAME,
|
||||||
|
FlatDarkLaf.NAME,
|
||||||
|
FlatIntelliJLaf.NAME,
|
||||||
|
FlatDarculaLaf.NAME,
|
||||||
|
} );
|
||||||
|
|
||||||
|
JOptionPane optionPane = new JOptionPane( new Object[] {
|
||||||
|
new JLabel( "Theme name:" ),
|
||||||
|
themeNameField,
|
||||||
|
new JLabel( "Base Theme:" ),
|
||||||
|
baseThemeField,
|
||||||
|
}, JOptionPane.PLAIN_MESSAGE, JOptionPane.OK_CANCEL_OPTION ) {
|
||||||
|
@Override
|
||||||
|
public void selectInitialValue() {
|
||||||
|
super.selectInitialValue();
|
||||||
|
themeNameField.requestFocusInWindow();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setValue( Object newValue ) {
|
||||||
|
if( Objects.equals( newValue, JOptionPane.OK_OPTION ) ) {
|
||||||
|
String themeName = themeNameField.getText().trim();
|
||||||
|
if( themeName.isEmpty() )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if( !SourceVersion.isIdentifier( themeName ) ) {
|
||||||
|
JOptionPane.showMessageDialog( this,
|
||||||
|
"'" + themeName + "' is not a valid Java identifier.",
|
||||||
|
title, JOptionPane.INFORMATION_MESSAGE );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
File file = new File( dir, themeName + ".properties" );
|
||||||
|
if( file.exists() ) {
|
||||||
|
JOptionPane.showMessageDialog( this, "Theme '" + themeName + "' already exists.", title, JOptionPane.INFORMATION_MESSAGE );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
createTheme( file, (String) baseThemeField.getSelectedItem() );
|
||||||
|
openFile( file, true );
|
||||||
|
} catch( IOException ex ) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
|
||||||
|
JOptionPane.showMessageDialog( this,
|
||||||
|
"Failed to create '" + file + "'." );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
super.setValue( newValue );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
JDialog dialog = optionPane.createDialog( this, title );
|
||||||
|
dialog.setVisible( true );
|
||||||
|
|
||||||
|
return Objects.equals( optionPane.getValue(), JOptionPane.OK_OPTION );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createTheme( File file, String baseTheme )
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
StringBuilder buf = new StringBuilder();
|
||||||
|
buf.append( "# base theme (light, dark, intellij or darcula)\n" );
|
||||||
|
switch( baseTheme ) {
|
||||||
|
case FlatLightLaf.NAME: buf.append( "@baseTheme = light\n" ); break;
|
||||||
|
case FlatDarkLaf.NAME: buf.append( "@baseTheme = dark\n" ); break;
|
||||||
|
case FlatIntelliJLaf.NAME: buf.append( "@baseTheme = intellij\n" ); break;
|
||||||
|
case FlatDarculaLaf.NAME: buf.append( "@baseTheme = darcula\n" ); break;
|
||||||
|
}
|
||||||
|
|
||||||
|
writeFile( file, buf.toString() );
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void writeFile( File file, String content )
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
try(
|
||||||
|
FileOutputStream out = new FileOutputStream( file );
|
||||||
|
Writer writer = new OutputStreamWriter( out, "UTF-8" );
|
||||||
|
) {
|
||||||
|
writer.write( content );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private boolean saveAll() {
|
private boolean saveAll() {
|
||||||
for( FlatThemeEditorPane themeEditorPane : getThemeEditorPanes() ) {
|
for( FlatThemeEditorPane themeEditorPane : getThemeEditorPanes() ) {
|
||||||
if( !themeEditorPane.saveIfDirty() )
|
if( !themeEditorPane.saveIfDirty() )
|
||||||
@@ -568,6 +698,7 @@ public class FlatThemeFileEditor
|
|||||||
menuBar = new JMenuBar();
|
menuBar = new JMenuBar();
|
||||||
fileMenu = new JMenu();
|
fileMenu = new JMenu();
|
||||||
openDirectoryMenuItem = new JMenuItem();
|
openDirectoryMenuItem = new JMenuItem();
|
||||||
|
newPropertiesFileMenuItem = new JMenuItem();
|
||||||
saveAllMenuItem = new JMenuItem();
|
saveAllMenuItem = new JMenuItem();
|
||||||
exitMenuItem = new JMenuItem();
|
exitMenuItem = new JMenuItem();
|
||||||
editMenu = new JMenu();
|
editMenu = new JMenu();
|
||||||
@@ -626,6 +757,13 @@ public class FlatThemeFileEditor
|
|||||||
openDirectoryMenuItem.addActionListener(e -> openDirectory());
|
openDirectoryMenuItem.addActionListener(e -> openDirectory());
|
||||||
fileMenu.add(openDirectoryMenuItem);
|
fileMenu.add(openDirectoryMenuItem);
|
||||||
|
|
||||||
|
//---- newPropertiesFileMenuItem ----
|
||||||
|
newPropertiesFileMenuItem.setText("New Properties File");
|
||||||
|
newPropertiesFileMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N, KeyEvent.CTRL_DOWN_MASK));
|
||||||
|
newPropertiesFileMenuItem.setMnemonic('N');
|
||||||
|
newPropertiesFileMenuItem.addActionListener(e -> newPropertiesFile());
|
||||||
|
fileMenu.add(newPropertiesFileMenuItem);
|
||||||
|
|
||||||
//---- saveAllMenuItem ----
|
//---- saveAllMenuItem ----
|
||||||
saveAllMenuItem.setText("Save All");
|
saveAllMenuItem.setText("Save All");
|
||||||
saveAllMenuItem.setMnemonic('S');
|
saveAllMenuItem.setMnemonic('S');
|
||||||
@@ -800,6 +938,7 @@ public class FlatThemeFileEditor
|
|||||||
private JMenuBar menuBar;
|
private JMenuBar menuBar;
|
||||||
private JMenu fileMenu;
|
private JMenu fileMenu;
|
||||||
private JMenuItem openDirectoryMenuItem;
|
private JMenuItem openDirectoryMenuItem;
|
||||||
|
private JMenuItem newPropertiesFileMenuItem;
|
||||||
private JMenuItem saveAllMenuItem;
|
private JMenuItem saveAllMenuItem;
|
||||||
private JMenuItem exitMenuItem;
|
private JMenuItem exitMenuItem;
|
||||||
private JMenu editMenu;
|
private JMenu editMenu;
|
||||||
|
|||||||
@@ -65,6 +65,13 @@ new FormModel {
|
|||||||
"accelerator": static javax.swing.KeyStroke getKeyStroke( 79, 4226, false )
|
"accelerator": static javax.swing.KeyStroke getKeyStroke( 79, 4226, false )
|
||||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "openDirectory", false ) )
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "openDirectory", false ) )
|
||||||
} )
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JMenuItem" ) {
|
||||||
|
name: "newPropertiesFileMenuItem"
|
||||||
|
"text": "New Properties File"
|
||||||
|
"accelerator": static javax.swing.KeyStroke getKeyStroke( 78, 130, false )
|
||||||
|
"mnemonic": 78
|
||||||
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "newPropertiesFile", false ) )
|
||||||
|
} )
|
||||||
add( new FormComponent( "javax.swing.JMenuItem" ) {
|
add( new FormComponent( "javax.swing.JMenuItem" ) {
|
||||||
name: "saveAllMenuItem"
|
name: "saveAllMenuItem"
|
||||||
"text": "Save All"
|
"text": "Save All"
|
||||||
|
|||||||
@@ -130,7 +130,7 @@ class FlatThemePropertiesBaseManager
|
|||||||
|
|
||||||
case "darcula":
|
case "darcula":
|
||||||
result.add( "FlatDarculaLaf" );
|
result.add( "FlatDarculaLaf" );
|
||||||
result.add( "FlatLightLaf" );
|
result.add( "FlatDarkLaf" );
|
||||||
result.add( "FlatLaf" );
|
result.add( "FlatLaf" );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user