├── .idea ├── .gitignore ├── compiler.xml ├── copyright │ └── profiles_settings.xml ├── misc.xml ├── modules.xml ├── uiDesigner.xml └── vcs.xml ├── README.markdown ├── SingletonTest.iml ├── SingletonTest.jar ├── demo ├── tip1.png ├── tip2.png └── tip3.png ├── resources └── META-INF │ └── plugin.xml └── src ├── res └── icon.jpg └── templete ├── GenerateType.java ├── ShowDialog.form ├── ShowDialog.java └── SingletonAction.java /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /workspace.xml 3 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/uiDesigner.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /README.markdown: -------------------------------------------------------------------------------- 1 | #studio 快速生成 单例模式的插件 2 | 3 | #单例的六种生成方式: 4 | 5 | LazyUnSafe,LazySafe,Hungry,DoubleCheck,StaticInner,Enum; 6 | 7 | #### [六种生成方式的参考](http://cantellow.iteye.com/blog/838473) 8 | 9 | 10 | #安装预设 11 | 12 | 1.Android studio 13 | File->Settings..->Plugins-->Browse repositores..搜索SingletonTest 14 | 2.安装插件,重启android studio 15 | 16 | #使用截图 17 | 18 | ![](./demo/tip1.png) 19 | ![](./demo/tip2.png) 20 | ![](./demo/tip3.png) 21 | 22 | # Reference&Thanks: 23 | 24 | https://github.com/zzz40500/GsonFormat 25 | -------------------------------------------------------------------------------- /SingletonTest.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /SingletonTest.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luhaoaimama1/SingletonTest/87c27aa80e32f4cd034f95b543d1fdfd2fb7002e/SingletonTest.jar -------------------------------------------------------------------------------- /demo/tip1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luhaoaimama1/SingletonTest/87c27aa80e32f4cd034f95b543d1fdfd2fb7002e/demo/tip1.png -------------------------------------------------------------------------------- /demo/tip2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luhaoaimama1/SingletonTest/87c27aa80e32f4cd034f95b543d1fdfd2fb7002e/demo/tip2.png -------------------------------------------------------------------------------- /demo/tip3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luhaoaimama1/SingletonTest/87c27aa80e32f4cd034f95b543d1fdfd2fb7002e/demo/tip3.png -------------------------------------------------------------------------------- /resources/META-INF/plugin.xml: -------------------------------------------------------------------------------- 1 | 2 | com.zone.unique.plugin.singleton 3 | SingletonTest 4 | 1.3 5 | 6 | 7 | 8 | zone 9 | 10 | 12 | ]]> 13 | 14 | 17 | 18 | fix EmptyThrowable: Icon cannot be found in '../res/icon.jpg'
19 | 20 | support 4.0 version
21 | ]]> 22 |
23 | 24 | 25 | 26 | 28 | 31 | 32 | com.intellij.modules.platform 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 45 | 46 | 47 | 48 | 49 |
-------------------------------------------------------------------------------- /src/res/icon.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luhaoaimama1/SingletonTest/87c27aa80e32f4cd034f95b543d1fdfd2fb7002e/src/res/icon.jpg -------------------------------------------------------------------------------- /src/templete/GenerateType.java: -------------------------------------------------------------------------------- 1 | package templete; 2 | 3 | /** 4 | * Created by fuzhipeng on 16/7/5. 5 | */ 6 | public enum GenerateType { 7 | LazyUnSafe,LazySafe,Hungry,DoubleCheck,StaticInner,Enum; 8 | 9 | public byte[] getBinaryContent(String packageString,String name) { 10 | String result = null; 11 | switch (this) { 12 | case LazyUnSafe: 13 | result=lazyUnSafe(packageString,name); 14 | break; 15 | 16 | case LazySafe: 17 | result=lazySafe(packageString,name); 18 | break; 19 | 20 | case StaticInner: 21 | result=staticInner(packageString,name); 22 | break; 23 | 24 | case Hungry: 25 | result=hungry(packageString,name); 26 | break; 27 | 28 | case DoubleCheck: 29 | result=doubleCheck(packageString,name); 30 | break; 31 | 32 | case Enum: 33 | result=enumString(packageString,name); 34 | break; 35 | 36 | default: 37 | break; 38 | } 39 | if(result==null||result.isEmpty()) 40 | return null; 41 | return (getPackageJoint(packageString)+result).getBytes(); 42 | }; 43 | private String getPackageJoint(String packageName){ 44 | if(packageName==null||packageName.trim().length()==0) 45 | return ""; 46 | else 47 | return "package " +packageName+";\n" + "\n" ; 48 | }; 49 | 50 | private String lazyUnSafe(String packageName,String className) { 51 | return 52 | "public class "+className+" {\n" + 53 | " private static "+className+" instance;\n" + 54 | "\n" + 55 | " private "+className+"() {\n" + 56 | " }\n" + 57 | "\n" + 58 | " public static "+className+" getInstance() {\n" + 59 | " if (instance == null) {\n" + 60 | " instance = new "+className+"();\n" + 61 | " }\n" + 62 | " return instance;\n" + 63 | " }\n" + 64 | "}"; 65 | } 66 | private String lazySafe(String packageName,String className){ 67 | return 68 | "public class "+className+" {\n" + 69 | " private static "+className+" instance;\n" + 70 | "\n" + 71 | " private "+className+"() {\n" + 72 | " }\n" + 73 | "\n" + 74 | " public static synchronized "+className+" getInstance() {\n" + 75 | " if (instance == null) {\n" + 76 | " instance = new "+className+"();\n" + 77 | " }\n" + 78 | " return instance;\n" + 79 | " }\n" + 80 | "}"; 81 | } 82 | private String staticInner(String packageName,String className){ 83 | return 84 | "public class "+className+" {\n" + 85 | "\n" + 86 | " private "+className+"() {\n" + 87 | " }\n" + 88 | "\n" + 89 | " private static class SingletonInstance {\n" + 90 | " private static final "+className+" INSTANCE = new "+className+"();\n" + 91 | " }\n" + 92 | "\n" + 93 | " public static "+className+" getInstance() {\n" + 94 | " return SingletonInstance.INSTANCE;\n" + 95 | " }\n" + 96 | "}"; 97 | } 98 | private String hungry(String packageName,String className){ 99 | return 100 | "public class "+className+" {\n" + 101 | " private static "+className+" instance = new "+className+"();\n" + 102 | "\n" + 103 | " private "+className+"() {\n" + 104 | " }\n" + 105 | "\n" + 106 | " public static "+className+" getInstance() {\n" + 107 | " return instance;\n" + 108 | " }\n" + 109 | "}"; 110 | } 111 | private String enumString(String packageName,String className){ 112 | return 113 | "public enum "+className+" {\n" + 114 | " INSTANCE;\n" + 115 | "}"; 116 | } 117 | private String doubleCheck(String packageName,String className){ 118 | return 119 | "public class "+className+" {\n" + 120 | "\n" + 121 | " private static volatile "+className+" singleton;\n" + 122 | "\n" + 123 | " private "+className+"() {\n" + 124 | " }\n" + 125 | "\n" + 126 | " public static "+className+" getInstance() {\n" + 127 | " if (singleton == null) {\n" + 128 | " synchronized ("+className+".class) {\n" + 129 | " if (singleton == null) {\n" + 130 | " singleton = new "+className+"();\n" + 131 | " }\n" + 132 | " }\n" + 133 | " }\n" + 134 | " return singleton;\n" + 135 | " }\n" + 136 | "}"; 137 | } 138 | 139 | } 140 | -------------------------------------------------------------------------------- /src/templete/ShowDialog.form: -------------------------------------------------------------------------------- 1 | 2 |
3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 |
102 | -------------------------------------------------------------------------------- /src/templete/ShowDialog.java: -------------------------------------------------------------------------------- 1 | package templete; 2 | 3 | import javax.swing.*; 4 | import java.awt.event.*; 5 | 6 | public class ShowDialog extends JDialog { 7 | private Callback callback; 8 | private JPanel contentPane; 9 | private JButton buttonCancel; 10 | private JButton buttonOK; 11 | private JTextField textField1; 12 | private JComboBox comboBox1; 13 | 14 | 15 | public ShowDialog() { 16 | setContentPane(contentPane); 17 | setModal(true); 18 | getRootPane().setDefaultButton(buttonOK); 19 | for (GenerateType type : GenerateType.values()) { 20 | comboBox1.addItem(type.name()); 21 | } 22 | comboBox1.setSelectedIndex(0); 23 | buttonCancel.addActionListener(new ActionListener() { 24 | public void actionPerformed(ActionEvent e) { 25 | onCancel(); 26 | } 27 | }); 28 | 29 | buttonOK.addActionListener(new ActionListener() { 30 | public void actionPerformed(ActionEvent e) { 31 | onOK(); 32 | } 33 | }); 34 | 35 | // call onCancel() when cross is clicked 36 | setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); 37 | addWindowListener(new WindowAdapter() { 38 | public void windowClosing(WindowEvent e) { 39 | onCancel(); 40 | } 41 | }); 42 | 43 | // call onCancel() on ESCAPE 44 | contentPane.registerKeyboardAction(new ActionListener() { 45 | public void actionPerformed(ActionEvent e) { 46 | onCancel(); 47 | } 48 | }, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); 49 | } 50 | 51 | private void onOK() { 52 | // add your code here 53 | callback.showDialogResult(textField1.getText().toString(), GenerateType.valueOf((String)comboBox1.getSelectedItem())); 54 | dispose(); 55 | } 56 | 57 | private void onCancel() { 58 | // add your code here if necessary 59 | dispose(); 60 | } 61 | 62 | public static void main(String[] args) { 63 | ShowDialog dialog = new ShowDialog(); 64 | dialog.pack(); 65 | dialog.setVisible(true); 66 | System.exit(0); 67 | } 68 | public void addCallback(Callback callback){ 69 | this.callback=callback; 70 | } 71 | public interface Callback{ 72 | void showDialogResult(String name, GenerateType type); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/templete/SingletonAction.java: -------------------------------------------------------------------------------- 1 | package templete; 2 | 3 | import com.intellij.openapi.actionSystem.*; 4 | import com.intellij.openapi.application.ApplicationManager; 5 | import com.intellij.openapi.command.CommandProcessor; 6 | import com.intellij.openapi.project.Project; 7 | import com.intellij.openapi.roots.ProjectRootManager; 8 | import com.intellij.openapi.util.IconLoader; 9 | import com.intellij.openapi.vfs.VirtualFile; 10 | import com.intellij.openapi.vfs.VirtualFileManager; 11 | import java.io.IOException; 12 | 13 | /** 14 | * Created by fuzhipeng on 16/7/5. 15 | */ 16 | public class SingletonAction extends AnAction { 17 | 18 | private VirtualFile folder; 19 | private Project project; 20 | private String name; 21 | private GenerateType type; 22 | private static final String SUFFIX=".java"; 23 | private boolean isSourceFolder; 24 | private String packageName; 25 | 26 | @Override 27 | public void actionPerformed(AnActionEvent e) { 28 | // Object navigatable = e.getData(CommonDataKeys.NAVIGATABLE);//获得该目录的名字 psi文件 29 | // if (navigatable != null) { 30 | // Messages.showDialog(navigatable.toString(), "Selected Element:", new String[]{"OK"}, -1, null); 31 | // } 32 | folder=e.getData(PlatformDataKeys.VIRTUAL_FILE); 33 | project=e.getProject(); 34 | 35 | 36 | try { 37 | ShowDialog sd=new ShowDialog(); 38 | sd.setSize(400, 150); 39 | sd.setLocationRelativeTo(null); 40 | sd.addCallback(callback); 41 | sd.setVisible(true); 42 | } catch (Exception e1) { 43 | e1.printStackTrace(); 44 | } 45 | 46 | } 47 | private ShowDialog.Callback callback=new ShowDialog.Callback() { 48 | @Override 49 | public void showDialogResult(String name, GenerateType type) { 50 | SingletonAction.this.name=name; 51 | SingletonAction.this.type=type; 52 | ApplicationManager.getApplication().runWriteAction(getRunnableWrapper(runnable)); 53 | } 54 | }; 55 | protected Runnable getRunnableWrapper(final Runnable runnable) { 56 | return new Runnable() { 57 | @Override 58 | public void run() { 59 | if(project==null) 60 | return ; 61 | //支持 undo 操作 62 | CommandProcessor.getInstance().executeCommand(project, runnable, " delete "+name+SUFFIX, ActionGroup.EMPTY_GROUP);//cut 是 undo 的描述 我应该填写类名 63 | } 64 | }; 65 | } 66 | 67 | final Runnable runnable = new Runnable() { 68 | @Override 69 | public void run() { 70 | if(folder==null) 71 | return; 72 | try { 73 | VirtualFile writeableFile = folder.createChildData(this, name+SUFFIX); 74 | writeableFile.setBinaryContent(type.getBinaryContent(packageName,name)); 75 | VirtualFileManager.getInstance().syncRefresh(); 76 | } catch (IOException e1) { 77 | e1.printStackTrace(); 78 | } 79 | } 80 | }; 81 | 82 | @Override 83 | public void update(final AnActionEvent e) { 84 | //Get required data keys 85 | // final Project project = e.getData(CommonDataKeys.PROJECT); 86 | // final Editor editor = e.getData(CommonDataKeys.EDITOR); 87 | 88 | //Set visibility only in case of existing project and editor 89 | VirtualFile operationFile = e.getData(PlatformDataKeys.VIRTUAL_FILE); 90 | 91 | if (operationFile!=null) { 92 | VirtualFile[] vFiles = ProjectRootManager.getInstance(e.getProject()).getContentSourceRoots(); 93 | checkSourceFolder(vFiles,operationFile); 94 | // e.getPresentation().setEnabled(editor != null); 95 | if (isSourceFolder) 96 | e.getPresentation().setIcon(IconLoader.getIcon("/res/icon.jpg")); 97 | // try { 98 | // e.getPresentation().setIcon(IconLoader.getIcon("../res/icon.jpg")); 99 | // } catch (Exception e1) { 100 | // 101 | //// e1.printStackTrace(); 102 | // } 103 | e.getPresentation().setVisible(isSourceFolder);//该action 的可见性 104 | }else 105 | e.getPresentation().setVisible(false);// 106 | 107 | } 108 | public void checkSourceFolder(VirtualFile[] sourceFiles,VirtualFile operationFile){ 109 | isSourceFolder=false; 110 | for (VirtualFile sourceFile : sourceFiles) { 111 | if(operationFile.getPath().contains(sourceFile.getPath())) { 112 | isSourceFolder =operationFile.isDirectory(); 113 | packageName = operationFile.getPath().replace(sourceFile.getPath(), ""); 114 | packageName =packageName.replace("/","."); 115 | if(packageName.length()>0&&".".equals(packageName.substring(0,1))) 116 | packageName=packageName.substring(1); 117 | else 118 | packageName=""; 119 | break; 120 | } 121 | } 122 | } 123 | } 124 | --------------------------------------------------------------------------------