Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import com.codename1.ui.Button;
import com.codename1.ui.ButtonGroup;
import com.codename1.ui.CheckBox;
import com.codename1.ui.spinner.Picker;
import com.codename1.ui.Component;
import com.codename1.ui.Container;
import com.codename1.ui.Dialog;
Expand Down Expand Up @@ -47,6 +48,8 @@ public void runApp() {
final ProjectOptions.ThemeMode[] selectedThemeMode = new ProjectOptions.ThemeMode[]{ProjectOptions.ThemeMode.LIGHT};
final ProjectOptions.Accent[] selectedAccent = new ProjectOptions.Accent[]{ProjectOptions.Accent.DEFAULT};
final boolean[] roundedButtons = new boolean[]{true};
final boolean[] includeLocalizationBundles = new boolean[]{true};
final ProjectOptions.PreviewLanguage[] previewLanguage = new ProjectOptions.PreviewLanguage[]{ProjectOptions.PreviewLanguage.ENGLISH};
final RadioButton[] templateButtons = new RadioButton[Template.values().length];
final SpanLabel summaryLabel = new SpanLabel();
final TemplatePreviewPanel previewPanel = new TemplatePreviewPanel(selectedTemplate[0]);
Expand All @@ -64,7 +67,10 @@ public void runApp() {

final Runnable refresh = new Runnable() {
public void run() {
ProjectOptions options = new ProjectOptions(selectedThemeMode[0], selectedAccent[0], roundedButtons[0]);
ProjectOptions options = new ProjectOptions(
selectedThemeMode[0], selectedAccent[0], roundedButtons[0],
includeLocalizationBundles[0], previewLanguage[0]
);
previewPanel.setTemplate(selectedTemplate[0]);
previewPanel.setOptions(options);
boolean canCustomizeTheme = supportsLivePreview(selectedTemplate[0]);
Expand Down Expand Up @@ -92,12 +98,14 @@ public void run() {
);
final Container idePanel = createIdeSelectorPanel(selectedIde, refresh);
final Container themePanel = createThemeOptionsPanel(selectedThemeMode, selectedAccent, roundedButtons, refresh);
final Container localizationPanel = createLocalizationPanel(includeLocalizationBundles, previewLanguage, refresh, previewPanel);
themePanelRef[0] = themePanel;
final Container settingsPanel = BoxLayout.encloseY(summaryLabel);

Accordion advancedAccordion = new Accordion();
advancedAccordion.addContent("IDE", idePanel);
advancedAccordion.addContent("Theme Customization", themePanel);
advancedAccordion.addContent("Localization", localizationPanel);
advancedAccordion.addContent("Current Settings", settingsPanel);
advancedAccordion.setAutoClose(false);
advancedAccordion.setScrollable(false);
Expand All @@ -123,7 +131,10 @@ public void run() {
}
String appName = appNameField.getText() == null ? "" : appNameField.getText().trim();
String packageName = packageField.getText() == null ? "" : packageField.getText().trim();
ProjectOptions options = new ProjectOptions(selectedThemeMode[0], selectedAccent[0], roundedButtons[0]);
ProjectOptions options = new ProjectOptions(
selectedThemeMode[0], selectedAccent[0], roundedButtons[0],
includeLocalizationBundles[0], previewLanguage[0]
);
GeneratorModel.create(selectedIde[0], selectedTemplate[0], appName, packageName, options).generate();
});

Expand All @@ -141,6 +152,39 @@ public void run() {
form.show();
}

private Container createLocalizationPanel(boolean[] includeLocalizationBundles,
ProjectOptions.PreviewLanguage[] previewLanguage,
Runnable onSelectionChanged,
TemplatePreviewPanel previewPanel) {
CheckBox includeBundles = new CheckBox("Include Resource Bundles");
includeBundles.setUIID("InitializrChoice");
includeBundles.setSelected(includeLocalizationBundles[0]);

Picker languagePicker = new Picker();
languagePicker.setUIID("InitializrField");
String[] labels = new String[ProjectOptions.PreviewLanguage.values().length];
for (int i = 0; i < labels.length; i++) {
labels[i] = ProjectOptions.PreviewLanguage.values()[i].label;
}
languagePicker.setStrings(labels);
languagePicker.setSelectedString(previewLanguage[0].label);

includeBundles.addActionListener(e -> {
includeLocalizationBundles[0] = includeBundles.isSelected();
languagePicker.setEnabled(includeBundles.isSelected());
onSelectionChanged.run();
});
languagePicker.setEnabled(includeBundles.isSelected());
languagePicker.addActionListener(e -> {
String selected = languagePicker.getSelectedString();
previewLanguage[0] = findLanguageByLabel(selected);
onSelectionChanged.run();
previewPanel.showUpdatedLivePreview();
});

return BoxLayout.encloseY(includeBundles, labeledField("Preview Language", languagePicker));
}

private Container createHeader() {
Label title = new Label("Initializr - Scaffold a Project in Seconds");
title.setUIID("InitializrHeroTitle");
Expand Down Expand Up @@ -319,6 +363,16 @@ private Container labeledFieldWithHelp(String label, Component input, String hel
return BoxLayout.encloseY(header, input);
}


private ProjectOptions.PreviewLanguage findLanguageByLabel(String label) {
for (ProjectOptions.PreviewLanguage language : ProjectOptions.PreviewLanguage.values()) {
if (language.label.equals(label)) {
return language;
}
}
return ProjectOptions.PreviewLanguage.ENGLISH;
}

private String formatEnumLabel(String text) {
if ("DEFAULT".equals(text)) {
return "Clean";
Expand Down Expand Up @@ -445,6 +499,8 @@ private String createSummary(String appName, String packageName, Template templa
+ "Theme: " + options.themeMode.name() + "\n"
+ "Accent: " + options.accent.name() + "\n"
+ "Rounded Buttons: " + (options.roundedButtons ? "Yes" : "No") + "\n"
+ "Localization Bundles: " + (options.includeLocalizationBundles ? "Yes" : "No") + "\n"
+ "Preview Language: " + options.previewLanguage.label + "\n"
+ "Kotlin: " + (template.IS_KOTLIN ? "Yes" : "No");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ void writeProjectZip(OutputStream outputStream) throws IOException {
}
copyZipEntriesToMap(template.CSS, mergedEntries, ZipEntryType.TEMPLATE_CSS);
copyZipEntriesToMap(template.SOURCE_ZIP, mergedEntries, ZipEntryType.TEMPLATE_SOURCE);
addLocalizationEntries(mergedEntries);

try (ZipOutputStream zos = new ZipOutputStream(outputStream)) {
for (Map.Entry<String, byte[]> fileEntry : mergedEntries.entrySet()) {
Expand All @@ -84,6 +85,30 @@ void writeProjectZip(OutputStream outputStream) throws IOException {
}
}


private void addLocalizationEntries(Map<String, byte[]> mergedEntries) throws IOException {
if (!isBareTemplate() || !options.includeLocalizationBundles) {
return;
}
copySingleTextEntryToMap(
"common/src/main/resources/messages.properties",
readResourceToString("/messages.properties"),
mergedEntries,
ZipEntryType.COMMON
);
for (ProjectOptions.PreviewLanguage language : ProjectOptions.PreviewLanguage.values()) {
if (language == ProjectOptions.PreviewLanguage.ENGLISH) {
continue;
}
copySingleTextEntryToMap(
"common/src/main/resources/messages_" + language.bundleSuffix + ".properties",
readResourceToString("/messages_" + language.bundleSuffix + ".properties"),
mergedEntries,
ZipEntryType.COMMON
);
}
}

private void copyZipEntriesToMap(String zipResource, Map<String, byte[]> mergedEntries, ZipEntryType zipType) throws IOException {
try(ZipInputStream zis = new ZipInputStream(getResourceAsStream(zipResource))) {
ZipEntry entry = zis.getNextEntry();
Expand Down Expand Up @@ -155,6 +180,9 @@ private byte[] applyDataReplacements(String targetPath, byte[] sourceData) throw
if ("common/codenameone_settings.properties".equals(targetPath)) {
content = replaceProperty(content, "codename1.kotlin", String.valueOf(template.IS_KOTLIN));
}
if (options.includeLocalizationBundles && isBareTemplate()) {
content = injectLocalizationBootstrap(targetPath, content);
}
if (isBareTemplate() && "common/src/main/css/theme.css".equals(targetPath)) {
content += buildThemeOverrides();
}
Expand All @@ -167,6 +195,54 @@ private byte[] applyDataReplacements(String targetPath, byte[] sourceData) throw
return content.getBytes("UTF-8");
}


private String injectLocalizationBootstrap(String targetPath, String content) {
String javaMainPath = "common/src/main/java/" + packageName.replace('.', '/') + "/" + appName + ".java";
String kotlinMainPath = "common/src/main/kotlin/" + packageName.replace('.', '/') + "/" + appName + ".kt";
if (javaMainPath.equals(targetPath)) {
return injectJavaLocalizationBootstrap(content);
}
if (kotlinMainPath.equals(targetPath)) {
return injectKotlinLocalizationBootstrap(content);
}
return content;
}

private String injectJavaLocalizationBootstrap(String content) {
if (content.indexOf("setBundle(") >= 0) {
return content;
}
content = StringUtil.replaceAll(content, "import static com.codename1.ui.CN.*;\n", "import static com.codename1.ui.CN.*;\nimport com.codename1.l10n.L10NManager;\nimport com.codename1.ui.plaf.UIManager;\nimport java.util.Hashtable;\n");
String method = "\n @Override\n"
+ " public void init(Object context) {\n"
+ " String language = L10NManager.getInstance().getLanguage();\n"
+ " Hashtable<String, String> bundle = Resources.getGlobalResources().getL10N(\"messages\", language);\n"
+ " UIManager.getInstance().setBundle(bundle);\n"
+ " }\n\n";
int firstBrace = content.indexOf('{');
if (firstBrace > -1) {
return content.substring(0, firstBrace + 1) + method + content.substring(firstBrace + 1);
}
return content;
}

private String injectKotlinLocalizationBootstrap(String content) {
if (content.indexOf("setBundle(") >= 0) {
return content;
}
content = StringUtil.replaceAll(content, "import com.codename1.system.Lifecycle\n", "import com.codename1.system.Lifecycle\nimport com.codename1.l10n.L10NManager\nimport com.codename1.ui.plaf.UIManager\nimport com.codename1.ui.util.Resources\nimport java.util.Hashtable\n");
String method = "\n override fun init(context: Any?) {\n"
+ " val language = L10NManager.getInstance().language\n"
+ " val bundle: Hashtable<String, String>? = Resources.getGlobalResources().getL10N(\"messages\", language)\n"
+ " UIManager.getInstance().setBundle(bundle)\n"
+ " }\n\n";
int firstBrace = content.indexOf('{');
if (firstBrace > -1) {
return content.substring(0, firstBrace + 1) + method + content.substring(firstBrace + 1);
}
return content;
}

private static String replaceTagValue(String xml, String tagName, String value) {
String open = "<" + tagName + ">";
String close = "</" + tagName + ">";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,36 @@
package com.codename1.initializr.model;

public final class ProjectOptions {
public enum PreviewLanguage {
ENGLISH("English", "en", false),
FRENCH("Fran\u00e7ais", "fr", false),
GERMAN("Deutsch", "de", false),
SPANISH("Espa\u00f1ol", "es", false),
ITALIAN("Italiano", "it", false),
PORTUGUESE("Portugu\u00eas", "pt", false),
DUTCH("Nederlands", "nl", false),
CHINESE_SIMPLIFIED("\u4e2d\u6587 (\u7b80\u4f53)", "zh_CN", false),
JAPANESE("\u65e5\u672c\u8a9e", "ja", false),
KOREAN("\ud55c\uad6d\uc5b4", "ko", false),
ARABIC("\u0627\u0644\u0639\u0631\u0628\u064a\u0629", "ar", true),
HEBREW("\u05e2\u05d1\u05e8\u05d9\u05ea", "he", true);

public final String label;
public final String bundleSuffix;
public final boolean rtl;

PreviewLanguage(String label, String bundleSuffix, boolean rtl) {
this.label = label;
this.bundleSuffix = bundleSuffix;
this.rtl = rtl;
}

@Override
public String toString() {
return label;
}
}

public enum ThemeMode {
LIGHT,
DARK
Expand All @@ -16,14 +46,19 @@ public enum Accent {
public final ThemeMode themeMode;
public final Accent accent;
public final boolean roundedButtons;
public final boolean includeLocalizationBundles;
public final PreviewLanguage previewLanguage;

public ProjectOptions(ThemeMode themeMode, Accent accent, boolean roundedButtons) {
public ProjectOptions(ThemeMode themeMode, Accent accent, boolean roundedButtons,
boolean includeLocalizationBundles, PreviewLanguage previewLanguage) {
this.themeMode = themeMode;
this.accent = accent;
this.roundedButtons = roundedButtons;
this.includeLocalizationBundles = includeLocalizationBundles;
this.previewLanguage = previewLanguage == null ? PreviewLanguage.ENGLISH : previewLanguage;
}

public static ProjectOptions defaults() {
return new ProjectOptions(ThemeMode.LIGHT, Accent.DEFAULT, true);
return new ProjectOptions(ThemeMode.LIGHT, Accent.DEFAULT, true, true, PreviewLanguage.ENGLISH);
}
}
Loading
Loading