package eu.bibl.cfide.ui.editor; import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.io.File; import java.net.URL; import java.util.Map; import javax.swing.JButton; import javax.swing.JFileChooser; import javax.swing.JLabel; import javax.swing.JMenuItem; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JPopupMenu; import javax.swing.SwingUtilities; import javax.swing.filechooser.FileNameExtensionFilter; import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; import org.fife.ui.rtextarea.RTextScrollPane; import eu.bibl.banalysis.storage.classes.ClassContainer; import eu.bibl.cfide.context.CFIDEContext; import eu.bibl.cfide.engine.launch.JarLauncher; import eu.bibl.cfide.ui.UISettings; public class EditorTextTab extends RTextScrollPane implements MouseListener, ActionListener { private static final long serialVersionUID = -9001184665877228717L; protected final CFIDEContext context; protected final String title; protected final JPopupMenu popupMenu; public EditorTextTab(String title, CFIDEContext context) { super(new RSyntaxTextArea()); this.title = title; this.context = context; ((RSyntaxTextArea) getTextArea()).setAntiAliasingEnabled(true); popupMenu = createPopupMenu(); // needs to be first createTabPanel(); } protected String lastMainClass = null; protected JPopupMenu createPopupMenu() { final EditorTabbedPane tabbedPane = context.editorTabbedPane; // Close menu popup JPopupMenu popupMenu = new JPopupMenu(); JMenuItem saveJarMenuItem = new JMenuItem("Save Jar"); saveJarMenuItem.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { JFileChooser fileChooser = new JFileChooser(); FileNameExtensionFilter filter = new FileNameExtensionFilter("Jar Files", "jar"); fileChooser.setFileFilter(filter); int returnValue = fileChooser.showSaveDialog(EditorTextTab.this); if (returnValue == JFileChooser.APPROVE_OPTION) { final File file = fileChooser.getSelectedFile(); tabbedPane.compileAndDump(context, file, false, null); } } }); JMenuItem saveJarRunMenuItem = new JMenuItem("Save & Run Jar"); saveJarRunMenuItem.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { try { JarLauncher.getInstance().poll(); } catch (Exception e1) { JOptionPane.showMessageDialog(null, e1.getMessage(), "Already running Jar", JOptionPane.ERROR_MESSAGE); return; } JFileChooser fileChooser = new JFileChooser(); FileNameExtensionFilter filter = new FileNameExtensionFilter("Jar Files", "jar"); fileChooser.setFileFilter(filter); int returnValue = fileChooser.showSaveDialog(EditorTextTab.this); if (returnValue == JFileChooser.APPROVE_OPTION) { final File file = fileChooser.getSelectedFile(); ClassContainer container = context.jarDownloader.getContents(); String mainClass = lastMainClass; if (mainClass == null) { urlFor: for (URL url : container.resources.keySet()) { Map<String, byte[]> res = container.resources.get(url); for (String name : res.keySet()) { if (name.equals("META-INF/MANIFEST.MF")) { String data = new String(res.get(name)); String[] lines = data.split("\n"); for (String line : lines) { String[] splits = line.split(":"); if (splits.length == 2) { String key = splits[0]; if (key.equals("Main-Class")) { String val = splits[1]; lastMainClass = mainClass = val.trim(); break urlFor; } } } } } } } if (mainClass == null) { mainClass = JOptionPane.showInputDialog(null, "No Main-Class", mainClass).trim(); lastMainClass = mainClass; if (mainClass == null) return; } tabbedPane.compileAndDump(context, file, true, mainClass); } } }); // Close this menu button JMenuItem closeMenuItem = new JMenuItem("Close"); closeMenuItem.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { tabbedPane.remove(EditorTextTab.this); } }); // Close others menu button JMenuItem closeOthers = new JMenuItem("Close Others"); closeOthers.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { for (EditorTextTab sp : tabbedPane.tabs.values()) { if (!EditorTextTab.this.equals(sp)) { remove(sp); } } } }); // Close all menu button JMenuItem closeAll = new JMenuItem("Close All"); closeAll.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { for (EditorTextTab sp : tabbedPane.tabs.values()) { tabbedPane.remove(sp); } } }); popupMenu.add(saveJarMenuItem); popupMenu.add(saveJarRunMenuItem); popupMenu.add(closeMenuItem); popupMenu.add(closeOthers); popupMenu.add(closeAll); return popupMenu; } protected int index; protected JPanel tabNamePanel; protected JLabel tabNameLabel; protected JButton tabCloseButton; protected void createTabPanel() { tabNamePanel = new JPanel(new BorderLayout(5, 2)); tabNamePanel.setOpaque(false); tabNamePanel.setFocusable(false); tabNameLabel = new JLabel(title); tabNameLabel.addMouseListener(this); tabCloseButton = new JButton(UISettings.CLOSE_BUTTON_ICON); tabCloseButton.setFocusable(false); tabCloseButton.setActionCommand("close"); tabCloseButton.addActionListener(this); tabCloseButton.setSize(UISettings.CLOSE_BUTTON_SIZE); tabCloseButton.setPreferredSize(UISettings.CLOSE_BUTTON_SIZE); tabNamePanel.setComponentPopupMenu(popupMenu); tabNamePanel.add(tabNameLabel, BorderLayout.WEST); tabNamePanel.add(tabCloseButton); } public void setupFinal() {// called from EditorTabbedPane.createTextTab // ISSUE #1: https://github.com/TheBiblMan/CFIDE/issues/1 EditorTabbedPane tabbedPane = context.editorTabbedPane; index = tabbedPane.getTabCount() - 1; tabbedPane.setTabComponentAt(index, tabNamePanel); } @Override public void mouseClicked(MouseEvent e) { } @Override public void mousePressed(MouseEvent e) { context.editorTabbedPane.setSelectedComponent(EditorTextTab.this); if (e.getButton() != MouseEvent.BUTTON1) { if (popupMenu.isShowing()) popupMenu.setVisible(false); popupMenu.show(tabNamePanel, e.getX(), e.getY()); } } @Override public void mouseReleased(MouseEvent e) { } @Override public void mouseEntered(MouseEvent e) { } @Override public void mouseExited(MouseEvent e) { } @Override public void actionPerformed(ActionEvent e) { String cmd = e.getActionCommand(); if (cmd.equals("close")) { context.editorTabbedPane.remove(EditorTextTab.this); } } public void setText(String text) { getTextArea().setText(text); SwingUtilities.invokeLater(RESET_VIEW_RUNNABLE); } protected ResetViewRunnable RESET_VIEW_RUNNABLE = new ResetViewRunnable(); // shared scrollpane scroller, technically not thread safe. protected class ResetViewRunnable implements Runnable { @Override public void run() { getHorizontalScrollBar().setValue(0); getVerticalScrollBar().setValue(0); } } }