package gui.processing; import gui.CustomButtonFactory; import java.awt.BorderLayout; import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.Stack; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.border.TitledBorder; import util.IconFactory; import net.miginfocom.swing.MigLayout; /** * * Abstract class representing a process command GUI component. A * CommandComponent has a number of CommandFileRows, where the user can specify * parameters such as in- and outfiles. * * @author oi12mlw, oi12pjn * @see CommandFileRow * */ @SuppressWarnings("serial") public abstract class CommandComponent extends JComponent { private static final int BUTTON_WIDTH = 20; private static final int BUTTON_HEIGHT = 20; public String commandName; private JButton removeButton; protected Stack<CommandFileRowPanel> commandFileRowPanelStack; /** * Constructs a new instance of a CommandComponent with the given command * name. * * @param commandName * the command name */ public CommandComponent(String commandName) { this.commandName = commandName; this.setBorder(new TitledBorder(commandName)); this.setLayout(new MigLayout()); commandFileRowPanelStack = new Stack<CommandFileRowPanel>(); } private void addRemoveButton() { removeButton = buildRemoveButton(); this.add(removeButton, "alignx right, wrap"); } private JButton buildRemoveButton() { ImageIcon icon = IconFactory.getClearIcon(BUTTON_WIDTH - 2 , BUTTON_HEIGHT - 2); ImageIcon hoverIcon = IconFactory.getClearIcon(BUTTON_WIDTH, BUTTON_HEIGHT); String tooltip = "Remove this command"; return CustomButtonFactory.makeCustomButton(icon, hoverIcon, BUTTON_WIDTH, 25, tooltip); } /** * Returns the command name * * @return the command name */ public String getCommandName() { return commandName; } /** * Adds the initial file row panel to the CommandComponent. This method * should be called in inheriting class constructor after super-constructor * call * */ protected void addInitialFileRowPanel() { CommandFileRow commandFileRow = buildCommandFileRow(); CommandFileRowPanel fileRowPanel = new CommandFileRowPanel( commandFileRow); fileRowPanel.addAddButtonActionListener(new AddFileRowButtonListener()); fileRowPanel .addRemoveButtonActionListener(new RemoveFileRowButtonListener()); fileRowPanel.setRemoveButtonEnabled(false); commandFileRowPanelStack.push(fileRowPanel); addRemoveButton(); this.add(fileRowPanel, "wrap"); } /** * Removes the given CommandFileRowPanel from this CommandComponent * * @param fileRowPanel * the given CommandFileRowPanel */ private void removeFileRowPanel(CommandFileRowPanel fileRowPanel) { CommandFileRowPanel topPanel = commandFileRowPanelStack.peek(); if (fileRowPanel.equals(topPanel)) { commandFileRowPanelStack.pop(); this.remove(fileRowPanel); CommandFileRowPanel newTopPanel = commandFileRowPanelStack.peek(); newTopPanel.setAddButtonEnabled(true); } else { commandFileRowPanelStack.remove(fileRowPanel); this.remove(fileRowPanel); } this.revalidate(); this.repaint(); } /** * Adds a new CommandFileRowPanel to the bottom of this CommandComponent */ private void addFileRowPanel() { CommandFileRow commandFileRow = buildCommandFileRow(); CommandFileRowPanel fileRowPanel = new CommandFileRowPanel( commandFileRow); fileRowPanel.addAddButtonActionListener(new AddFileRowButtonListener()); fileRowPanel .addRemoveButtonActionListener(new RemoveFileRowButtonListener()); CommandFileRowPanel topPanel = commandFileRowPanelStack.peek(); topPanel.setAddButtonEnabled(false); topPanel.revalidate(); topPanel.repaint(); commandFileRowPanelStack.push(fileRowPanel); this.add(fileRowPanel, "wrap"); } /** * Abstract method for building the correct CommandFileRow used by the * inheriting class * * @return the built CommandFileRow */ protected abstract CommandFileRow buildCommandFileRow(); /** * Returns the parameters put in by the user in the file rows contained by * this CommandComponent. * * @return the input parameters of the CommandComponent */ public abstract ProcessParameters[] getProcessParameters(); /** * * Button listener for removal of a file row panel * * @author oi12mlw, oi12pjn * @see CommandFileRowPanel */ private class RemoveFileRowButtonListener implements ActionListener { @Override public void actionPerformed(ActionEvent e) { JButton sourceButton = (JButton) e.getSource(); /* The parent of the parent of the button is the file row panel. */ CommandFileRowPanel parentPanel = (CommandFileRowPanel) sourceButton .getParent().getParent(); removeFileRowPanel(parentPanel); } } /** * Button listener for adding of file row panels * * @author oi12mlw, oi12pjn * */ private class AddFileRowButtonListener implements ActionListener { @Override public void actionPerformed(ActionEvent e) { addFileRowPanel(); } } public void addRemoveButtonListener(ActionListener removeButtonListener) { removeButton.addActionListener(removeButtonListener); } private class RemoveCommandComponentListener implements ActionListener { @Override public void actionPerformed(ActionEvent e) { JButton sourceButton = (JButton) e.getSource(); // TODO: Come up with better solution. /* The parent of the parent of the button is the file scroll panel. */ CommandScrollPane parentPanel = (CommandScrollPane) sourceButton .getParent().getParent().getParent().getParent().getParent(); parentPanel.removeCommand((CommandComponent) sourceButton .getParent().getParent()); } } }