package holeg.ui.view.window; import holeg.api.AddOn; import holeg.preferences.ImagePreference; import holeg.ui.controller.Control; import holeg.ui.view.image.Import; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.Font; import java.io.File; import java.io.FileNotFoundException; import java.lang.reflect.InvocationTargetException; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; import java.util.Scanner; import javax.swing.JFileChooser; import javax.swing.JFrame; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JTextPane; import javax.swing.filechooser.FileNameExtensionFilter; import javax.swing.text.SimpleAttributeSet; import javax.swing.text.StyleConstants; import javax.tools.JavaCompiler; import javax.tools.ToolProvider; public class AddOnWindow extends JFrame { private AddOn actual; private Control control; private JPanel content = new JPanel(); public AddOnWindow(JFrame parentFrame, Control control) { this.control = control; this.setTitle("Add-Ons"); this.setVisible(true); this.setContentPane(content); this.setIconImage(Import.loadImage(ImagePreference.Logo, 30, 30)); initMenuBar(); initDefaultContentPanel(); this.pack(); this.setLocationRelativeTo(parentFrame); } private void initMenuBar() { JMenuBar menuBar = new JMenuBar(); JMenu menuSelect = new JMenu("File"); JMenuItem menuItemAlgorithm = new JMenuItem("Open .java-File.."); menuItemAlgorithm.addActionListener(actionEvent -> openJavaFile()); menuSelect.add(menuItemAlgorithm); JMenuItem menuItemFolder = new JMenuItem("Open Folder.."); menuItemFolder.addActionListener(actionEvent -> openFolder(menuSelect)); menuSelect.add(menuItemFolder); menuSelect.addSeparator(); JMenu menuHelp = new JMenu("Help"); menuBar.add(menuSelect); menuBar.add(menuHelp); this.setJMenuBar(menuBar); } private void initDefaultContentPanel() { content.setLayout(new BorderLayout()); JTextPane textPane = new JTextPane(); SimpleAttributeSet attribs = new SimpleAttributeSet(); StyleConstants.setAlignment(attribs, StyleConstants.ALIGN_JUSTIFIED); textPane.setParagraphAttributes(attribs, true); textPane.setText("No algorithm is loaded." + "\n OPTION[1]:" + "\n Select '.java'-file via the file browser. (File\u2192Open .jave-File..)" + "\n" + "\n OPTION[2]:" + "\n First select the folder where the addon '.java'-file is located. (File\u2192Open Folder..)" + "\n Second load the algorithm. (File\u2192'YourAlgo')"); textPane.setFont(new Font("Serif", Font.PLAIN, 16)); content.add(textPane, BorderLayout.CENTER); content.setPreferredSize(new Dimension(500, 500)); } /** * */ private void openJavaFile() { JFileChooser fileChooser = new JFileChooser(); fileChooser.setCurrentDirectory( new File(System.getProperty("user.dir") + "/src/holeg/algorithm/")); fileChooser.setFileFilter(new FileNameExtensionFilter("JAVA Source Files", "java")); fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY); fileChooser.setAcceptAllFileFilterUsed(false); int result = fileChooser.showOpenDialog(this); if (result == JFileChooser.APPROVE_OPTION) { //Found a file loadAlgorithm(fileChooser.getSelectedFile()); } } private void openFolder(JMenu menuSelect) { JFileChooser fileChooser = new JFileChooser(); fileChooser.setCurrentDirectory(new File(System.getProperty("user.dir") + "/src/")); fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); fileChooser.setAcceptAllFileFilterUsed(false); int result = fileChooser.showOpenDialog(this); if (result == JFileChooser.APPROVE_OPTION) { File[] files = fileChooser.getSelectedFile() .listFiles(file -> file.getName().endsWith(".java")); //Remove all Index from old Folder for (int i = menuSelect.getItemCount() - 1; i > 2; i--) { menuSelect.remove(i); } for (File file : files) { JMenuItem insertMenuItem = new JMenuItem(getNameWithoutExtension(file)); insertMenuItem.addActionListener(actionEvent -> loadAlgorithm(file)); menuSelect.add(insertMenuItem); } } } /** * Compile and load a java File. * * @param javafile */ private void loadAlgorithm(File javafile) { //Get Class name: String name = getNameWithoutExtension(javafile); //get Package name String packageName = ""; Scanner in = null; try { in = new Scanner(javafile); } catch (FileNotFoundException e) { generateErrorDialog("File not Found"); } while (in.hasNext()) { String line = in.nextLine().trim(); if (line.startsWith("package")) { packageName = line.substring(8, line.length() - 1); break; } } //GetPathName //String path = javafile.getParentFile().isDirectory() ? javafile.getParentFile().getAbsolutePath() : ""; File folder = javafile.getParentFile(); // Compile source file. JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); if (ToolProvider.getSystemJavaCompiler() == null) { generateErrorDialog("Please install the JDK on your system."); } else { compiler.run(null, null, null, javafile.getAbsolutePath()); } try { URLClassLoader classLoader = URLClassLoader.newInstance(new URL[]{folder.toURI().toURL()}); Class cls = Class.forName(packageName.isEmpty() ? name : packageName + "." + name, true, classLoader); Object object = cls.getDeclaredConstructor().newInstance(); if (object instanceof AddOn addon) { actual = addon; actual.setController(control); this.setContentPane(actual.getPanel()); this.pack(); } else { generateErrorDialog("Class does not implement CpsAlgorithm!"); } } catch (MalformedURLException e) { generateErrorDialog("URLClassLoader error"); } catch (ClassNotFoundException e) { generateErrorDialog("ClassNotFound error" + e.getMessage()); } catch (InstantiationException e) { generateErrorDialog("Class does not implement a Constructor." + e.getMessage()); } catch (IllegalAccessException e) { generateErrorDialog( "Class set this method privat or protected needs to be public." + e.getMessage()); } catch (IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException e) { e.printStackTrace(); } } /** * Returns the Name of a file without Extension. * * @param file * @return */ private String getNameWithoutExtension(File file) { return file.getName().substring(0, file.getName().lastIndexOf(".")); } /** * Generate a little Error Dialog to inform the User. * * @param message */ private void generateErrorDialog(String message) { System.out.println(message); JOptionPane.showConfirmDialog(this, message, "Error", JOptionPane.OK_OPTION, JOptionPane.ERROR_MESSAGE); } }