/* * Copyright (c) 2012, Codename One and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Codename One designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Codename One through http://www.codenameone.com/ if you * need additional information or have any questions. */ package com.codename1.designer; import com.codename1.ui.Display; import com.codename1.ui.EncodedImage; import com.codename1.ui.util.EditableResources; import java.awt.Component; import java.awt.image.BufferedImage; import java.io.File; import java.io.FileFilter; import java.io.IOException; import java.util.ArrayList; import java.util.Hashtable; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import javax.imageio.ImageIO; import javax.swing.DefaultComboBoxModel; import javax.swing.DefaultListCellRenderer; import javax.swing.JComboBox; import javax.swing.JList; import javax.swing.JOptionPane; import javax.swing.ListCellRenderer; import javax.swing.SwingUtilities; /** * * @author Shai Almog */ public class Import9Patch extends javax.swing.JDialog { private EditableResources res; private String theme; /** Creates new form Import9Patch */ public Import9Patch(java.awt.Component parent, EditableResources res, String theme) { super((java.awt.Frame)SwingUtilities.windowForComponent(parent), true); this.res = res; this.theme = theme; initComponents(); AddThemeEntry.initUIIDComboBox(uiidCombo); pack(); setLocationByPlatform(true); setVisible(true); } /** This method is called from within the constructor to * initialize the form. * WARNING: Do NOT modify this code. The content of this method is * always regenerated by the Form Editor. */ @SuppressWarnings("unchecked") // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents private void initComponents() { jLabel1 = new javax.swing.JLabel(); jLabel2 = new javax.swing.JLabel(); imageDirectory = new javax.swing.JTextField(); pickDirectory = new javax.swing.JButton(); jLabel3 = new javax.swing.JLabel(); uiidCombo = new javax.swing.JComboBox(); jLabel4 = new javax.swing.JLabel(); styleState = new javax.swing.JComboBox(); jPanel1 = new javax.swing.JPanel(); jPanel2 = new javax.swing.JPanel(); okButton = new javax.swing.JButton(); cancelButton = new javax.swing.JButton(); jLabel5 = new javax.swing.JLabel(); imagesCombo = new javax.swing.JComboBox(); FormListener formListener = new FormListener(); setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); setTitle("Import 9-Patch Files"); jLabel1.setText("<html>Select the directory where the 9-patch images are stored based on the directory hierarchy<br/>convention used in the Android platform"); jLabel1.setName("jLabel1"); // NOI18N jLabel2.setText("Image Directory"); jLabel2.setName("jLabel2"); // NOI18N imageDirectory.setName("imageDirectory"); // NOI18N pickDirectory.setText("..."); pickDirectory.setName("pickDirectory"); // NOI18N pickDirectory.addActionListener(formListener); jLabel3.setText("Apply To"); jLabel3.setName("jLabel3"); // NOI18N uiidCombo.setEditable(true); uiidCombo.setName("uiidCombo"); // NOI18N jLabel4.setText("State"); jLabel4.setName("jLabel4"); // NOI18N styleState.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Unselected", "Selected", "Pressed", "Disabled" })); styleState.setName("styleState"); // NOI18N jPanel1.setName("jPanel1"); // NOI18N jPanel2.setName("jPanel2"); // NOI18N jPanel2.setLayout(new java.awt.GridLayout(1, 2)); okButton.setText("Apply"); okButton.setName("okButton"); // NOI18N okButton.addActionListener(formListener); jPanel2.add(okButton); cancelButton.setText("Close"); cancelButton.setName("cancelButton"); // NOI18N cancelButton.addActionListener(formListener); jPanel2.add(cancelButton); jPanel1.add(jPanel2); jLabel5.setText("Image"); jLabel5.setName("jLabel5"); // NOI18N imagesCombo.setName("imagesCombo"); // NOI18N org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) .add(layout.createSequentialGroup() .addContainerGap() .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) .add(jLabel1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) .add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createSequentialGroup() .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) .add(jLabel2) .add(jLabel3) .add(jLabel4)) .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING) .add(org.jdesktop.layout.GroupLayout.LEADING, imagesCombo, 0, 390, Short.MAX_VALUE) .add(org.jdesktop.layout.GroupLayout.LEADING, imageDirectory, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 390, Short.MAX_VALUE) .add(org.jdesktop.layout.GroupLayout.LEADING, styleState, 0, 390, Short.MAX_VALUE) .add(org.jdesktop.layout.GroupLayout.LEADING, uiidCombo, 0, 390, Short.MAX_VALUE)) .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) .add(pickDirectory)))) .add(layout.createSequentialGroup() .add(224, 224, 224) .add(jPanel1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) .addContainerGap(210, Short.MAX_VALUE)) .add(layout.createSequentialGroup() .addContainerGap() .add(jLabel5) .addContainerGap(546, Short.MAX_VALUE)) ); layout.setVerticalGroup( layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) .add(layout.createSequentialGroup() .add(11, 11, 11) .add(jLabel1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE) .add(jLabel2) .add(imageDirectory, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) .add(pickDirectory)) .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE) .add(jLabel5) .add(imagesCombo, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE) .add(uiidCombo, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) .add(jLabel3)) .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE) .add(styleState, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) .add(jLabel4)) .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, 8, Short.MAX_VALUE) .add(jPanel1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) .add(9, 9, 9)) ); pack(); } // Code for dispatching events from components to event handlers. private class FormListener implements java.awt.event.ActionListener { FormListener() {} public void actionPerformed(java.awt.event.ActionEvent evt) { if (evt.getSource() == pickDirectory) { Import9Patch.this.pickDirectoryActionPerformed(evt); } else if (evt.getSource() == okButton) { Import9Patch.this.okButtonActionPerformed(evt); } else if (evt.getSource() == cancelButton) { Import9Patch.this.cancelButtonActionPerformed(evt); } } }// </editor-fold>//GEN-END:initComponents private void pickDirectoryActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_pickDirectoryActionPerformed File[] result = ResourceEditorView.showOpenFileChooserWithTitle("Select The Directory", true, "Directory"); if(result != null && result.length == 1) { imageDirectory.setText(result[0].getAbsolutePath()); } File drawableHdpi = new File(imageDirectory.getText() + File.separator + "drawable-hdpi"); File[] potentials = drawableHdpi.listFiles(new FileFilter() { @Override public boolean accept(File file) { return file.getName().endsWith(".9.png"); } }); if(potentials == null || potentials.length == 0) { JOptionPane.showMessageDialog(this, "Can't find 9-patch files in the hdpi directory", "Error", JOptionPane.ERROR_MESSAGE); return; } imagesCombo.setRenderer(new DefaultListCellRenderer() { @Override public Component getListCellRendererComponent(JList jlist, Object o, int i, boolean bln, boolean bln1) { if(o instanceof File) { o = ((File)o).getName(); } return super.getListCellRendererComponent(jlist, o, i, bln, bln1); } }); imagesCombo.setModel(new DefaultComboBoxModel(potentials)); }//GEN-LAST:event_pickDirectoryActionPerformed private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelButtonActionPerformed dispose(); }//GEN-LAST:event_cancelButtonActionPerformed private void okButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_okButtonActionPerformed try { File[] dirs = new File(imageDirectory.getText()).listFiles(new FileFilter() { @Override public boolean accept(File file) { return file.isDirectory(); } }); if(dirs.length == 0) { JOptionPane.showMessageDialog(this, "No directories found", "Error", JOptionPane.ERROR_MESSAGE); return; } File drawableHdpi = new File(imageDirectory.getText() + File.separator + "drawable-hdpi"); File drawableLdpi = new File(imageDirectory.getText() + File.separator + "drawable-ldpi"); File drawableMdpi = new File(imageDirectory.getText() + File.separator + "drawable-mdpi"); File drawableXHdpi = new File(imageDirectory.getText() + File.separator + "drawable-xhdpi"); if(!drawableHdpi.exists()) { JOptionPane.showMessageDialog(this, "Can't find the drawable-hdpi directory", "Error", JOptionPane.ERROR_MESSAGE); return; } drawableHdpi = (File)imagesCombo.getSelectedItem(); drawableLdpi = new File(drawableLdpi, drawableHdpi.getName()); drawableMdpi = new File(drawableMdpi, drawableHdpi.getName()); drawableXHdpi = new File(drawableXHdpi, drawableHdpi.getName()); List<BufferedImage> images = new ArrayList<BufferedImage>(); List<Integer> densities = new ArrayList<Integer>(); BufferedImage hdpi = ImageIO.read(drawableHdpi); images.add(hdpi); densities.add(Display.DENSITY_HIGH); BufferedImage ldpi = null; if(drawableLdpi.exists()) { ldpi = ImageIO.read(drawableLdpi); images.add(ldpi); densities.add(Display.DENSITY_LOW); } BufferedImage mdpi = null; if(drawableMdpi.exists()) { mdpi = ImageIO.read(drawableMdpi); images.add(mdpi); densities.add(Display.DENSITY_MEDIUM); } BufferedImage xhdpi = null; if(drawableXHdpi.exists()) { xhdpi = ImageIO.read(drawableXHdpi); images.add(xhdpi); densities.add(Display.DENSITY_VERY_HIGH); } create9Patch(images, densities); } catch (IOException ex) { ex.printStackTrace(); JOptionPane.showMessageDialog(this, "IO Error reading file", "Error", JOptionPane.ERROR_MESSAGE); } }//GEN-LAST:event_okButtonActionPerformed private void create9Patch(List<BufferedImage> biList, List<Integer> densities) { List<com.codename1.ui.EncodedImage> topLeftCodenameOne = new ArrayList<EncodedImage>(); List<com.codename1.ui.EncodedImage> topRightCodenameOne = new ArrayList<EncodedImage>(); List<com.codename1.ui.EncodedImage> bottomLeftCodenameOne = new ArrayList<EncodedImage>(); List<com.codename1.ui.EncodedImage> bottomRightCodenameOne = new ArrayList<EncodedImage>(); List<com.codename1.ui.EncodedImage> centerCodenameOne = new ArrayList<EncodedImage>(); List<com.codename1.ui.EncodedImage> topImageCodenameOne = new ArrayList<EncodedImage>(); List<com.codename1.ui.EncodedImage> bottomImageCodenameOne = new ArrayList<EncodedImage>(); List<com.codename1.ui.EncodedImage> leftImageCodenameOne = new ArrayList<EncodedImage>(); List<com.codename1.ui.EncodedImage> rightImageCodenameOne = new ArrayList<EncodedImage>(); for(BufferedImage bi : biList) { int left = 0; for(int x = 0 ; x < bi.getWidth() ; x++) { int pixel = bi.getRGB(x, 0); if((pixel & 0xff000000) == 0xff000000) { break; } left++; } int right = 0; for(int x = bi.getWidth() - 1 ; x > 0 ; x--) { int pixel = bi.getRGB(x, 0); if((pixel & 0xff000000) == 0xff000000) { break; } right++; } int top = 0; for(int y = 0 ; y < bi.getHeight() ; y++) { int pixel = bi.getRGB(0, y); if((pixel & 0xff000000) == 0xff000000) { break; } top++; } int bottom = 0; for(int y = bi.getHeight() - 1 ; y > 0 ; y--) { int pixel = bi.getRGB(0, y); if((pixel & 0xff000000) == 0xff000000) { break; } bottom++; } bi = bi.getSubimage(1, 1, bi.getWidth() - 2, bi.getHeight() - 2); top--; bottom--; left--; right--; BufferedImage topLeft = bi.getSubimage(0, 0, left, top); BufferedImage topRight = bi.getSubimage(bi.getWidth() - right, 0, right, top); BufferedImage bottomLeft = bi.getSubimage(0, bi.getHeight() - bottom, left, bottom); BufferedImage bottomRight = bi.getSubimage(bi.getWidth() - right, bi.getHeight() - bottom, right, bottom); BufferedImage center = bi.getSubimage(left, top, bi.getWidth() - right - left, bi.getHeight() - bottom - top); BufferedImage topImage = bi.getSubimage(left, 0, bi.getWidth() - left - right, top); BufferedImage bottomImage = bi.getSubimage(left, bi.getHeight() - bottom, bi.getWidth() - left - right, bottom); BufferedImage leftImage = bi.getSubimage(0, top, left, bi.getHeight() - top - bottom); BufferedImage rightImage = bi.getSubimage(bi.getWidth() - right, top, right, bi.getHeight() - top - bottom); topLeftCodenameOne.add(com.codename1.ui.EncodedImage.create(ImageBorderCuttingWizard.toPng(topLeft))); topRightCodenameOne.add(com.codename1.ui.EncodedImage.create(ImageBorderCuttingWizard.toPng(topRight))); bottomLeftCodenameOne.add(com.codename1.ui.EncodedImage.create(ImageBorderCuttingWizard.toPng(bottomLeft))); bottomRightCodenameOne.add(com.codename1.ui.EncodedImage.create(ImageBorderCuttingWizard.toPng(bottomRight))); centerCodenameOne.add(com.codename1.ui.EncodedImage.create(ImageBorderCuttingWizard.toPng(center))); topImageCodenameOne.add(com.codename1.ui.EncodedImage.create(ImageBorderCuttingWizard.toPng(topImage))); bottomImageCodenameOne.add(com.codename1.ui.EncodedImage.create(ImageBorderCuttingWizard.toPng(bottomImage))); leftImageCodenameOne.add(com.codename1.ui.EncodedImage.create(ImageBorderCuttingWizard.toPng(leftImage))); rightImageCodenameOne.add(com.codename1.ui.EncodedImage.create(ImageBorderCuttingWizard.toPng(rightImage))); } String prefix = (String)uiidCombo.getSelectedItem() + "."; switch(styleState.getSelectedIndex()) { case 1: prefix += "sel#"; break; case 2: prefix += "press#"; break; case 3: prefix += "dis#"; break; } com.codename1.ui.EncodedImage topLeftCodenameOneE = storeImage(topLeftCodenameOne, densities, prefix + " "); com.codename1.ui.EncodedImage topRightCodenameOneE = storeImage(topRightCodenameOne, densities, prefix + " "); com.codename1.ui.EncodedImage bottomLeftCodenameOneE = storeImage(bottomLeftCodenameOne, densities, prefix + " "); com.codename1.ui.EncodedImage bottomRightCodenameOneE = storeImage(bottomRightCodenameOne, densities, prefix + " "); com.codename1.ui.EncodedImage centerCodenameOneE = storeImage(centerCodenameOne, densities, prefix + " "); com.codename1.ui.EncodedImage topImageCodenameOneE = storeImage(topImageCodenameOne, densities, prefix + " "); com.codename1.ui.EncodedImage bottomImageCodenameOneE = storeImage(bottomImageCodenameOne, densities, prefix + " "); com.codename1.ui.EncodedImage leftImageCodenameOneE = storeImage(leftImageCodenameOne, densities, prefix + " "); com.codename1.ui.EncodedImage rightImageCodenameOneE = storeImage(rightImageCodenameOne, densities, prefix + " "); com.codename1.ui.plaf.Border b = com.codename1.ui.plaf.Border.createImageScaledBorder(topImageCodenameOneE, bottomImageCodenameOneE, leftImageCodenameOneE, rightImageCodenameOneE, topLeftCodenameOneE, topRightCodenameOneE, bottomLeftCodenameOneE, bottomRightCodenameOneE, centerCodenameOneE); Hashtable newTheme = new Hashtable(res.getTheme(theme)); newTheme.put(prefix + "border", b); res.setTheme(theme, newTheme); } private com.codename1.ui.EncodedImage storeImage(List<com.codename1.ui.EncodedImage> imgs, List<Integer> densities, String prefix) { int i = 1; while(res.containsResource(prefix + "_" + i + ".png")) { i++; } EditableResources.MultiImage multi = new EditableResources.MultiImage(); int[] dpis = new int[densities.size()]; com.codename1.ui.EncodedImage[] images = new com.codename1.ui.EncodedImage[dpis.length]; for(int iter = 0 ; iter < dpis.length ; iter++) { dpis[iter] = densities.get(iter); images[iter] = imgs.get(iter); } multi.setDpi(dpis); multi.setInternalImages(images); res.setMultiImage(prefix + "_" + i + ".png", multi); return multi.getBest(); } // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton cancelButton; private javax.swing.JTextField imageDirectory; private javax.swing.JComboBox imagesCombo; private javax.swing.JLabel jLabel1; private javax.swing.JLabel jLabel2; private javax.swing.JLabel jLabel3; private javax.swing.JLabel jLabel4; private javax.swing.JLabel jLabel5; private javax.swing.JPanel jPanel1; private javax.swing.JPanel jPanel2; private javax.swing.JButton okButton; private javax.swing.JButton pickDirectory; private javax.swing.JComboBox styleState; private javax.swing.JComboBox uiidCombo; // End of variables declaration//GEN-END:variables }