/*
* SK's Minecraft Launcher
* Copyright (C) 2010-2014 Albert Pham <http://www.sk89q.com> and contributors
* Please see LICENSE.txt for license information.
*/
package com.skcraft.launcher.creator.dialog;
import com.google.common.base.Strings;
import com.jidesoft.swing.SearchableUtils;
import com.jidesoft.swing.TableSearchable;
import com.skcraft.launcher.builder.BuilderConfig;
import com.skcraft.launcher.builder.FeaturePattern;
import com.skcraft.launcher.builder.FnPatternList;
import com.skcraft.launcher.creator.model.swing.FeaturePatternTableModel;
import com.skcraft.launcher.model.modpack.LaunchModifier;
import com.skcraft.launcher.swing.SwingHelper;
import com.skcraft.launcher.swing.TextFieldPopupMenu;
import net.miginfocom.swing.MigLayout;
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
public class BuilderConfigDialog extends JDialog {
private final JTextField nameText = new JTextField(20);
private final JTextField titleText = new JTextField(30);
private final JTextField gameVersionText = new JTextField(10);
private final JTextArea launchFlagsArea = new JTextArea(10, 40);
private final JTextArea userFilesIncludeArea = new JTextArea(15, 40);
private final JTextArea userFilesExcludeArea = new JTextArea(8, 40);
private final FeaturePatternTable featuresTable = new FeaturePatternTable();
private FeaturePatternTableModel featuresModel;
private final BuilderConfig config;
private boolean saved = false;
public BuilderConfigDialog(Window parent, BuilderConfig config) {
super(parent, "Modpack Properties", ModalityType.DOCUMENT_MODAL);
this.config = config;
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
initComponents();
setResizable(false);
pack();
setLocationRelativeTo(parent);
copyFrom();
nameText.requestFocus();
}
private void initComponents() {
nameText.setComponentPopupMenu(TextFieldPopupMenu.INSTANCE);
titleText.setComponentPopupMenu(TextFieldPopupMenu.INSTANCE);
gameVersionText.setComponentPopupMenu(TextFieldPopupMenu.INSTANCE);
launchFlagsArea.setComponentPopupMenu(TextFieldPopupMenu.INSTANCE);
userFilesIncludeArea.setComponentPopupMenu(TextFieldPopupMenu.INSTANCE);
launchFlagsArea.setFont(nameText.getFont());
userFilesIncludeArea.setFont(nameText.getFont());
userFilesExcludeArea.setFont(nameText.getFont());
JTabbedPane tabbedPane = new JTabbedPane();
JPanel container = new JPanel();
container.setLayout(new MigLayout("fill, insets dialog"));
tabbedPane.addTab("Modpack", null, createMainPanel());
tabbedPane.addTab("Launch", null, createLaunchPanel());
tabbedPane.addTab("User Files", null, createUserFilesPanel());
tabbedPane.addTab("Optional Features", null, createFeaturesPanel());
container.add(tabbedPane, "span, grow, gapbottom unrel");
JButton saveButton = new JButton("Save");
JButton cancelButton = new JButton("Cancel");
container.add(saveButton, "tag ok, span, split 2, sizegroup bttn");
container.add(cancelButton, "tag cancel, sizegroup bttn");
getRootPane().setDefaultButton(saveButton);
getRootPane().registerKeyboardAction(event -> cancelButton.doClick(), KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_IN_FOCUSED_WINDOW);
add(container, BorderLayout.CENTER);
saveButton.addActionListener(e -> {
if (nameText.getText().trim().isEmpty()) {
SwingHelper.showErrorDialog(BuilderConfigDialog.this, "The 'Name' field cannot be empty.", "Input Error");
return;
}
if (gameVersionText.getText().trim().isEmpty()) {
SwingHelper.showErrorDialog(BuilderConfigDialog.this, "The 'Game Version' field must be a Minecraft version.", "Input Error");
return;
}
copyTo();
saved = true;
dispose();
});
cancelButton.addActionListener(e -> dispose());
TableSearchable tableSearchable = SearchableUtils.installSearchable(featuresTable);
tableSearchable.setMainIndex(-1);
}
private JPanel createMainPanel() {
JPanel container = new JPanel();
SwingHelper.removeOpaqueness(container);
container.setLayout(new MigLayout("insets dialog"));
container.add(new JLabel("Name:"));
container.add(nameText, "span");
container.add(new JLabel("Title:"));
container.add(titleText, "span");
container.add(new JLabel("Game Version:"));
container.add(gameVersionText, "span");
return container;
}
private JPanel createLaunchPanel() {
JPanel container = new JPanel();
SwingHelper.removeOpaqueness(container);
container.setLayout(new MigLayout("insets dialog"));
container.add(new JLabel("Launch Flags:"), "wrap");
container.add(SwingHelper.wrapScrollPane(launchFlagsArea), "span");
return container;
}
private JPanel createUserFilesPanel() {
JPanel container = new JPanel();
SwingHelper.removeOpaqueness(container);
container.setLayout(new MigLayout("insets dialog"));
container.add(new JLabel("Include Patterns:"), "wrap");
container.add(SwingHelper.wrapScrollPane(userFilesIncludeArea), "span, gapbottom unrel");
container.add(new JLabel("Exclude Patterns:"), "wrap");
container.add(SwingHelper.wrapScrollPane(userFilesExcludeArea), "span");
return container;
}
private JPanel createFeaturesPanel() {
JPanel container = new JPanel();
SwingHelper.removeOpaqueness(container);
container.setLayout(new MigLayout("fill, insets dialog"));
JButton newButton = new JButton("New...");
JButton editButton = new JButton("Edit...");
JButton deleteButton = new JButton("Delete...");
container.add(newButton, "span, split 3, sizegroup bttn");
container.add(editButton, "sizegroup bttn");
container.add(deleteButton, "sizegroup bttn");
container.add(SwingHelper.wrapScrollPane(featuresTable), "grow, w 10:100:null, gaptop 10");
newButton.addActionListener(e -> {
FeaturePattern pattern = new FeaturePattern();
if (FeaturePatternDialog.showEditor(BuilderConfigDialog.this, pattern)) {
featuresModel.addFeature(pattern);
}
});
editButton.addActionListener(e -> {
int index = featuresTable.getSelectedRow();
if (index > -1) {
FeaturePattern pattern = featuresModel.getFeature(index);
FeaturePatternDialog.showEditor(BuilderConfigDialog.this, pattern);
featuresModel.fireTableDataChanged();
} else {
SwingHelper.showErrorDialog(BuilderConfigDialog.this, "Select a feature first.", "No Selection");
}
});
deleteButton.addActionListener(e -> {
int index = featuresTable.getSelectedRow();
if (index > -1) {
FeaturePattern pattern = featuresModel.getFeature(index);
if (SwingHelper.confirmDialog(BuilderConfigDialog.this, "Are you sure that you want to delete '" + pattern.getFeature().getName() + "'?", "Delete")) {
featuresModel.removeFeature(index);
}
} else {
SwingHelper.showErrorDialog(BuilderConfigDialog.this, "Select a feature first.", "No Selection");
}
});
return container;
}
private void copyFrom() {
SwingHelper.setTextAndResetCaret(nameText, config.getName());
SwingHelper.setTextAndResetCaret(titleText, config.getTitle());
SwingHelper.setTextAndResetCaret(gameVersionText, config.getGameVersion());
SwingHelper.setTextAndResetCaret(launchFlagsArea, SwingHelper.listToLines(config.getLaunchModifier().getFlags()));
SwingHelper.setTextAndResetCaret(userFilesIncludeArea, SwingHelper.listToLines(config.getUserFiles().getInclude()));
SwingHelper.setTextAndResetCaret(userFilesExcludeArea, SwingHelper.listToLines(config.getUserFiles().getExclude()));
featuresModel = new FeaturePatternTableModel(config.getFeatures());
featuresTable.setModel(featuresModel);
}
private void copyTo() {
config.setName(nameText.getText().trim());
config.setTitle(Strings.emptyToNull(titleText.getText().trim()));
config.setGameVersion(gameVersionText.getText().trim());
LaunchModifier launchModifier = config.getLaunchModifier();
FnPatternList userFiles = config.getUserFiles();
launchModifier.setFlags(SwingHelper.linesToList(launchFlagsArea.getText()));
userFiles.setInclude(SwingHelper.linesToList(userFilesIncludeArea.getText()));
userFiles.setExclude(SwingHelper.linesToList(userFilesExcludeArea.getText()));
}
public static boolean showEditor(Window window, BuilderConfig config) {
BuilderConfigDialog dialog = new BuilderConfigDialog(window, config);
dialog.setVisible(true);
return dialog.saved;
}
}