All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.codename1.designer.PickMIDlet Maven / Gradle / Ivy

/*
 * Copyright (c) 2008, 2010, Oracle 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.  Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores
 * CA 94065 USA or visit www.oracle.com if you need additional information or
 * have any questions.
 */

package com.codename1.designer;

import com.codename1.ui.Display;
import com.codename1.ui.Form;
import com.codename1.impl.javase.JavaSEPortWithSVGSupport;
import com.codename1.ui.plaf.Accessor;
import com.codename1.ui.util.EditableResources;
import com.codename1.ui.util.UIBuilderOverride;
import java.io.IOException;
import java.util.jar.Attributes.Name;
import java.awt.BorderLayout;
import java.awt.Component;
import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.Vector;
import java.util.jar.Attributes;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.prefs.Preferences;
import javax.swing.DefaultComboBoxModel;
import javax.swing.DefaultListCellRenderer;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

/**
 * UI and logic allowing us to pick the MIDlet which will appear in the preview
 * pane
 *
 * @author  Shai Almog
 */
public class PickMIDlet extends javax.swing.JPanel {
    private static CustomComponent[] customComponents;

    /** Creates new form PickMIDlet */
    public PickMIDlet() {
        initComponents();
        midletPicker.setRenderer(new DefaultListCellRenderer() {
            public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
                if(value == null) {
                    value = "";
                } else {
                    String s = (String)value;
                    value = s.substring(0, s.indexOf(','));
                }
                return super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
            }
        });
        Preferences pref = Preferences.userNodeForPackage(ResourceEditorView.class);
        jarFile.setText(pref.get("jar", ""));
        updateMIDletList();
        midletPicker.setSelectedItem(pref.get("midlet", null));
        customComponents = null;
    }
    
    public static void showPickMIDletDialog(JComponent parent) {
        JDialog dlg = new JDialog((JFrame)SwingUtilities.getWindowAncestor(parent));
        dlg.setTitle("Pick MIDlet");
        dlg.getContentPane().setLayout(new BorderLayout());
        dlg.getContentPane().add(BorderLayout.CENTER, new PickMIDlet());
        dlg.setLocationByPlatform(true);
        dlg.pack();
        dlg.setVisible(true);
    }


    public static CustomComponent[] getCustomComponents() {
        if(customComponents == null) {
            Preferences pref = Preferences.userNodeForPackage(ResourceEditorView.class);
            String jar = pref.get("jar", null);
            if(jar != null) {
                try {
                    File jarFile = new File(jar);
                    URLClassLoader cl = URLClassLoader.newInstance(new URL[]{jarFile.toURI().toURL()}, PickMIDlet.class.getClassLoader());
                    JarFile zip = new JarFile(jarFile);
                    Enumeration en = zip.entries();
                    List customList = new ArrayList();
                    while(en.hasMoreElements()) {
                        JarEntry e = en.nextElement();
                        String className = e.getName().replace("/", ".");
                        if(className.endsWith(".class") && !className.startsWith("com.codename1.ui.") && className.indexOf('$') < 0) {
                            className = className.substring(0, className.length() - 6);
                            try {
                                CustomComponent current = new CustomComponent();
                                current.setCls(cl.loadClass(className));
                                if(!current.getCls().getName().startsWith("com.codename1.ui")) {
                                    // check that it has a default constructor
                                    com.codename1.ui.Component cmp = (com.codename1.ui.Component)current.getCls().newInstance();
                                    current.setClassName(current.getCls().getName());
                                    current.setCodenameOneBaseClass(current.getCls().getName());
                                    current.setType(cmp.getUIID());
                                    customList.add(current);
                                    UIBuilderOverride.registerCustomComponent(cmp.getUIID(), current.getCls());
                                }
                            } catch (Throwable ex) {
                            }
                        }
                    }
                    customComponents = new CustomComponent[customList.size()];
                    customList.toArray(customComponents);
                } catch (IOException ex) {
                    ex.printStackTrace();
                    JOptionPane.showMessageDialog(JFrame.getFrames()[0], "IO Error when accessing MIDlet JAR File: " + ex, "IO Error", JOptionPane.ERROR_MESSAGE);
                }
            }
        }
        return customComponents;
    }

    public static void resetSettings() {
        Preferences pref = Preferences.userNodeForPackage(ResourceEditorView.class);
        pref.remove("jar");
        pref.remove("midlet");
    }
    
    public static void startMIDlet(Hashtable themeHash) {
        Accessor.setTheme(themeHash);
        Preferences pref = Preferences.userNodeForPackage(ResourceEditorView.class);
        String jar = pref.get("jar", null);
        String midlet = pref.get("midlet", null);
        if(jar != null && midlet != null) {
            File jarFile = new File(jar);
            if(jarFile.exists()) {
                try {
                    URLClassLoader cl = URLClassLoader.newInstance(new URL[]{jarFile.toURI().toURL()}, PickMIDlet.class.getClassLoader());
                    StringTokenizer tokenizer = new StringTokenizer((String) midlet, " ,");
                    String s = tokenizer.nextToken();
                    while(tokenizer.hasMoreTokens()) {
                        s = tokenizer.nextToken();
                    }
                    Class cls = cl.loadClass(s);
                    JavaSEPortWithSVGSupport.setClassLoader(cls);
                    EditableResources.setResourcesClassLoader(cls);
                    Accessor.setTheme(themeHash);
                    
                    Object app = cls.newInstance();
                    
                    JarFile zip = new JarFile(jarFile);
                    Attributes m = zip.getManifest().getMainAttributes();
                    
                    cls.getDeclaredMethod("init", new Class[] {Object.class}).invoke(app, new Object[] {null});
                    cls.getDeclaredMethod("start", new Class[0]).invoke(app, new Object[0]);
                    
                    // there might be an ongoing transition and the form.show() method is serial
                    Display.getInstance().callSerially(new Runnable() {
                        public void run() {
                            if(Display.getInstance().getCurrent() != null) {
                                Display.getInstance().getCurrent().refreshTheme();
                                return;
                            } else {
                                new Thread() {
                                    public void run() {
                                        try {
                                            sleep(100);
                                        } catch (InterruptedException ex) {
                                            ex.printStackTrace();
                                        }
                                        Display.getInstance().callSerially(this);
                                    }
                                }.start();
                            }
                        }
                    });
                    return;
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        }
        
        JavaSEPortWithSVGSupport.setClassLoader(PickMIDlet.class);
        LiveDemo l = new LiveDemo();
        l.init(null);
        l.start();
        Accessor.setTheme(themeHash);
        Form current = Display.getInstance().getCurrent();
        if(current != null) {
            current.refreshTheme();
        }
    }
    
    /** 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")
    // //GEN-BEGIN:initComponents
    private void initComponents() {

        jLabel2 = new javax.swing.JLabel();
        jarFile = new javax.swing.JTextField();
        pickJarFile = new javax.swing.JButton();
        jLabel3 = new javax.swing.JLabel();
        midletPicker = new javax.swing.JComboBox();
        okButton = new javax.swing.JButton();
        cancelButton = new javax.swing.JButton();
        jScrollPane1 = new javax.swing.JScrollPane();
        jTextPane1 = new javax.swing.JTextPane();

        FormListener formListener = new FormListener();

        setName("Form"); // NOI18N

        jLabel2.setText("JAR File");
        jLabel2.setName("jLabel2"); // NOI18N

        jarFile.setEditable(false);
        jarFile.setName("jarFile"); // NOI18N

        pickJarFile.setText("...");
        pickJarFile.setName("pickJarFile"); // NOI18N
        pickJarFile.addActionListener(formListener);

        jLabel3.setText("MIDlet");
        jLabel3.setName("jLabel3"); // NOI18N

        midletPicker.setName("midletPicker"); // NOI18N

        okButton.setText("OK");
        okButton.setEnabled(false);
        okButton.setName("okButton"); // NOI18N
        okButton.addActionListener(formListener);

        cancelButton.setText("Cancel");
        cancelButton.setName("cancelButton"); // NOI18N
        cancelButton.addActionListener(formListener);

        jScrollPane1.setName("jScrollPane1"); // NOI18N

        jTextPane1.setContentType("text/html");
        jTextPane1.setEditable(false);
        jTextPane1.setText("\r\n  \r\n\r\n  \r\n  \r\n    

\r\n Allows selecting an Application to execute within the preview window of the theme view when\ncreating a theme for a specific Application. The preview might not reflect the full set of changes \nfrom the theme but would provide a good estimate for a designer. This application can also expose\nadditional custom components to the GUI designer view simply by creating valid Codename One component\nsubclasses with default constructors.\r\n

\r\n

\n The picked Application MUST NOT be obfuscated, this allows the Codename One Designer to replace the \nApplications CodenameOne version with its own. \n

\n

\n To debug pick Application run the Codename One Designer with a console or from command line and look at the\nerrors printed out when opening a theme.\n

\n \r\n\r\n"); // NOI18N jTextPane1.setName("jTextPane1"); // NOI18N jScrollPane1.setViewportView(jTextPane1); org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) .add(layout.createSequentialGroup() .addContainerGap() .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) .add(jLabel2) .add(jLabel3)) .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) .add(midletPicker, 0, 274, Short.MAX_VALUE) .add(jarFile, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 274, Short.MAX_VALUE) .add(layout.createSequentialGroup() .add(okButton) .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) .add(cancelButton))) .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) .add(pickJarFile) .addContainerGap()) .add(jScrollPane1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 452, Short.MAX_VALUE) ); layout.linkSize(new java.awt.Component[] {cancelButton, okButton}, org.jdesktop.layout.GroupLayout.HORIZONTAL); layout.setVerticalGroup( layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) .add(layout.createSequentialGroup() .addContainerGap() .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE) .add(jLabel2) .add(jarFile, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) .add(pickJarFile)) .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE) .add(jLabel3) .add(midletPicker, 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(okButton) .add(cancelButton)) .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) .add(jScrollPane1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 247, Short.MAX_VALUE)) ); } // 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() == pickJarFile) { PickMIDlet.this.pickJarFileActionPerformed(evt); } else if (evt.getSource() == okButton) { PickMIDlet.this.okButtonActionPerformed(evt); } else if (evt.getSource() == cancelButton) { PickMIDlet.this.cancelButtonActionPerformed(evt); } } }//
//GEN-END:initComponents private void updateMIDletList() { String j = jarFile.getText(); if(j != null && j.length() > 0) { File file = new File(j); if(file.exists() && file.isFile()) { try { JarFile zip = new JarFile(file); Attributes m = zip.getManifest().getMainAttributes(); Vector v = new Vector(); for (int i = 1 ; m.getValue("MIDlet-" + i) != null ; i++) { v.addElement(m.getValue("MIDlet-" + i)); } midletPicker.setModel(new DefaultComboBoxModel(v)); } catch (IOException ex) { ex.printStackTrace(); JOptionPane.showMessageDialog(this, "An IO Error occured while accessing\n" + "the MIDlet JAR:\n" + ex.getMessage(), "IO Error", JOptionPane.ERROR_MESSAGE); } } } } private void selectFile(JTextField field, String type) { JFileChooser c = ResourceEditorView.createFileChooser("*" + type, type); if(JFileChooser.APPROVE_OPTION == c.showDialog(this, "Select")) { File f = c.getSelectedFile(); field.setText(f.getAbsolutePath()); Preferences.userNodeForPackage(ResourceEditorView.class).put("lastDir", f.getParentFile().getAbsolutePath()); } updateMIDletList(); if(midletPicker.getModel().getSize() > 0) { midletPicker.setSelectedIndex(0); } updateOKEnabled(); } private void updateOKEnabled() { if(new File(jarFile.getText()).exists()) { okButton.setEnabled(true); } } private void pickJarFileActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_pickJarFileActionPerformed selectFile(jarFile, ".jar"); }//GEN-LAST:event_pickJarFileActionPerformed private void okButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_okButtonActionPerformed SwingUtilities.windowForComponent(this).dispose(); Preferences pref = Preferences.userNodeForPackage(ResourceEditorView.class); pref.put("jar", jarFile.getText()); pref.put("midlet", (String)midletPicker.getSelectedItem()); }//GEN-LAST:event_okButtonActionPerformed private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelButtonActionPerformed SwingUtilities.windowForComponent(this).dispose(); }//GEN-LAST:event_cancelButtonActionPerformed // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton cancelButton; private javax.swing.JLabel jLabel2; private javax.swing.JLabel jLabel3; private javax.swing.JScrollPane jScrollPane1; private javax.swing.JTextPane jTextPane1; private javax.swing.JTextField jarFile; private javax.swing.JComboBox midletPicker; private javax.swing.JButton okButton; private javax.swing.JButton pickJarFile; // End of variables declaration//GEN-END:variables }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy