package ui.view; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.Font; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; import java.util.Arrays; import java.util.Scanner; import java.util.stream.Collectors; import javax.swing.JButton; import javax.swing.JFileChooser; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JTextArea; import javax.swing.JTextPane; import javax.swing.filechooser.FileNameExtensionFilter; import javax.swing.text.SimpleAttributeSet; import javax.swing.text.StyleConstants; import javax.swing.text.StyledDocument; import javax.tools.JavaCompiler; import javax.tools.ToolProvider; import api.AddOn; import ui.controller.Control; import utility.Util; @SuppressWarnings("serial") public class AddOnWindow extends JFrame{ private AddOn actual; private Control control; private JPanel content = new JPanel(); AddOnWindow(JFrame parentFrame, Control control){ this.control = control; this.setTitle("Add-Ons"); this.setVisible(true); this.setContentPane(content); this.setIconImage(Util.loadImage("/Images/Holeg.png", 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/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.newInstance(); if(!(object instanceof AddOn)) { generateErrorDialog("Class does not implement CpsAlgorithm!"); }else { actual = (AddOn)object; actual.setController(control); this.setContentPane(actual.getPanel()); this.pack(); } } 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()); } } /** * 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); } }