diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..dfe0770 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Auto detect text files and perform LF normalization +* text=auto diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a1c2a23 --- /dev/null +++ b/.gitignore @@ -0,0 +1,23 @@ +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..a3191c5 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 Noah Ortega + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/NMSVRScreenshotFix.java b/NMSVRScreenshotFix.java new file mode 100644 index 0000000..264f2fd --- /dev/null +++ b/NMSVRScreenshotFix.java @@ -0,0 +1,287 @@ + +package nmsvrscreenshotfix; + +import java.io.IOException; +import java.io.File; +import java.awt.image.BufferedImage; +import javax.imageio.ImageIO; +import java.awt.Graphics2D; +import static java.lang.Character.isLetterOrDigit; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * Iterates through every image in the executable's folder and if applicable, + * creates a copy of it with an aspect ratio to 1:1 + * @author Noah Ortega + */ +public class NMSVRScreenshotFix { + + public static void main(String[] args) { + LogicController.getInstance(); + } +} + +class LogicController { + + public boolean isExecuting = false; + public boolean canceled = false; + + private int totalFiles; + private int converted; + private BufferedImage curImage; + + public String sourcePath; + public String resultPath; + + public boolean shouldRename = true; + public boolean renameNewFile = true; + public String addToFile = "_fix"; + public boolean addAsPrefix = false; + + ProgramUI myUI; + + //singleton + private static LogicController sharedController = null; + private LogicController() { + launchUI(); + sourcePath = System.getProperty("user.dir"); + resultPath = System.getProperty("user.dir"); + } + public static LogicController getInstance() { + if(sharedController == null) { + sharedController = new LogicController(); + } + return sharedController; + } + + + private void launchUI() { + /* Set the Nimbus look and feel */ + // + /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel. + * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html + */ + try { + for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) { + if ("Nimbus".equals(info.getName())) { + javax.swing.UIManager.setLookAndFeel(info.getClassName()); + break; + } + } + } catch (ClassNotFoundException ex) { + java.util.logging.Logger.getLogger(ProgramUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); + } catch (InstantiationException ex) { + java.util.logging.Logger.getLogger(ProgramUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); + } catch (IllegalAccessException ex) { + java.util.logging.Logger.getLogger(ProgramUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); + } catch (javax.swing.UnsupportedLookAndFeelException ex) { + java.util.logging.Logger.getLogger(ProgramUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); + } + // + // + // + // + + /* Create and display the form */ + java.awt.EventQueue.invokeLater(new Runnable() { + public void run() { + myUI = new ProgramUI(); + myUI.setVisible(true); + } + }); + } + + /** + * Iterates through the files in the directory, validates files before + * allowing resizing. + */ + public void execute() { + System.out.println("starting"); + isExecuting = true; + canceled = false; + myUI.updateProgressBar(0); + converted = 0; + + File sourceFolder = new File(sourcePath); //file of originals + File destFolder = new File(resultPath); //destination files + + File[] folderContents = sourceFolder.listFiles(); + totalFiles = folderContents.length; + File curFile; + + + for (int fileIndex = 0; fileIndex < totalFiles && !canceled; fileIndex++) { + curFile = folderContents[fileIndex]; + if (!folderContents[fileIndex].isDirectory() && isImage(curFile.getPath())) { + System.out.println(fileIndex); + //System.out.println(curFile.getPath()); + try { + curImage = ImageIO.read(folderContents[fileIndex]); + if (shouldResize(curImage.getWidth(), curImage.getHeight())) { + squish(curFile); + converted++; + } + } + catch (IOException ex) { + System.err.println(">> Caught IOException on '" + curFile.getPath() + "':\n " + ex.getMessage()); + } + } + myUI.updateProgressBar((fileIndex + 1)*100/totalFiles); + } + if(canceled) {myUI.cancelPopup(converted);} + else {myUI.successPopup(converted);} + + isExecuting = false; + System.out.println("finished"); + } + + /** + * Resizes an image to a 1:1 aspect ratio by changing the width + * @param originalFile Path of the original input image + * @throws java.io.IOException + * + * based on code by Nam Ha Minh from article "How to resize images in Java" + * https://www.codejava.net/java-se/graphics/how-to-resize-images-in-java + */ + private void squish(File originalFile) throws IOException { + int newWidth = curImage.getHeight(); + int height = curImage.getHeight(); + // creates output image + BufferedImage outputImage = new BufferedImage(newWidth, height, curImage.getType()); + + // scales the input image to the output image + Graphics2D g2d = outputImage.createGraphics(); + g2d.drawImage(curImage, 0, 0, newWidth, height, null); + g2d.dispose(); + + int fileDotIndex = originalFile.getName().lastIndexOf('.'); + String formatName = originalFile.getName().substring(fileDotIndex + 1); + + File newFile = new File(resultPath +"/"+ originalFile.getName()); + if(shouldRename) { + if (renameNewFile) { + newFile = modifyFilePath(resultPath,originalFile.getName()); + } + else { + originalFile.renameTo(modifyFilePath(sourcePath,originalFile.getName())); + } + } + // write to output file + ImageIO.write(outputImage, formatName, newFile); + + System.out.println(">> Converted"); + } + + public void cancelExecution() { + canceled = true; + } + + public String getCurrentBehavior() { + String behavior = ""; + if(!shouldRename && (sourcePath.equals(resultPath))) { + behavior += "• Replacing originals with converted screenshots"; + } + else { + behavior += "• Making copies of converted screenshots"; + } + + behavior +="\n"; + if(shouldRename) { + if(addAsPrefix) { + behavior += "• Adding prefix "; + } + else { + behavior += "• Adding suffix "; + } + behavior += "\""+addToFile+"\" to "; + if(renameNewFile) { + behavior += "converted image"; + } + else { + behavior += "original image"; + } + behavior += "\n"; + behavior += "• " + getExampleRename(); + } + return behavior; + } + + private String getRename(String oldName) { + int dotIndex = oldName.lastIndexOf('.'); + + String name = oldName.substring(0, dotIndex); + String ext = oldName.substring(dotIndex); + + return addAsPrefix ? (addToFile+name+ext) : (name+addToFile+ext); + } + + private String getExampleRename() { + String exampleName = renameNewFile ? "converted.png" : "original.png"; + return ("Ex: \"" + exampleName + "\" -> \"" + getRename(exampleName) +"\""); + } + + private File modifyFilePath(String parentPath, String fileName) { + return (new File(parentPath + "/" + getRename(fileName))); + } + + /** + * Determines if a file is a basic image type + * @param path file path of image + * @return true if extension is png jpg or jpeg + */ + private boolean isImage(String path) { + //extention of file, from file after final period + int dotIndex = path.lastIndexOf('.'); + String extension = (dotIndex == -1) ? "no extension" : path.substring(dotIndex + 1); + extension = extension.toLowerCase(); + return (extension.equals("png") || extension.equals("jpg") || extension.equals("jpeg")); + } + + /** + * Determines if an image should be resized based on criteria: + * - width must be greater than height + * @param width image width + * @param height image height + * @return true if image matches criteria + */ + private boolean shouldResize(int width, int height) { + if (width == height) { + System.out.println(">> Already 1:1 aspect ratio"); + return false; + } else if (width < height) { + System.out.println(">> Height is greater than width"); + return false; + } else { + return true; + } + } + + /** + * For generating the path of the output image + * @param inputPath Path of the original input image + * @param dotIndex the index of the dot in the input path + * @return the final output path + */ + public String generateOutputPath(String inputPath, int dotIndex) { + + return inputPath.substring(0, dotIndex) + addToFile + inputPath.substring(dotIndex); + } + + public boolean isValidAddition(String phrase) { + + for (int charIndex = 0; charIndex < phrase.length(); charIndex++) { + char curChar = phrase.charAt(charIndex); + if(!isLetterOrDigit(curChar)) { + if(curChar != '_' && curChar != '-') { + return false; + } + } + } + return true; + } + + public boolean hasValidDirectoryPaths() { + return((new File(sourcePath)).isDirectory() && (new File(resultPath)).isDirectory()); + } +} \ No newline at end of file diff --git a/ProgramUI.form b/ProgramUI.form new file mode 100644 index 0000000..d6418a2 --- /dev/null +++ b/ProgramUI.form @@ -0,0 +1,210 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/ProgramUI.java b/ProgramUI.java new file mode 100644 index 0000000..41ca483 --- /dev/null +++ b/ProgramUI.java @@ -0,0 +1,278 @@ + +package nmsvrscreenshotfix; + +import javax.swing.JFileChooser; +import javax.swing.JOptionPane; + + +public class ProgramUI extends javax.swing.JFrame { + + LogicController controller = LogicController.getInstance(); + + public ProgramUI() { + initComponents(); + resultFolderField.setText(controller.resultPath); + sourceFolderField.setText(controller.sourcePath); + behaviorTextArea.setText(controller.getCurrentBehavior()); + } + + /** + * 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() { + + jPanel3 = new javax.swing.JPanel(); + jLabel2 = new javax.swing.JLabel(); + jLabel1 = new javax.swing.JLabel(); + jLabel3 = new javax.swing.JLabel(); + sourceFolderField = new javax.swing.JTextField(); + sourceFolderButton = new javax.swing.JButton(); + resultFolderField = new javax.swing.JTextField(); + resultFolderButton = new javax.swing.JButton(); + jScrollPane2 = new javax.swing.JScrollPane(); + behaviorTextArea = new javax.swing.JTextArea(); + settingsButton = new javax.swing.JButton(); + executeButton = new javax.swing.JButton(); + progressBar = new javax.swing.JProgressBar(); + + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + setTitle("NMS VR Screenshot Fix"); + setResizable(false); + + jLabel2.setText("Source Folder:"); + + jLabel1.setText("Behavior:"); + jLabel1.setVerticalAlignment(javax.swing.SwingConstants.TOP); + + jLabel3.setText("Result Folder:"); + + sourceFolderField.setText("err"); + sourceFolderField.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + sourceFolderFieldActionPerformed(evt); + } + }); + + sourceFolderButton.setText("..."); + sourceFolderButton.setMaximumSize(new java.awt.Dimension(22, 22)); + sourceFolderButton.setMinimumSize(new java.awt.Dimension(22, 22)); + sourceFolderButton.setPreferredSize(new java.awt.Dimension(32, 32)); + sourceFolderButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + sourceFolderButtonActionPerformed(evt); + } + }); + + resultFolderField.setText("err"); + resultFolderField.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + resultFolderFieldActionPerformed(evt); + } + }); + + resultFolderButton.setText("..."); + resultFolderButton.setMaximumSize(new java.awt.Dimension(22, 22)); + resultFolderButton.setMinimumSize(new java.awt.Dimension(22, 22)); + resultFolderButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + resultFolderButtonActionPerformed(evt); + } + }); + + behaviorTextArea.setEditable(false); + behaviorTextArea.setColumns(20); + behaviorTextArea.setLineWrap(true); + behaviorTextArea.setRows(5); + behaviorTextArea.setText("• Make copies of converted screenshots\n• Add prefix \" new_\" to the new image\n• Ex: \"image.png\" -> \"new_image.png\"\n"); + jScrollPane2.setViewportView(behaviorTextArea); + + settingsButton.setText("Behavior Settings"); + settingsButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + settingsButtonActionPerformed(evt); + } + }); + + executeButton.setText("Execute"); + executeButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + executeButtonActionPerformed(evt); + } + }); + + javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3); + jPanel3.setLayout(jPanel3Layout); + jPanel3Layout.setHorizontalGroup( + jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel3Layout.createSequentialGroup() + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(executeButton) + .addComponent(jLabel3) + .addComponent(jLabel2) + .addComponent(jLabel1)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) + .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 318, Short.MAX_VALUE) + .addComponent(settingsButton) + .addComponent(sourceFolderField) + .addComponent(resultFolderField) + .addComponent(progressBar, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(sourceFolderButton, javax.swing.GroupLayout.PREFERRED_SIZE, 30, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(resultFolderButton, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 30, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(273, 273, 273)) + ); + jPanel3Layout.setVerticalGroup( + jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel3Layout.createSequentialGroup() + .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel3Layout.createSequentialGroup() + .addGap(23, 23, 23) + .addComponent(sourceFolderButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel3Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(sourceFolderField, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 32, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel2, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 32, javax.swing.GroupLayout.PREFERRED_SIZE)))) + .addGap(17, 17, 17) + .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(resultFolderButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(resultFolderField, javax.swing.GroupLayout.PREFERRED_SIZE, 32, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(settingsButton) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(progressBar, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(executeButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGap(12, 12, 12)) + ); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); + getContentPane().setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jPanel3, javax.swing.GroupLayout.PREFERRED_SIZE, 462, javax.swing.GroupLayout.PREFERRED_SIZE) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jPanel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + ); + + pack(); + }// //GEN-END:initComponents + + private void executeButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_executeButtonActionPerformed + if(controller.isExecuting) { + controller.cancelExecution(); + toggleUI(); + } + else { + controller.sourcePath = sourceFolderField.getText(); + controller.resultPath = resultFolderField.getText(); + if (controller.hasValidDirectoryPaths()) { + controller.execute(); + toggleUI(); + } + else { + JOptionPane.showMessageDialog(this, + "One of the paths appears to not be a valid folder","Error", + JOptionPane.WARNING_MESSAGE); + } + } + }//GEN-LAST:event_executeButtonActionPerformed + + private void toggleUI() { + boolean shouldEnable = !controller.isExecuting; + settingsButton.setEnabled(shouldEnable); + sourceFolderField.setEnabled(shouldEnable); + sourceFolderButton.setEnabled(shouldEnable); + resultFolderField.setEnabled(shouldEnable); + resultFolderButton.setEnabled(shouldEnable); + + if(controller.isExecuting) {executeButton.setText("cancel");} + else {executeButton.setText("execute");} + } + + private void settingsButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_settingsButtonActionPerformed + new SettingsUI(this,true).setVisible(true); + behaviorTextArea.setText(controller.getCurrentBehavior()); + }//GEN-LAST:event_settingsButtonActionPerformed + + private void sourceFolderButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_sourceFolderButtonActionPerformed + JFileChooser jfc = new JFileChooser(); + jfc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); + int optionCode = jfc.showSaveDialog(null); + + if (optionCode == JFileChooser.APPROVE_OPTION) { + controller.sourcePath = jfc.getSelectedFile().getAbsolutePath(); + sourceFolderField.setText(controller.sourcePath); + behaviorTextArea.setText(controller.getCurrentBehavior()); + } + }//GEN-LAST:event_sourceFolderButtonActionPerformed + + private void resultFolderButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_resultFolderButtonActionPerformed + JFileChooser jfc = new JFileChooser(); + jfc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); + int optionCode = jfc.showSaveDialog(null); + + if (optionCode == JFileChooser.APPROVE_OPTION) { + controller.resultPath = jfc.getSelectedFile().getAbsolutePath(); + resultFolderField.setText(controller.resultPath); + behaviorTextArea.setText(controller.getCurrentBehavior()); + } + }//GEN-LAST:event_resultFolderButtonActionPerformed + + private void sourceFolderFieldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_sourceFolderFieldActionPerformed + controller.sourcePath = sourceFolderField.getText(); + behaviorTextArea.setText(controller.getCurrentBehavior()); + }//GEN-LAST:event_sourceFolderFieldActionPerformed + + private void resultFolderFieldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_resultFolderFieldActionPerformed + controller.resultPath = resultFolderField.getText(); + behaviorTextArea.setText(controller.getCurrentBehavior()); + }//GEN-LAST:event_resultFolderFieldActionPerformed + + public void updateProgressBar(int value) { + progressBar.setValue(value); + } + + public void successPopup(int value) { + JOptionPane.showMessageDialog(this, + ("Converted " + value + " images successfully."),"Complete", + JOptionPane.INFORMATION_MESSAGE); + progressBar.setValue(0); + } + + public void cancelPopup(int value) { + JOptionPane.showMessageDialog(this, + "Converted " + value + " files before canceling.","Canceled", + JOptionPane.ERROR_MESSAGE); + } + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JTextArea behaviorTextArea; + private javax.swing.JButton executeButton; + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel2; + private javax.swing.JLabel jLabel3; + private javax.swing.JPanel jPanel3; + private javax.swing.JScrollPane jScrollPane2; + private javax.swing.JProgressBar progressBar; + private javax.swing.JButton resultFolderButton; + private javax.swing.JTextField resultFolderField; + private javax.swing.JButton settingsButton; + private javax.swing.JButton sourceFolderButton; + private javax.swing.JTextField sourceFolderField; + // End of variables declaration//GEN-END:variables +} diff --git a/README.md b/README.md new file mode 100644 index 0000000..1985832 --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# NMS-VR-Screenshot-Fix + By default, No Man's Sky VR takes screenshots that appear stretched. By changing their aspect ratio to 1:1 the shots look much more natural. To automate this solution, this program makes 1:1 aspect ratio copies of images. diff --git a/SettingsUI.form b/SettingsUI.form new file mode 100644 index 0000000..a6803d6 --- /dev/null +++ b/SettingsUI.form @@ -0,0 +1,267 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/SettingsUI.java b/SettingsUI.java new file mode 100644 index 0000000..1372f11 --- /dev/null +++ b/SettingsUI.java @@ -0,0 +1,327 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package nmsvrscreenshotfix; + +import java.awt.Component; +import javax.swing.JOptionPane; +import javax.swing.JPanel; + +/** + * + * @author midli + */ +public class SettingsUI extends javax.swing.JDialog { + + LogicController controller = LogicController.getInstance(); + + + public SettingsUI(java.awt.Frame parent, boolean modal) { + super(parent, modal); + initComponents(); + + if(controller.shouldRename) {renameButton.setSelected(true);} + else {dontRenameButton.setSelected(true);} + if(controller.renameNewFile) {renameNewButton.setSelected(true);} + else {renameOriginalButton.setSelected(true);} + addTextField.setText(controller.addToFile); + if(controller.addAsPrefix) {prefixButton.setSelected(true);} + else {suffixButton.setSelected(true);} + + if(dontRenameButton.isSelected()) {disableRenamePanel(newFileSettings);} + + } + + /** + * 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() { + + replaceOrCopyGroup = new javax.swing.ButtonGroup(); + renameWhichGroup = new javax.swing.ButtonGroup(); + prefixOrSuffix = new javax.swing.ButtonGroup(); + jPanel1 = new javax.swing.JPanel(); + dontRenameButton = new javax.swing.JRadioButton(); + renameButton = new javax.swing.JRadioButton(); + jLabel1 = new javax.swing.JLabel(); + jSeparator1 = new javax.swing.JSeparator(); + ConfirmButton = new javax.swing.JButton(); + newFileSettings = new javax.swing.JPanel(); + renameNewButton = new javax.swing.JRadioButton(); + renameOriginalButton = new javax.swing.JRadioButton(); + jLabel6 = new javax.swing.JLabel(); + jLabel7 = new javax.swing.JLabel(); + prefixButton = new javax.swing.JRadioButton(); + suffixButton = new javax.swing.JRadioButton(); + jLabel8 = new javax.swing.JLabel(); + addTextField = new javax.swing.JTextField(); + + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + setTitle("Settings"); + setModal(true); + setResizable(false); + + replaceOrCopyGroup.add(dontRenameButton); + dontRenameButton.setText("Keep Same Names"); + dontRenameButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + dontRenameButtonActionPerformed(evt); + } + }); + + replaceOrCopyGroup.add(renameButton); + renameButton.setText("Edit File Names"); + renameButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + renameButtonActionPerformed(evt); + } + }); + + jLabel1.setText("Rename files?"); + + ConfirmButton.setText("confirm"); + ConfirmButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + ConfirmButtonActionPerformed(evt); + } + }); + + renameWhichGroup.add(renameNewButton); + renameNewButton.setText("Converted File"); + renameNewButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + renameNewButtonActionPerformed(evt); + } + }); + + renameWhichGroup.add(renameOriginalButton); + renameOriginalButton.setText("Original File"); + renameOriginalButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + renameOriginalButtonActionPerformed(evt); + } + }); + + jLabel6.setText("Rename which file?"); + + jLabel7.setText("Add as a prefix or suffix?"); + + prefixOrSuffix.add(prefixButton); + prefixButton.setText("Add Prefix"); + prefixButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + prefixButtonActionPerformed(evt); + } + }); + + prefixOrSuffix.add(suffixButton); + suffixButton.setText("Add Suffix"); + suffixButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + suffixButtonActionPerformed(evt); + } + }); + + jLabel8.setText("Text to be added:"); + + addTextField.setText("_new"); + addTextField.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + addTextFieldActionPerformed(evt); + } + }); + + javax.swing.GroupLayout newFileSettingsLayout = new javax.swing.GroupLayout(newFileSettings); + newFileSettings.setLayout(newFileSettingsLayout); + newFileSettingsLayout.setHorizontalGroup( + newFileSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, newFileSettingsLayout.createSequentialGroup() + .addGroup(newFileSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel7) + .addComponent(jLabel8) + .addComponent(jLabel6) + .addComponent(renameOriginalButton) + .addComponent(prefixButton)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(newFileSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(renameNewButton) + .addComponent(suffixButton)) + .addGap(35, 35, 35)) + .addGroup(newFileSettingsLayout.createSequentialGroup() + .addContainerGap() + .addComponent(addTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 290, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(23, Short.MAX_VALUE)) + ); + newFileSettingsLayout.setVerticalGroup( + newFileSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, newFileSettingsLayout.createSequentialGroup() + .addContainerGap() + .addComponent(jLabel6) + .addGap(2, 2, 2) + .addGroup(newFileSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER) + .addComponent(renameOriginalButton) + .addComponent(renameNewButton)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jLabel8) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(addTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jLabel7) + .addGap(4, 4, 4) + .addGroup(newFileSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER) + .addComponent(prefixButton) + .addComponent(suffixButton)) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + + javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); + jPanel1.setLayout(jPanel1Layout); + jPanel1Layout.setHorizontalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addGap(27, 27, 27) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, 321, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGroup(jPanel1Layout.createSequentialGroup() + .addGap(6, 6, 6) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(jLabel1) + .addComponent(newFileSettings, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(dontRenameButton) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(renameButton) + .addGap(35, 35, 35)))))) + .addGroup(jPanel1Layout.createSequentialGroup() + .addGap(145, 145, 145) + .addComponent(ConfirmButton))) + .addContainerGap(20, Short.MAX_VALUE)) + ); + jPanel1Layout.setVerticalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup() + .addGap(20, 20, 20) + .addComponent(jLabel1) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(dontRenameButton) + .addComponent(renameButton)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(newFileSettings, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(ConfirmButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addContainerGap()) + ); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); + getContentPane().setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + ); + + pack(); + }// //GEN-END:initComponents + + private void dontRenameButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_dontRenameButtonActionPerformed + disableRenamePanel(newFileSettings); + controller.shouldRename = false; + }//GEN-LAST:event_dontRenameButtonActionPerformed + + private void renameButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_renameButtonActionPerformed + enableRenamePanel(newFileSettings); + controller.shouldRename = true; + }//GEN-LAST:event_renameButtonActionPerformed + + private void ConfirmButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ConfirmButtonActionPerformed + if (controller.isValidAddition(addTextField.getText())) { + controller.addToFile = addTextField.getText(); + this.setVisible(false); + } + else { + JOptionPane.showMessageDialog(this, + "Text can only contain alphanumeric characters, '_' and '-'.","Error", + JOptionPane.WARNING_MESSAGE); + } + }//GEN-LAST:event_ConfirmButtonActionPerformed + + private void renameNewButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_renameNewButtonActionPerformed + controller.renameNewFile = true; + }//GEN-LAST:event_renameNewButtonActionPerformed + + private void prefixButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_prefixButtonActionPerformed + controller.addAsPrefix = true; + }//GEN-LAST:event_prefixButtonActionPerformed + + private void addTextFieldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addTextFieldActionPerformed + // no action + }//GEN-LAST:event_addTextFieldActionPerformed + + private void renameOriginalButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_renameOriginalButtonActionPerformed + controller.renameNewFile = false; + }//GEN-LAST:event_renameOriginalButtonActionPerformed + + private void suffixButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_suffixButtonActionPerformed + controller.addAsPrefix = false; + }//GEN-LAST:event_suffixButtonActionPerformed + + private void disableRenamePanel(JPanel panel){ + panel.setEnabled(false); + Component[] components = panel.getComponents(); + + for (Component component : components) { + if (component instanceof JPanel) { + disableRenamePanel((JPanel) component); + } + component.setEnabled(false); + } + } + + private void enableRenamePanel(JPanel panel){ + panel.setEnabled(true); + Component[] components = panel.getComponents(); + + for (Component component : components) { + if (component instanceof JPanel) { + disableRenamePanel((JPanel) component); + } + component.setEnabled(true); + } + } + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton ConfirmButton; + private javax.swing.JTextField addTextField; + private javax.swing.JRadioButton dontRenameButton; + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel6; + private javax.swing.JLabel jLabel7; + private javax.swing.JLabel jLabel8; + private javax.swing.JPanel jPanel1; + private javax.swing.JSeparator jSeparator1; + private javax.swing.JPanel newFileSettings; + private javax.swing.JRadioButton prefixButton; + private javax.swing.ButtonGroup prefixOrSuffix; + private javax.swing.JRadioButton renameButton; + private javax.swing.JRadioButton renameNewButton; + private javax.swing.JRadioButton renameOriginalButton; + private javax.swing.ButtonGroup renameWhichGroup; + private javax.swing.ButtonGroup replaceOrCopyGroup; + private javax.swing.JRadioButton suffixButton; + // End of variables declaration//GEN-END:variables +}