Java tutorial
/* * Copyright 2015 Marc Prengemann * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for * the specific language governing permissions and limitations under the License. */ package de.mprengemann.intellij.plugin.androidicons.dialogs; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.ui.ValidationInfo; import com.intellij.openapi.util.SystemInfo; import com.intellij.ui.ComboboxSpeedSearch; import com.intellij.ui.JBColor; import com.intellij.ui.LayeredIcon; import com.intellij.ui.ListCellRendererWrapper; import com.intellij.util.Consumer; import com.intellij.util.ui.EmptyIcon; import de.mprengemann.intellij.plugin.androidicons.IconApplication; import de.mprengemann.intellij.plugin.androidicons.controllers.defaults.IDefaultsController; import de.mprengemann.intellij.plugin.androidicons.controllers.iconimporter.IIconsImporterController; import de.mprengemann.intellij.plugin.androidicons.controllers.iconimporter.IconsImporterController; import de.mprengemann.intellij.plugin.androidicons.controllers.iconimporter.IconsImporterObserver; import de.mprengemann.intellij.plugin.androidicons.controllers.icons.androidicons.IAndroidIconsController; import de.mprengemann.intellij.plugin.androidicons.controllers.icons.materialicons.IMaterialIconsController; import de.mprengemann.intellij.plugin.androidicons.controllers.settings.ISettingsController; import de.mprengemann.intellij.plugin.androidicons.model.Format; import de.mprengemann.intellij.plugin.androidicons.model.IconPack; import de.mprengemann.intellij.plugin.androidicons.model.ImageAsset; import de.mprengemann.intellij.plugin.androidicons.model.Resolution; import de.mprengemann.intellij.plugin.androidicons.util.ImageUtils; import de.mprengemann.intellij.plugin.androidicons.widgets.ExportNameField; import de.mprengemann.intellij.plugin.androidicons.widgets.FileBrowserField; import de.mprengemann.intellij.plugin.androidicons.widgets.ResolutionButtonModel; import org.apache.commons.lang.StringUtils; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ComponentAdapter; import java.awt.event.ComponentEvent; import java.awt.event.FocusAdapter; import java.awt.event.FocusEvent; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.File; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Set; public class IconImporter extends DialogWrapper implements IconsImporterObserver { private final Project project; private Module module; private final IAndroidIconsController androidIconsController; private final IMaterialIconsController materialIconsController; private final ISettingsController settingsController; private final IDefaultsController defaultsController; private final IIconsImporterController controller; private JLabel imageContainer; private JComboBox assetSpinner; private JComboBox colorSpinner; private JComboBox categorySpinner; private JComboBox sizeSpinner; private JPanel uiContainer; private FileBrowserField resRoot; private ExportNameField resExportName; private JCheckBox LDPICheckBox; private JCheckBox MDPICheckBox; private JCheckBox HDPICheckBox; private JCheckBox XHDPICheckBox; private JCheckBox XXHDPICheckBox; private JCheckBox XXXHDPICheckBox; private JComboBox iconPackSpinner; private JComboBox searchField; private JCheckBox TVDPICheckBox; private JComboBox formatSpinner; private final ActionListener iconPackActionListener = new ActionListener() { @Override public void actionPerformed(ActionEvent actionEvent) { final JComboBox source = (JComboBox) actionEvent.getSource(); final IconPack selectedItem = (IconPack) source.getSelectedItem(); controller.setSelectedIconPack(selectedItem.getId()); } }; private final ActionListener categoryActionListener = new ActionListener() { @Override public void actionPerformed(ActionEvent actionEvent) { final JComboBox source = (JComboBox) actionEvent.getSource(); final String selectedItem = (String) source.getSelectedItem(); controller.setSelectedCategory(selectedItem); } }; private final ActionListener assetActionListener = new ActionListener() { @Override public void actionPerformed(ActionEvent actionEvent) { final JComboBox source = (JComboBox) actionEvent.getSource(); final ImageAsset selectedItem = (ImageAsset) source.getSelectedItem(); controller.setSelectedAsset(selectedItem); } }; private final ActionListener sizeActionListener = new ActionListener() { @Override public void actionPerformed(ActionEvent actionEvent) { final JComboBox source = (JComboBox) actionEvent.getSource(); final String selectedItem = (String) source.getSelectedItem(); controller.setSelectedSize(selectedItem); } }; private final ActionListener colorActionListener = new ActionListener() { @Override public void actionPerformed(ActionEvent actionEvent) { final JComboBox source = (JComboBox) actionEvent.getSource(); final String selectedItem = (String) source.getSelectedItem(); controller.setSelectedColor(selectedItem); } }; private final ActionListener resolutionActionListener = new ActionListener() { @Override public void actionPerformed(ActionEvent actionEvent) { final JCheckBox source = (JCheckBox) actionEvent.getSource(); final Resolution resolution = ((ResolutionButtonModel) source.getModel()).getResolution(); controller.setExportResolution(resolution, source.isSelected()); } }; private final ActionListener formatListener = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { final JComboBox source = (JComboBox) e.getSource(); final Format selectedItem = (Format) source.getSelectedItem(); controller.setFormat(selectedItem); } }; private final Consumer<File> resRootListener = new Consumer<File>() { @Override public void consume(File file) { String path; if (file == null) { path = ""; } else { path = file.getPath(); } controller.setExportRoot(path); } }; private final ItemListener searchFieldListener = new ItemListener() { @Override public void itemStateChanged(ItemEvent e) { final ImageAsset selectedItem = (ImageAsset) searchField.getSelectedItem(); if (selectedItem == null) { return; } controller.setSelectedAsset(selectedItem); } }; private ComboboxSpeedSearch comboboxSpeedSearch; public IconImporter(Project project, Module module) { super(project, true); this.project = project; this.module = module; final IconApplication container = ApplicationManager.getApplication().getComponent(IconApplication.class); androidIconsController = container.getControllerFactory().getAndroidIconsController(); materialIconsController = container.getControllerFactory().getMaterialIconsController(); settingsController = container.getControllerFactory().getSettingsController(); defaultsController = container.getControllerFactory().getDefaultsController(); controller = new IconsImporterController(defaultsController, androidIconsController, materialIconsController); initResRoot(); setTitle("Icon Pack Drawable Importer"); getHelpAction().setEnabled(true); AssetSpinnerRenderer renderer = new AssetSpinnerRenderer(); //noinspection GtkPreferredJComboBoxRenderer assetSpinner.setRenderer(renderer); imageContainer.addComponentListener(new ComponentAdapter() { @Override public void componentResized(ComponentEvent e) { super.componentResized(e); updateImage(); } }); initCheckBoxes(); initSearch(); controller.addObserver(this); init(); pack(); } private void initSearch() { final List<ImageAsset> imageAssets = new ArrayList<ImageAsset>(); imageAssets.addAll(androidIconsController.getAssets(androidIconsController.getCategories())); imageAssets.addAll(materialIconsController.getAssets(materialIconsController.getCategories())); for (ImageAsset imageAsset : imageAssets) { searchField.addItem(imageAsset); } searchField.setRenderer(new AssetSpinnerRenderer()); comboboxSpeedSearch = new ComboboxSpeedSearch(searchField) { @Override protected String getElementText(Object element) { return element instanceof ImageAsset ? ((ImageAsset) element).getName() : ""; } }; searchField.addFocusListener(new FocusAdapter() { @Override public void focusGained(FocusEvent e) { comboboxSpeedSearch.showPopup(); } }); searchField.addItemListener(searchFieldListener); } private void initCheckBoxes() { LDPICheckBox.setModel(new ResolutionButtonModel(Resolution.LDPI)); MDPICheckBox.setModel(new ResolutionButtonModel(Resolution.MDPI)); HDPICheckBox.setModel(new ResolutionButtonModel(Resolution.HDPI)); XHDPICheckBox.setModel(new ResolutionButtonModel(Resolution.XHDPI)); XXHDPICheckBox.setModel(new ResolutionButtonModel(Resolution.XXHDPI)); XXXHDPICheckBox.setModel(new ResolutionButtonModel(Resolution.XXXHDPI)); TVDPICheckBox.setModel(new ResolutionButtonModel(Resolution.TVDPI)); } @NotNull @Override public Action[] createActions() { return SystemInfo.isMac ? new Action[] { this.getHelpAction(), this.getCancelAction(), this.getOKAction() } : new Action[] { this.getOKAction(), this.getCancelAction(), this.getHelpAction() }; } private void prepareSpinner(JComboBox comboBox, ActionListener listener) { comboBox.removeActionListener(listener); comboBox.setSelectedItem(null); comboBox.removeAllItems(); } private void initSpinner(JComboBox comboBox, Object selectedItem, ActionListener listener) { comboBox.setSelectedItem(selectedItem); comboBox.addActionListener(listener); } private void updatePacks() { prepareSpinner(iconPackSpinner, iconPackActionListener); iconPackSpinner.addItem(androidIconsController.getIconPack()); iconPackSpinner.addItem(materialIconsController.getIconPack()); initSpinner(iconPackSpinner, controller.getSelectedIconPack().getIconPack(), iconPackActionListener); } private void updateCategories() { prepareSpinner(categorySpinner, categoryActionListener); for (String category : controller.getCategories()) { categorySpinner.addItem(category); } categorySpinner.setEnabled(categorySpinner.getItemCount() > 1); initSpinner(categorySpinner, controller.getSelectedCategory(), categoryActionListener); } private void updateExportResolutions() { final Set<Resolution> resolutions = controller.getExportResolutions(); for (JCheckBox checkBox : Arrays.asList(LDPICheckBox, MDPICheckBox, HDPICheckBox, XHDPICheckBox, XXHDPICheckBox, XXXHDPICheckBox, TVDPICheckBox)) { checkBox.removeActionListener(resolutionActionListener); final Resolution resolution = ((ResolutionButtonModel) checkBox.getModel()).getResolution(); checkBox.setSelected(resolutions.contains(resolution)); checkBox.addActionListener(resolutionActionListener); } } private void updateAssets() { prepareSpinner(assetSpinner, assetActionListener); List<ImageAsset> assets = controller.getAssets(); for (ImageAsset asset : assets) { assetSpinner.addItem(asset); } initSpinner(assetSpinner, controller.getSelectedAsset(), assetActionListener); } private void updateSizes() { prepareSpinner(sizeSpinner, sizeActionListener); List<String> sizes = controller.getSizes(); for (String size : sizes) { sizeSpinner.addItem(size); } sizeSpinner.setEnabled(sizeSpinner.getItemCount() > 1); initSpinner(sizeSpinner, controller.getSelectedSize(), sizeActionListener); } private void updateColors() { prepareSpinner(colorSpinner, colorActionListener); List<String> colors = controller.getColors(); for (String color : colors) { colorSpinner.addItem(color); } initSpinner(colorSpinner, controller.getSelectedColor(), colorActionListener); } private void updateFormat() { formatSpinner.removeActionListener(formatListener); formatSpinner.removeAllItems(); for (Format format : Format.nonVectorValues()) { formatSpinner.addItem(format); } formatSpinner.setSelectedItem(controller.getFormat()); formatSpinner.setEnabled(!controller.isNinePatch()); formatSpinner.addActionListener(formatListener); } private void updateExportName() { resExportName.setText(controller.getExportName()); } private void updateSearch() { searchField.removeItemListener(searchFieldListener); searchField.setSelectedItem(controller.getSelectedAsset()); searchField.addItemListener(searchFieldListener); } private void updateImage() { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { if (imageContainer == null) { return; } ImageUtils.updateImage(imageContainer, controller.getSelectedImageFile(), controller.getFormat()); } }); } @Override protected void doHelpAction() { materialIconsController.openHelp(); } @Override protected void doOKAction() { importIcons(); defaultsController.setImageAsset(controller.getSelectedAsset()); defaultsController.setColor(controller.getSelectedColor()); defaultsController.setSize(controller.getSelectedSize()); defaultsController.setResolutions(controller.getExportResolutions()); super.doOKAction(); settingsController.saveResRootForProject("file://" + controller.getExportRoot()); } private void importIcons() { controller.getTask(project).queue(); } @Nullable @Override protected ValidationInfo doValidate() { if (StringUtils.isEmpty(controller.getExportRoot())) { return new ValidationInfo("Please select the resources root.", resRoot); } if (StringUtils.isEmpty(controller.getExportName().trim())) { return new ValidationInfo("Please select a name for the drawable.", resExportName); } else if (!controller.getExportName().matches("[a-z0-9_.]*")) { return new ValidationInfo( "Please select a valid name for the drawable. There are just \"[a-z0-9_.]\" allowed.", resExportName); } return null; } @Nullable @Override protected JComponent createCenterPanel() { return uiContainer; } @Override public void updated() { updatePacks(); updateExportResolutions(); updateCategories(); updateAssets(); updateSearch(); updateSizes(); updateColors(); updateFormat(); updateImage(); updateExportName(); } private void createUIComponents() { resRoot = new FileBrowserField(FileBrowserField.RESOURCE_DIR_CHOOSER); } private void initResRoot() { resRoot.setSelectionListener(resRootListener); resRoot.initWithResourceRoot(project, module, settingsController); resExportName.addPropertyChangeListener("value", new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent propertyChangeEvent) { controller.setExportName((String) resExportName.getValue()); } }); } private class AssetSpinnerRenderer extends ListCellRendererWrapper<ImageAsset> { private final Icon EMPTY_ICON = EmptyIcon.ICON_18; @Override public void customize(JList list, ImageAsset imageAsset, int index, boolean selected, boolean hasFocus) { LayeredIcon layeredIcon = new LayeredIcon(2); File imageFile = controller.getThumbnailFile(imageAsset); if (imageFile != null && imageFile.exists()) { final ImageIcon icon = new ImageIcon(imageFile.getAbsolutePath()); layeredIcon.setIcon(icon, 1, (-icon.getIconWidth() + EMPTY_ICON.getIconWidth()) / 2, (EMPTY_ICON.getIconHeight() - icon.getIconHeight()) / 2); } setIcon(layeredIcon); final String searchQuery = comboboxSpeedSearch.getEnteredPrefix(); if (searchQuery != null && searchQuery.trim().length() > 0 && imageAsset.getName().contains(searchQuery)) { setBackground(JBColor.YELLOW); } else { setBackground(null); } } } }