├── .github └── FUNDING.yml ├── .gitignore ├── LICENSE ├── README.md ├── build.xml ├── manifest.mf ├── nbproject ├── build-impl.xml ├── genfiles.properties ├── platform.properties ├── project.properties └── project.xml ├── pom.xml └── src └── com └── junichi11 └── netbeans └── gitignoreio ├── Bundle.properties ├── options └── GitignoreioOptions.java └── ui ├── Bundle.properties ├── GitignoreListPanel.form ├── GitignoreListPanel.java └── actions └── GenerateGitIgnoreAction.java /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: junichi11 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | nbproject/private 3 | lib 4 | pom.xml.asc 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # NetBeans gitignore.io Plugin 2 | 3 | Support for gitignore.io. This plugin generates .gitignore file to your project node. 4 | 5 | ## Plugin Portal (Download) 6 | 7 | - http://plugins.netbeans.org/plugin/50356/gitignore-io 8 | 9 | ## What's gitignore.io? 10 | 11 | - https://gitignore.io 12 | 13 | ## Requirements 14 | 15 | - NetBeans 8.0 or newer 16 | 17 | ## Usage 18 | 19 | - Right-click the project node 20 | - Click Generate gitignore file 21 | - Click gitignore items or input specific items to text area on the dialog 22 | 23 | ### Notice 24 | 25 | Warning dialog is shown with the following cases: 26 | 27 | - .gitignore already exists 28 | - Isn't connected to an internet 29 | 30 | ## Issues 31 | 32 | If you hava some problems, please submit them to the github issue tracker. 33 | (Please don't submit them to NetBeans bugzilla.) 34 | 35 | ## Donation 36 | 37 | - https://github.com/sponsors/junichi11 38 | 39 | ## License 40 | 41 | The Apache License, Version 2.0 42 | 43 | ``` 44 | Copyright 2020 junichi11. 45 | 46 | Licensed under the Apache License, Version 2.0 (the "License"); 47 | you may not use this file except in compliance with the License. 48 | You may obtain a copy of the License at 49 | 50 | http://www.apache.org/licenses/LICENSE-2.0 51 | 52 | Unless required by applicable law or agreed to in writing, software 53 | distributed under the License is distributed on an "AS IS" BASIS, 54 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 55 | See the License for the specific language governing permissions and 56 | limitations under the License. 57 | ``` 58 | -------------------------------------------------------------------------------- /build.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Builds, tests, and runs the project com.junichi11.netbeans.gitignoreio. 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 20 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 32 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /manifest.mf: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | OpenIDE-Module: com.junichi11.netbeans.gitignoreio 3 | OpenIDE-Module-Localizing-Bundle: com/junichi11/netbeans/gitignoreio/Bundle.properties 4 | OpenIDE-Module-Specification-Version: 1.1.0 5 | 6 | -------------------------------------------------------------------------------- /nbproject/build-impl.xml: -------------------------------------------------------------------------------- 1 | 2 | 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 | -------------------------------------------------------------------------------- /nbproject/genfiles.properties: -------------------------------------------------------------------------------- 1 | build.xml.data.CRC32=a90dcdbb 2 | build.xml.script.CRC32=ca76860a 3 | build.xml.stylesheet.CRC32=15ca8a54@2.75.1 4 | # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. 5 | # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. 6 | nbproject/build-impl.xml.data.CRC32=a90dcdbb 7 | nbproject/build-impl.xml.script.CRC32=913696c2 8 | nbproject/build-impl.xml.stylesheet.CRC32=49aa68b0@2.75.1 9 | -------------------------------------------------------------------------------- /nbproject/platform.properties: -------------------------------------------------------------------------------- 1 | cluster.path=\ 2 | ${nbplatform.active.dir}/nb:\ 3 | ${nbplatform.active.dir}/platform:\ 4 | ${nbplatform.active.dir}/apisupport:\ 5 | ${nbplatform.active.dir}/php:\ 6 | ${nbplatform.active.dir}/ide:\ 7 | ${nbplatform.active.dir}/websvccommon:\ 8 | ${nbplatform.active.dir}/webcommon:\ 9 | ${nbplatform.active.dir}/harness 10 | nbplatform.active=default 11 | -------------------------------------------------------------------------------- /nbproject/project.properties: -------------------------------------------------------------------------------- 1 | javac.source=1.8 2 | javac.compilerargs=-Xlint -Xlint:-serial 3 | license.file=LICENSE 4 | nbm.homepage=https://github.com/junichi11/netbeans-gitignore-io-plugin 5 | nbm.module.author=junichi11 6 | project.license=apache20 7 | keystore=nbproject/private/keystore 8 | nbm_alias=gitignoreio 9 | -------------------------------------------------------------------------------- /nbproject/project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | org.netbeans.modules.apisupport.project 4 | 5 | 6 | com.junichi11.netbeans.gitignoreio 7 | 8 | 9 | 10 | org.netbeans.modules.csl.api 11 | 12 | 13 | 14 | 2 15 | 2.33.3.2.1.1.6 16 | 17 | 18 | 19 | org.netbeans.modules.csl.types 20 | 21 | 22 | 23 | 1 24 | 1.3.1 25 | 26 | 27 | 28 | org.netbeans.modules.parsing.api 29 | 30 | 31 | 32 | 1 33 | 9.5.1.8 34 | 35 | 36 | 37 | org.netbeans.modules.projectapi 38 | 39 | 40 | 41 | 1 42 | 1.50.1 43 | 44 | 45 | 46 | org.openide.awt 47 | 48 | 49 | 50 | 7.55.1 51 | 52 | 53 | 54 | org.openide.dialogs 55 | 56 | 57 | 58 | 7.28.1 59 | 60 | 61 | 62 | org.openide.filesystems 63 | 64 | 65 | 66 | 9.8.1 67 | 68 | 69 | 70 | org.openide.filesystems.nb 71 | 72 | 73 | 74 | 9.7.1 75 | 76 | 77 | 78 | org.openide.util 79 | 80 | 81 | 82 | 8.29.3 83 | 84 | 85 | 86 | org.openide.util.lookup 87 | 88 | 89 | 90 | 8.19.1 91 | 92 | 93 | 94 | org.openide.util.ui 95 | 96 | 97 | 98 | 9.4.1 99 | 100 | 101 | 102 | 103 | 104 | unit 105 | 106 | org.netbeans.libs.junit4 107 | 108 | 109 | 110 | org.netbeans.modules.nbjunit 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | com.junichi11.netbeans.modules 5 | netbeans-gitignore-io 6 | 7 | 1.1.0 8 | nbm 9 | NetBeans gitignore.io Plugin 10 | https://github.com/junichi11/netbeans-gitignore-io-plugin 11 | Support for gitignore.io. This plugin generates .gitignore file to your project node. 12 | 13 | 14 | junichi11 15 | Junichi Yamamoto 16 | https://github.com/junichi11 17 | 18 | 19 | 20 | scm:git:https://github.com/junichi11/netbeans-gitignore-io-plugin.git 21 | scm:git:https://github.com/junichi11/netbeans-gitignore-io-plugin.git 22 | https://github.com/junichi11/netbeans-gitignore-io-plugin 23 | HEAD 24 | 25 | 26 | 27 | Apache License, Version 2.0 28 | https://www.apache.org/licenses/LICENSE-2.0 29 | 30 | 31 | 32 | 33 | ossrh 34 | https://oss.sonatype.org/content/repositories/snapshots 35 | 36 | 37 | ossrh 38 | https://oss.sonatype.org/service/local/staging/deploy/maven2/ 39 | 40 | 41 | 42 | 43 | 44 | org.apache.maven.plugins 45 | maven-deploy-plugin 46 | 3.0.0-M1 47 | 48 | 49 | org.sonatype.plugins 50 | nexus-staging-maven-plugin 51 | 1.6.7 52 | true 53 | 54 | ossrh 55 | https://oss.sonatype.org/ 56 | true 57 | 58 | 59 | 60 | org.apache.maven.plugins 61 | maven-compiler-plugin 62 | 3.8.1 63 | 64 | 1.8 65 | 1.8 66 | 67 | 68 | 69 | org.apache.maven.plugins 70 | maven-jar-plugin 71 | 3.1.2 72 | 73 | 74 | ${project.build.outputDirectory}/META-INF/MANIFEST.MF 75 | 76 | 77 | 78 | 79 | org.apache.maven.plugins 80 | maven-gpg-plugin 81 | 1.6 82 | 83 | 84 | sign-artifacts 85 | verify 86 | 87 | sign 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /src/com/junichi11/netbeans/gitignoreio/Bundle.properties: -------------------------------------------------------------------------------- 1 | OpenIDE-Module-Display-Category=Versioning 2 | OpenIDE-Module-Long-Description=\ 3 |

NetBeans gitignore.io Plugin

\n

Support for gitignore.io. \ 4 | This plugin generates .gitignore file to your project node.\ 5 |

\n

Plugin Portal (Download)

\n

What's gitignore.io?\ 6 |

\n

Requirements

\n\n

Usage

\n

Notice

Warning dialog is shown with the following cases:

\n\n

Issues

\n

If you hava some problems, please submit them to the github issue tracker. \ 7 | (Please don't submit them to NetBeans bugzilla.)\ 8 |

9 | OpenIDE-Module-Name=gitignore.io 10 | OpenIDE-Module-Short-Description=Support for gitignore.io 11 | -------------------------------------------------------------------------------- /src/com/junichi11/netbeans/gitignoreio/options/GitignoreioOptions.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 junichi11. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.junichi11.netbeans.gitignoreio.options; 17 | 18 | import java.util.prefs.Preferences; 19 | import org.openide.util.NbPreferences; 20 | 21 | /** 22 | * 23 | * @author junichi11 24 | */ 25 | public final class GitignoreioOptions { 26 | 27 | private static final GitignoreioOptions INSTANCE = new GitignoreioOptions(); 28 | private static final String DEFAULT_GITIGNORES = "default.gitignores"; // NOI18N 29 | 30 | private GitignoreioOptions() { 31 | } 32 | 33 | public static GitignoreioOptions getInstance() { 34 | return INSTANCE; 35 | } 36 | 37 | public String getDefaultGitignores() { 38 | return getPreferences().get(DEFAULT_GITIGNORES, ""); // NOI18N 39 | } 40 | 41 | public void setDefaultGitignores(String gitignores) { 42 | getPreferences().put(DEFAULT_GITIGNORES, gitignores); 43 | } 44 | 45 | private Preferences getPreferences() { 46 | return NbPreferences.forModule(GitignoreioOptions.class); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/com/junichi11/netbeans/gitignoreio/ui/Bundle.properties: -------------------------------------------------------------------------------- 1 | GitignoreListPanel.availableListLabel.text=Available list: 2 | GitignoreListPanel.loadDefaultButton.text=Load Default 3 | GitignoreListPanel.saveAsDefaultButton.text=Save as Default 4 | GitignoreListPanel.gitignoresTextField.text= 5 | GitignoreListPanel.resetButton.text=Reset 6 | GitignoreListPanel.normalRadioButton.text=normal 7 | GitignoreListPanel.overwriteRadioButton.text=overwrite 8 | GitignoreListPanel.postscriptRadioButton.text=postscript 9 | GitignoreListPanel.filterLabel.text=Filter: 10 | GitignoreListPanel.filterTextField.text= 11 | GitignoreListPanel.filePathTextField.text= 12 | GitignoreListPanel.browseButton.text=Browse... 13 | GitignoreListPanel.messageLabel.text=MESSAGE 14 | -------------------------------------------------------------------------------- /src/com/junichi11/netbeans/gitignoreio/ui/GitignoreListPanel.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 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 |
249 | -------------------------------------------------------------------------------- /src/com/junichi11/netbeans/gitignoreio/ui/GitignoreListPanel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 junichi11. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.junichi11.netbeans.gitignoreio.ui; 17 | 18 | import com.junichi11.netbeans.gitignoreio.options.GitignoreioOptions; 19 | import java.awt.Dialog; 20 | import java.io.BufferedInputStream; 21 | import java.io.BufferedReader; 22 | import java.io.File; 23 | import java.io.IOException; 24 | import java.io.InputStreamReader; 25 | import java.net.MalformedURLException; 26 | import java.net.URL; 27 | import java.net.URLConnection; 28 | import java.util.ArrayList; 29 | import java.util.Arrays; 30 | import java.util.List; 31 | import java.util.logging.Level; 32 | import java.util.logging.Logger; 33 | import javax.net.ssl.HttpsURLConnection; 34 | import javax.swing.DefaultListModel; 35 | import javax.swing.JList; 36 | import javax.swing.JPanel; 37 | import javax.swing.SwingUtilities; 38 | import javax.swing.event.DocumentEvent; 39 | import javax.swing.event.DocumentListener; 40 | import org.openide.DialogDescriptor; 41 | import org.openide.DialogDisplayer; 42 | import org.openide.filesystems.FileChooserBuilder; 43 | import org.openide.filesystems.FileObject; 44 | import org.openide.filesystems.FileUtil; 45 | import org.openide.util.NbBundle; 46 | import org.openide.util.RequestProcessor; 47 | 48 | /** 49 | * 50 | * @author junichi11 51 | */ 52 | public class GitignoreListPanel extends JPanel { 53 | 54 | private volatile boolean isConnectedNetwork = true; 55 | private volatile boolean initilized = false; 56 | 57 | private static final String GITIGNORE_API = "https://www.gitignore.io/api/"; // NOI18N 58 | private static final String GITIGNORE_API_LIST = GITIGNORE_API + "list"; // NOI18N 59 | private static final String FORMAT_LINES = "lines"; // NOI18N 60 | private static final String FORMAT_JSON = "json"; // NOI18N 61 | private static final String UTF8 = "UTF-8"; // NOI18N 62 | private static final String GITIGNORE_LAST_FOLDER_SUFFIX = ".gitignore"; // NOI18N 63 | private static List GITIGNORES; 64 | private static final GitignoreListPanel INSTANCE = new GitignoreListPanel(); 65 | private static final long serialVersionUID = -5226048221599145625L; 66 | private static final Logger LOGGER = Logger.getLogger(GitignoreListPanel.class.getName()); 67 | private static final RequestProcessor RP = new RequestProcessor(GitignoreListPanel.class); 68 | 69 | /** 70 | * Creates new form GitignoreListPanel 71 | */ 72 | public GitignoreListPanel() { 73 | initComponents(); 74 | } 75 | 76 | public static GitignoreListPanel getDefault() { 77 | if (!INSTANCE.initilized) { 78 | INSTANCE.init(); 79 | INSTANCE.initilized = true; 80 | } 81 | 82 | // retry 83 | if (!INSTANCE.isConnectedNetwork) { 84 | INSTANCE.init(); 85 | } 86 | return INSTANCE; 87 | } 88 | 89 | private void init() { 90 | setMessage(""); // NOI18N 91 | DefaultListModel model = new DefaultListModel<>(); 92 | availableList.setModel(model); 93 | addGitignores(""); // NOI18N 94 | normalRadioButton.setSelected(true); 95 | 96 | // add listener 97 | filterTextField.getDocument().addDocumentListener(new DocumentListener() { 98 | 99 | @Override 100 | public void insertUpdate(DocumentEvent e) { 101 | processUpdate(); 102 | } 103 | 104 | @Override 105 | public void removeUpdate(DocumentEvent e) { 106 | processUpdate(); 107 | } 108 | 109 | @Override 110 | public void changedUpdate(DocumentEvent e) { 111 | processUpdate(); 112 | } 113 | 114 | private void processUpdate() { 115 | String text = filterTextField.getText(); 116 | addGitignores(text); 117 | } 118 | }); 119 | } 120 | 121 | private void addGitignores(String filter) { 122 | if (filter == null) { 123 | return; 124 | } 125 | DefaultListModel model = (DefaultListModel) availableList.getModel(); 126 | model.clear(); 127 | 128 | filter = filter.replaceAll("\\s+", " "); // NOI18N 129 | String[] filters = filter.split(" "); // NOI18N 130 | List availableGitignores = getAvailableGitignores(); 131 | if (availableGitignores != null) { 132 | availableGitignores.forEach((gitignore) -> { 133 | for (String f : filters) { 134 | if (gitignore.contains(f)) { 135 | model.addElement(gitignore); 136 | } 137 | } 138 | }); 139 | availableList.setModel(model); 140 | } 141 | } 142 | 143 | public String getGitignoreContent() throws MalformedURLException, IOException { 144 | String gitignores = getGitignores(); 145 | String url = GITIGNORE_API + gitignores; 146 | HttpsURLConnection connection = openUrlConnection(url); 147 | return getContent(connection, UTF8); 148 | } 149 | 150 | private HttpsURLConnection openUrlConnection(String url) throws IOException { 151 | HttpsURLConnection connection = (HttpsURLConnection) new URL(url).openConnection(); 152 | connection.setRequestMethod("GET"); // NOI18N 153 | connection.setRequestProperty("User-Agent", "NetBeans Plugin"); 154 | connection.setReadTimeout(2000); 155 | connection.setConnectTimeout(2000); 156 | return connection; 157 | } 158 | 159 | public String getGitignores() { 160 | return gitignoresTextField.getText().trim(); 161 | } 162 | 163 | public void setGitignores(String ignores) { 164 | gitignoresTextField.setText(ignores); 165 | } 166 | 167 | public boolean isNormal() { 168 | return normalRadioButton.isSelected(); 169 | } 170 | 171 | public boolean isOverwrite() { 172 | return overwriteRadioButton.isSelected(); 173 | } 174 | 175 | public boolean isPostscript() { 176 | return postscriptRadioButton.isSelected(); 177 | } 178 | 179 | public void setEnabledOverwrite(boolean isEnabled) { 180 | overwriteRadioButton.setEnabled(isEnabled); 181 | if (!isEnabled && isOverwrite()) { 182 | normalRadioButton.setSelected(true); 183 | } 184 | } 185 | 186 | public void setEnabledPostscript(boolean isEnabled) { 187 | postscriptRadioButton.setEnabled(isEnabled); 188 | if (!isEnabled && isPostscript()) { 189 | normalRadioButton.setSelected(true); 190 | } 191 | } 192 | 193 | public String getFilePath() { 194 | return filePathTextField.getText(); 195 | } 196 | 197 | public void setFilePath(String filePath) { 198 | filePathTextField.setText(filePath); 199 | } 200 | 201 | private void setMessage(String message) { 202 | messageLabel.setText(message); 203 | } 204 | 205 | @NbBundle.Messages({ 206 | "GitignoreListPanel.dialog.title=gitignore.io available list", 207 | "GitignoreListPanel.network.error=You have to connect to the Internet." 208 | }) 209 | public DialogDescriptor showDialog() throws IOException { 210 | if (!isConnectedNetwork) { 211 | throw new IOException(Bundle.GitignoreListPanel_network_error()); 212 | } 213 | DialogDescriptor descriptor = new DialogDescriptor(this, Bundle.GitignoreListPanel_dialog_title()); 214 | Dialog dialog = DialogDisplayer.getDefault().createDialog(descriptor); 215 | dialog.pack(); 216 | dialog.setVisible(true); 217 | return descriptor; 218 | } 219 | 220 | @NbBundle.Messages({ 221 | "GitignoreListPanel.message.getting=Getting the available list...", 222 | }) 223 | private synchronized List getAvailableGitignores() { 224 | if (GITIGNORES == null) { 225 | setMessage(Bundle.GitignoreListPanel_message_getting()); 226 | RP.post(() -> { 227 | GITIGNORES = new ArrayList<>(); 228 | String gitignoreList = getAvailableGitignoresText(); 229 | if (gitignoreList != null) { 230 | String[] gitignores = splitGitignores(gitignoreList); 231 | Arrays.sort(gitignores); 232 | GITIGNORES.addAll(Arrays.asList(gitignores)); 233 | SwingUtilities.invokeLater(() -> { 234 | addGitignores(""); // NOI18N 235 | setMessage(""); // NOI18N 236 | }); 237 | } 238 | }); 239 | } 240 | return GITIGNORES; 241 | } 242 | 243 | @NbBundle.Messages({ 244 | "GitignoreListPanel.message.connection.error=Connection error", 245 | }) 246 | private String getAvailableGitignoresText() { 247 | String list = null; 248 | try { 249 | // #5 now use the "lines" format option 250 | HttpsURLConnection openConnection = openUrlConnection(getApiListURL(FORMAT_LINES)); 251 | list = getContent(openConnection, UTF8); 252 | isConnectedNetwork = true; 253 | } catch (MalformedURLException ex) { 254 | LOGGER.log(Level.WARNING, ex.getMessage()); 255 | isConnectedNetwork = false; 256 | } catch (IOException ex) { 257 | LOGGER.log(Level.WARNING, ex.getMessage()); 258 | setMessage(Bundle.GitignoreListPanel_message_connection_error()); 259 | isConnectedNetwork = false; 260 | } 261 | return list; 262 | } 263 | 264 | private String getApiListURL(String format) { 265 | String formatParam = String.format("format=%s", format); // NOI18N 266 | StringBuilder sb = new StringBuilder(); 267 | sb.append(GITIGNORE_API_LIST); 268 | sb.append("?"); // NOI18N 269 | sb.append(formatParam); 270 | return sb.toString(); 271 | } 272 | 273 | private String getContent(URLConnection connection, String charset) throws IOException { 274 | StringBuilder sb = new StringBuilder(); 275 | BufferedInputStream inuptStream = new BufferedInputStream(connection.getInputStream()); 276 | BufferedReader reader = new BufferedReader(new InputStreamReader(inuptStream, charset)); // NOI18N 277 | String line; 278 | while ((line = reader.readLine()) != null) { 279 | sb.append(line).append("\n"); // NOI18N 280 | } 281 | 282 | return sb.toString(); 283 | } 284 | 285 | private String[] splitGitignores(String gitignores) { 286 | // #5 new use the "lines" format option 287 | return gitignores.split("\n"); // NOI18N 288 | } 289 | 290 | private GitignoreioOptions getOptions() { 291 | return GitignoreioOptions.getInstance(); 292 | } 293 | 294 | /** 295 | * This method is called from within the constructor to initialize the form. 296 | * WARNING: Do NOT modify this code. The content of this method is always 297 | * regenerated by the Form Editor. 298 | */ 299 | @SuppressWarnings("unchecked") 300 | // //GEN-BEGIN:initComponents 301 | private void initComponents() { 302 | 303 | writeOptionButtonGroup = new javax.swing.ButtonGroup(); 304 | availableListLabel = new javax.swing.JLabel(); 305 | availableListScrollPane = new javax.swing.JScrollPane(); 306 | availableList = new javax.swing.JList<>(); 307 | gitignoresTextField = new javax.swing.JTextField(); 308 | saveAsDefaultButton = new javax.swing.JButton(); 309 | loadDefaultButton = new javax.swing.JButton(); 310 | resetButton = new javax.swing.JButton(); 311 | normalRadioButton = new javax.swing.JRadioButton(); 312 | overwriteRadioButton = new javax.swing.JRadioButton(); 313 | postscriptRadioButton = new javax.swing.JRadioButton(); 314 | filterTextField = new javax.swing.JTextField(); 315 | filterLabel = new javax.swing.JLabel(); 316 | browseButton = new javax.swing.JButton(); 317 | filePathTextField = new javax.swing.JTextField(); 318 | messageLabel = new javax.swing.JLabel(); 319 | 320 | org.openide.awt.Mnemonics.setLocalizedText(availableListLabel, org.openide.util.NbBundle.getMessage(GitignoreListPanel.class, "GitignoreListPanel.availableListLabel.text")); // NOI18N 321 | 322 | availableList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION); 323 | availableList.addMouseListener(new java.awt.event.MouseAdapter() { 324 | public void mouseReleased(java.awt.event.MouseEvent evt) { 325 | availableListMouseReleased(evt); 326 | } 327 | }); 328 | availableList.addListSelectionListener(new javax.swing.event.ListSelectionListener() { 329 | public void valueChanged(javax.swing.event.ListSelectionEvent evt) { 330 | availableListValueChanged(evt); 331 | } 332 | }); 333 | availableListScrollPane.setViewportView(availableList); 334 | 335 | gitignoresTextField.setText(org.openide.util.NbBundle.getMessage(GitignoreListPanel.class, "GitignoreListPanel.gitignoresTextField.text")); // NOI18N 336 | 337 | org.openide.awt.Mnemonics.setLocalizedText(saveAsDefaultButton, org.openide.util.NbBundle.getMessage(GitignoreListPanel.class, "GitignoreListPanel.saveAsDefaultButton.text")); // NOI18N 338 | saveAsDefaultButton.addActionListener(new java.awt.event.ActionListener() { 339 | public void actionPerformed(java.awt.event.ActionEvent evt) { 340 | saveAsDefaultButtonActionPerformed(evt); 341 | } 342 | }); 343 | 344 | org.openide.awt.Mnemonics.setLocalizedText(loadDefaultButton, org.openide.util.NbBundle.getMessage(GitignoreListPanel.class, "GitignoreListPanel.loadDefaultButton.text")); // NOI18N 345 | loadDefaultButton.addActionListener(new java.awt.event.ActionListener() { 346 | public void actionPerformed(java.awt.event.ActionEvent evt) { 347 | loadDefaultButtonActionPerformed(evt); 348 | } 349 | }); 350 | 351 | org.openide.awt.Mnemonics.setLocalizedText(resetButton, org.openide.util.NbBundle.getMessage(GitignoreListPanel.class, "GitignoreListPanel.resetButton.text")); // NOI18N 352 | resetButton.addActionListener(new java.awt.event.ActionListener() { 353 | public void actionPerformed(java.awt.event.ActionEvent evt) { 354 | resetButtonActionPerformed(evt); 355 | } 356 | }); 357 | 358 | writeOptionButtonGroup.add(normalRadioButton); 359 | org.openide.awt.Mnemonics.setLocalizedText(normalRadioButton, org.openide.util.NbBundle.getMessage(GitignoreListPanel.class, "GitignoreListPanel.normalRadioButton.text")); // NOI18N 360 | 361 | writeOptionButtonGroup.add(overwriteRadioButton); 362 | org.openide.awt.Mnemonics.setLocalizedText(overwriteRadioButton, org.openide.util.NbBundle.getMessage(GitignoreListPanel.class, "GitignoreListPanel.overwriteRadioButton.text")); // NOI18N 363 | 364 | writeOptionButtonGroup.add(postscriptRadioButton); 365 | org.openide.awt.Mnemonics.setLocalizedText(postscriptRadioButton, org.openide.util.NbBundle.getMessage(GitignoreListPanel.class, "GitignoreListPanel.postscriptRadioButton.text")); // NOI18N 366 | 367 | filterTextField.setText(org.openide.util.NbBundle.getMessage(GitignoreListPanel.class, "GitignoreListPanel.filterTextField.text")); // NOI18N 368 | 369 | org.openide.awt.Mnemonics.setLocalizedText(filterLabel, org.openide.util.NbBundle.getMessage(GitignoreListPanel.class, "GitignoreListPanel.filterLabel.text")); // NOI18N 370 | 371 | org.openide.awt.Mnemonics.setLocalizedText(browseButton, org.openide.util.NbBundle.getMessage(GitignoreListPanel.class, "GitignoreListPanel.browseButton.text")); // NOI18N 372 | browseButton.addActionListener(new java.awt.event.ActionListener() { 373 | public void actionPerformed(java.awt.event.ActionEvent evt) { 374 | browseButtonActionPerformed(evt); 375 | } 376 | }); 377 | 378 | filePathTextField.setEditable(false); 379 | filePathTextField.setText(org.openide.util.NbBundle.getMessage(GitignoreListPanel.class, "GitignoreListPanel.filePathTextField.text")); // NOI18N 380 | 381 | org.openide.awt.Mnemonics.setLocalizedText(messageLabel, org.openide.util.NbBundle.getMessage(GitignoreListPanel.class, "GitignoreListPanel.messageLabel.text")); // NOI18N 382 | 383 | javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); 384 | this.setLayout(layout); 385 | layout.setHorizontalGroup( 386 | layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 387 | .addGroup(layout.createSequentialGroup() 388 | .addContainerGap() 389 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 390 | .addComponent(messageLabel) 391 | .addComponent(availableListLabel)) 392 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) 393 | .addComponent(resetButton) 394 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 395 | .addComponent(loadDefaultButton) 396 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 397 | .addComponent(saveAsDefaultButton) 398 | .addContainerGap()) 399 | .addGroup(layout.createSequentialGroup() 400 | .addGap(12, 12, 12) 401 | .addComponent(normalRadioButton) 402 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 403 | .addComponent(overwriteRadioButton) 404 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 405 | .addComponent(postscriptRadioButton) 406 | .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) 407 | .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() 408 | .addContainerGap() 409 | .addComponent(filePathTextField) 410 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 411 | .addComponent(browseButton) 412 | .addGap(12, 12, 12)) 413 | .addGroup(layout.createSequentialGroup() 414 | .addGap(12, 12, 12) 415 | .addComponent(filterLabel) 416 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 417 | .addComponent(filterTextField) 418 | .addContainerGap()) 419 | .addGroup(layout.createSequentialGroup() 420 | .addGap(12, 12, 12) 421 | .addComponent(gitignoresTextField) 422 | .addGap(12, 12, 12)) 423 | .addGroup(layout.createSequentialGroup() 424 | .addGap(12, 12, 12) 425 | .addComponent(availableListScrollPane) 426 | .addGap(12, 12, 12)) 427 | ); 428 | layout.setVerticalGroup( 429 | layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 430 | .addGroup(layout.createSequentialGroup() 431 | .addContainerGap() 432 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) 433 | .addComponent(availableListLabel) 434 | .addComponent(saveAsDefaultButton) 435 | .addComponent(loadDefaultButton) 436 | .addComponent(resetButton)) 437 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 438 | .addComponent(messageLabel) 439 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 440 | .addComponent(availableListScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 98, Short.MAX_VALUE) 441 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 442 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) 443 | .addComponent(filterTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) 444 | .addComponent(filterLabel)) 445 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 446 | .addComponent(gitignoresTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) 447 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 448 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) 449 | .addComponent(normalRadioButton) 450 | .addComponent(overwriteRadioButton) 451 | .addComponent(postscriptRadioButton)) 452 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 453 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) 454 | .addComponent(browseButton) 455 | .addComponent(filePathTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) 456 | .addContainerGap()) 457 | ); 458 | }// //GEN-END:initComponents 459 | 460 | private void availableListValueChanged(javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_availableListValueChanged 461 | // Object[] gitignores = availableList.getSelectedValues(); 462 | // StringBuilder sb = new StringBuilder(); 463 | // for (Object gitignore : gitignores) { 464 | // sb.append((String) gitignore).append(","); // NOI18N 465 | // } 466 | // int length = sb.length(); 467 | // if (length > 0) { 468 | // sb.deleteCharAt(length - 1); 469 | // } 470 | // gitignoresTextField.setText(sb.toString()); 471 | }//GEN-LAST:event_availableListValueChanged 472 | 473 | private void loadDefaultButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_loadDefaultButtonActionPerformed 474 | gitignoresTextField.setText(getOptions().getDefaultGitignores()); 475 | }//GEN-LAST:event_loadDefaultButtonActionPerformed 476 | 477 | private void saveAsDefaultButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveAsDefaultButtonActionPerformed 478 | getOptions().setDefaultGitignores(getGitignores()); 479 | }//GEN-LAST:event_saveAsDefaultButtonActionPerformed 480 | 481 | private void availableListMouseReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_availableListMouseReleased 482 | Object source = evt.getSource(); 483 | JList list; 484 | if (source instanceof JList) { 485 | list = (JList) source; 486 | } else { 487 | return; 488 | } 489 | String selectedValue = (String) list.getSelectedValue(); 490 | String gitignores = getGitignores(); 491 | String[] items = gitignores.split(","); // NOI18N 492 | if (Arrays.asList(items).contains(selectedValue)) { 493 | return; 494 | } 495 | 496 | // add value 497 | if (gitignores.isEmpty()) { 498 | setGitignores(selectedValue); 499 | } else { 500 | setGitignores(gitignores + "," + selectedValue); // NOI18N 501 | } 502 | }//GEN-LAST:event_availableListMouseReleased 503 | 504 | private void resetButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_resetButtonActionPerformed 505 | setGitignores(""); // NOI18N 506 | }//GEN-LAST:event_resetButtonActionPerformed 507 | 508 | @NbBundle.Messages({ 509 | "GitignoreListPanel.browseButton.title=Select a directory" 510 | }) 511 | private void browseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_browseButtonActionPerformed 512 | File file = new FileChooserBuilder(GitignoreListPanel.class.getName() + GITIGNORE_LAST_FOLDER_SUFFIX) 513 | .setDirectoriesOnly(true) 514 | .setTitle(Bundle.GitignoreListPanel_browseButton_title()) 515 | .showOpenDialog(); 516 | if (file != null && file.isDirectory()) { 517 | filePathTextField.setText(file.getAbsolutePath()); 518 | FileObject targetDirectory = FileUtil.toFileObject(file); 519 | FileObject gitignoreFile = targetDirectory.getFileObject(".gitignore"); // NOI18N 520 | boolean exists = gitignoreFile != null; 521 | setEnabledOverwrite(exists); 522 | setEnabledPostscript(exists); 523 | } 524 | }//GEN-LAST:event_browseButtonActionPerformed 525 | 526 | // Variables declaration - do not modify//GEN-BEGIN:variables 527 | private javax.swing.JList availableList; 528 | private javax.swing.JLabel availableListLabel; 529 | private javax.swing.JScrollPane availableListScrollPane; 530 | private javax.swing.JButton browseButton; 531 | private javax.swing.JTextField filePathTextField; 532 | private javax.swing.JLabel filterLabel; 533 | private javax.swing.JTextField filterTextField; 534 | private javax.swing.JTextField gitignoresTextField; 535 | private javax.swing.JButton loadDefaultButton; 536 | private javax.swing.JLabel messageLabel; 537 | private javax.swing.JRadioButton normalRadioButton; 538 | private javax.swing.JRadioButton overwriteRadioButton; 539 | private javax.swing.JRadioButton postscriptRadioButton; 540 | private javax.swing.JButton resetButton; 541 | private javax.swing.JButton saveAsDefaultButton; 542 | private javax.swing.ButtonGroup writeOptionButtonGroup; 543 | // End of variables declaration//GEN-END:variables 544 | } 545 | -------------------------------------------------------------------------------- /src/com/junichi11/netbeans/gitignoreio/ui/actions/GenerateGitIgnoreAction.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 junichi11. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.junichi11.netbeans.gitignoreio.ui.actions; 17 | 18 | import com.junichi11.netbeans.gitignoreio.ui.GitignoreListPanel; 19 | import java.awt.event.ActionEvent; 20 | import java.awt.event.ActionListener; 21 | import java.io.File; 22 | import java.io.FileNotFoundException; 23 | import java.io.FileOutputStream; 24 | import java.io.FileWriter; 25 | import java.io.IOException; 26 | import java.io.OutputStreamWriter; 27 | import java.io.PrintWriter; 28 | import java.io.UnsupportedEncodingException; 29 | import java.net.MalformedURLException; 30 | import javax.swing.SwingUtilities; 31 | import org.netbeans.api.project.Project; 32 | import org.netbeans.modules.csl.api.UiUtils; 33 | import org.openide.DialogDescriptor; 34 | import org.openide.DialogDisplayer; 35 | import org.openide.NotifyDescriptor; 36 | import org.openide.awt.ActionID; 37 | import org.openide.awt.ActionReference; 38 | import org.openide.awt.ActionReferences; 39 | import org.openide.awt.ActionRegistration; 40 | import org.openide.filesystems.FileObject; 41 | import org.openide.filesystems.FileUtil; 42 | import org.openide.util.Exceptions; 43 | import org.openide.util.NbBundle; 44 | import org.openide.util.NbBundle.Messages; 45 | 46 | @ActionID( 47 | category = "Versioning", 48 | id = "com.junichi11.netbeans.gitignoreio.ui.actions.GenerateGitIgnoreAction") 49 | @ActionRegistration( 50 | displayName = "#CTL_GenerateGitIgnoreAction") 51 | @ActionReferences({ 52 | @ActionReference(path = "Menu/File", position = 2550), 53 | @ActionReference(path = "Projects/Actions", position = 2550) 54 | }) 55 | @Messages("CTL_GenerateGitIgnoreAction=Generate gitignore file") 56 | public final class GenerateGitIgnoreAction implements ActionListener { 57 | 58 | private static final String GITIGNORE_NAME = ".gitignore"; // NOI18N 59 | private static final String UTF8 = "UTF-8"; // NOI18N 60 | private final Project context; 61 | private File gitignoreFile; 62 | 63 | public GenerateGitIgnoreAction(Project context) { 64 | this.context = context; 65 | } 66 | 67 | @NbBundle.Messages({ 68 | "GenerateGitignoreAction.new.file.error.message=File already exists.", 69 | "GenerateGitignoreAction.select.gitignore.list.message=Please select item from gitignore list." 70 | }) 71 | @Override 72 | public void actionPerformed(ActionEvent ev) { 73 | 74 | FileObject projectDirectory = context.getProjectDirectory(); 75 | gitignoreFile = new File(FileUtil.toFile(projectDirectory), GITIGNORE_NAME); 76 | final boolean isEnabled = gitignoreFile.exists(); 77 | final String projectDirectoryPath = FileUtil.toFile(projectDirectory).getAbsolutePath(); 78 | SwingUtilities.invokeLater(() -> { 79 | GitignoreListPanel panel = GitignoreListPanel.getDefault(); 80 | panel.setEnabledOverwrite(isEnabled); 81 | panel.setEnabledPostscript(isEnabled); 82 | panel.setFilePath(projectDirectoryPath); 83 | 84 | DialogDescriptor descriptor; 85 | try { 86 | descriptor = panel.showDialog(); 87 | if (descriptor.getValue() == DialogDescriptor.OK_OPTION) { 88 | // get content 89 | String gitignoreContent = panel.getGitignoreContent(); 90 | if (gitignoreContent == null) { 91 | String warning = Bundle.GenerateGitignoreAction_select_gitignore_list_message(); 92 | showDialog(warning); 93 | return; 94 | } 95 | if (!panel.getFilePath().equals(projectDirectoryPath)) { 96 | gitignoreFile = new File(new File(panel.getFilePath()), GITIGNORE_NAME); 97 | } 98 | 99 | // create file 100 | if (!createFile() && panel.isNormal()) { 101 | // show dialog 102 | String error = Bundle.GenerateGitignoreAction_new_file_error_message(); 103 | showDialog(error); 104 | } else { 105 | // write 106 | writeFile(panel, gitignoreContent); 107 | } 108 | 109 | // open file 110 | FileObject gitignore = FileUtil.toFileObject(gitignoreFile); 111 | if (gitignore != null) { 112 | UiUtils.open(gitignore, 0); 113 | } 114 | } 115 | } catch (MalformedURLException ex) { 116 | Exceptions.printStackTrace(ex); 117 | } catch (IOException ex) { 118 | showDialog(ex.getMessage()); 119 | } 120 | }); 121 | } 122 | 123 | private boolean createFile() throws IOException { 124 | return gitignoreFile.createNewFile(); 125 | } 126 | 127 | private void writeFile(GitignoreListPanel panel, String gitignoreContent) { 128 | if (!gitignoreFile.exists()) { 129 | return; 130 | } 131 | 132 | PrintWriter pw; 133 | try { 134 | if (panel.isNormal() || panel.isOverwrite()) { 135 | pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(gitignoreFile), UTF8), true); // NOI18N 136 | } else if (panel.isPostscript()) { 137 | pw = new PrintWriter(new FileWriter(gitignoreFile, true)); 138 | } else { 139 | return; 140 | } 141 | try { 142 | if (panel.isNormal() || panel.isOverwrite()) { 143 | pw.print(gitignoreContent); 144 | } else if (panel.isPostscript()) { 145 | // # Created by https://www.gitignore.io 146 | gitignoreContent = gitignoreContent.replace("# Created by https://www.gitignore.io\n", ""); // NOI18N 147 | pw.write(gitignoreContent); 148 | } 149 | } finally { 150 | pw.close(); 151 | } 152 | } catch (FileNotFoundException ex) { 153 | Exceptions.printStackTrace(ex); 154 | } catch (UnsupportedEncodingException ex) { 155 | Exceptions.printStackTrace(ex); 156 | } catch (IOException ex) { 157 | Exceptions.printStackTrace(ex); 158 | } 159 | } 160 | 161 | private void showDialog(final String error) { 162 | SwingUtilities.invokeLater(() -> { 163 | NotifyDescriptor.Message message = new NotifyDescriptor.Message(error, NotifyDescriptor.WARNING_MESSAGE); 164 | DialogDisplayer.getDefault().notify(message); 165 | }); 166 | } 167 | } 168 | --------------------------------------------------------------------------------