package gui.processing; import java.awt.Component; import java.awt.Dimension; import java.awt.Rectangle; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.AdjustmentEvent; import java.awt.event.AdjustmentListener; import java.util.ArrayList; import java.util.Iterator; import javax.swing.BorderFactory; import javax.swing.BoxLayout; import javax.swing.JPanel; import javax.swing.JScrollPane; /** * Scroll pane containing CommandComponents * * @author oi12mlw, oi12pjn * @see CommandComponent */ @SuppressWarnings("serial") public class CommandScrollPane extends JScrollPane { private static final int SCROLL_SPEED = 16; private JPanel componentPanel; private ArrayList<CommandComponent> commandList; /** * Constructs a new instance of a CommandScrollPane */ public CommandScrollPane() { super(VERTICAL_SCROLLBAR_AS_NEEDED, HORIZONTAL_SCROLLBAR_NEVER); commandList = new ArrayList<CommandComponent>(); componentPanel = new JPanel(); componentPanel.setLayout(new BoxLayout(componentPanel, BoxLayout.PAGE_AXIS)); this.getViewport().add(componentPanel); this.getVerticalScrollBar().setUnitIncrement(SCROLL_SPEED); this.setBorder(BorderFactory.createTitledBorder("Commands")); this.setPreferredSize(new Dimension(600, 1000)); setUpAutoScrollBehaviour(); } private void setUpAutoScrollBehaviour() { this.getVerticalScrollBar().addAdjustmentListener( new AdjustmentListener() { int prevMax = 0; public void adjustmentValueChanged(AdjustmentEvent e) { if (e.getAdjustable().getMaximum() != prevMax) { prevMax = e.getAdjustable().getMaximum(); e.getAdjustable().setValue(prevMax); } } }); } /** * Adds the CommandComponent to this scroll pane * * @param commandComponent * the CommandComponent */ public void addCommandComponent(CommandComponent commandComponent) { // if (containsCommand(commandComponent)) return; // Niklas says let them run however many of the same after eachother. componentPanel.add(commandComponent); commandList.add(commandComponent); // Scroll to visible Rectangle bounds = new Rectangle(0, commandComponent.getHeight() - 1, 1, 1); this.scrollRectToVisible(bounds); this.revalidate(); this.repaint(); commandComponent.addRemoveButtonListener(new RemoveButtonListener(commandComponent)); } // TODO: to be used? /** * Removes the given CommandComponent from this scroll pane * * @param commandComponent * the given CommandComponent */ public void removeCommand(CommandComponent commandComponent) { commandList.remove(commandComponent); this.componentPanel.remove(commandComponent); this.revalidate(); this.repaint(); } /** * Returns the list of ProcessCommands represented by the CommandComponents * in this scroll pane * * @return the list of ProcessCommands */ public ProcessCommand[] getCommandList() { ProcessCommand[] commands = new ProcessCommand[commandList.size()]; Iterator<CommandComponent> componentIterator = commandList.iterator(); for (int i = 0; componentIterator.hasNext(); i++) { CommandComponent currentComponent = componentIterator.next(); commands[i] = buildProcessCommand(currentComponent); } return commands; } private ProcessCommand buildProcessCommand(CommandComponent component) { String type = component.getCommandName(); ProcessParameters[] parameters = component.getProcessParameters(); ProcessCommand command = new ProcessCommand(type, parameters); return command; } /** * Removes all CommandComponents from this scroll pane */ public void empty() { this.componentPanel.removeAll(); commandList.clear(); componentPanel.revalidate(); componentPanel.repaint(); } private boolean containsCommand(CommandComponent commandComponent) { Component[] components = componentPanel.getComponents(); for (Component c : components) { if (!CommandComponent.class.isAssignableFrom(c.getClass())) continue; if (((CommandComponent) c).getCommandName().equals( commandComponent.getCommandName())) return true; } return false; } private class RemoveButtonListener implements ActionListener { private CommandComponent commandComponent; public RemoveButtonListener(CommandComponent commandComponent) { this.commandComponent = commandComponent; } @Override public void actionPerformed(ActionEvent e) { CommandScrollPane.this.removeCommand(commandComponent); } } }