/* * Copyright (c) 2005 (Mike) Maurice Kienenberger (mkienenb@gmail.com) * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package org.gamenet.swing.controls; import java.awt.Component; import java.awt.FlowLayout; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.net.URL; import java.util.ArrayList; import java.util.List; import javax.swing.BoxLayout; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JLabel; import javax.swing.JPanel; import org.gamenet.util.SubTaskObserver; public class ComponentArrayPanel extends JPanel { // null task observer private SubTaskObserver taskObserver = new SubTaskObserver() { public void taskProgress(float percentageDone) { } }; private List componentList = null; private ComponentDataSource componentDataSource = null; private List componentControllerList = null; private ComponentArrayPanel thisComponentArrayPanel = this; public ComponentArrayPanel(SubTaskObserver taskObserver, List componentList, ComponentDataSource componentDataSource) throws InterruptedException { super(); this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); this.taskObserver = taskObserver; this.componentList = componentList; this.componentDataSource = componentDataSource; createComponentTable(); } public ComponentArrayPanel(List componentList, ComponentDataSource componentDataSource) throws InterruptedException { super(); this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); this.componentList = componentList; this.componentDataSource = componentDataSource; createComponentTable(); } private void createComponentTable() throws InterruptedException { componentControllerList = new ArrayList(); for (int componentIndex = 0; componentIndex < componentList.size(); componentIndex++) { Component component = (Component)componentList.get(componentIndex); addControlsForComponent(component, componentIndex); taskObserver.taskProgress((1f / componentList.size()) * componentIndex); if (Thread.currentThread().isInterrupted()) throw new InterruptedException("createComponentTable() was interrupted."); } // Add button at end int componentIndex = componentList.size(); final ComponentController componentController = new ComponentController(componentIndex); componentControllerList.add(componentIndex, componentController); JPanel componentPanel = new JPanel(new FlowLayout(FlowLayout.LEFT)); this.add(componentPanel, componentIndex); URL addImageURL = getClass().getResource("/toolbarButtonGraphics/general/Add16.gif"); JButton addButton = new JButton(new ImageIcon(addImageURL)); addButton.setMargin(new Insets(0,0,0,0)); componentPanel.add(addButton); componentController.setControls(null, addButton, null, null, null); final Runnable addRunnable = new Runnable() { public void run() { int componentIndex = componentController.getComponentIndex(); Component newComponent = componentDataSource.createComponent(componentIndex); if (null == newComponent) return; componentList.add(componentIndex, newComponent); thisComponentArrayPanel.addControlsForComponent(newComponent, componentIndex); refreshComponentControllers(); componentDataSource.fireComponentAdded(componentIndex, newComponent); } }; addButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { addRunnable.run(); } }); } private void addControlsForComponent(Component component, int componentIndex) { JPanel componentPanel = new JPanel(new FlowLayout(FlowLayout.LEFT)); this.add(componentPanel, componentIndex); final ComponentController componentController = new ComponentController(componentIndex); componentControllerList.add(componentIndex, componentController); JLabel idLabel = null; JButton addButton = null; JButton upButton = null; JButton downButton = null; JButton deleteButton = null; URL addImageURL = getClass().getResource("/toolbarButtonGraphics/general/Add16.gif"); addButton = new JButton(new ImageIcon(addImageURL)); addButton.setMargin(new Insets(0,0,0,0)); componentPanel.add(addButton); URL upImageURL = getClass().getResource("/toolbarButtonGraphics/navigation/Up16.gif"); upButton = new JButton(new ImageIcon(upImageURL)); upButton.setMargin(new Insets(0,0,0,0)); componentPanel.add(upButton); URL downImageURL = getClass().getResource("/toolbarButtonGraphics/navigation/Down16.gif"); downButton = new JButton(new ImageIcon(downImageURL)); downButton.setMargin(new Insets(0,0,0,0)); componentPanel.add(downButton); URL deleteImageURL = getClass().getResource("/toolbarButtonGraphics/general/Delete16.gif"); deleteButton = new JButton(new ImageIcon(deleteImageURL)); deleteButton.setMargin(new Insets(0,0,0,0)); componentPanel.add(deleteButton); idLabel = new JLabel("#" + String.valueOf(componentIndex) + " - "); componentController.setControls(idLabel, addButton, upButton, downButton, deleteButton); componentController.configureControls(); componentPanel.add(idLabel); final Runnable addRunnable = new Runnable() { public void run() { int componentIndex = componentController.getComponentIndex(); Component newComponent = componentDataSource.createComponent(componentIndex); if (null == newComponent) return; componentList.add(componentIndex, newComponent); thisComponentArrayPanel.addControlsForComponent(newComponent, componentIndex); refreshComponentControllers(); componentDataSource.fireComponentAdded(componentIndex, newComponent); } }; final Runnable deleteRunnable = new Runnable() { public void run() { int componentIndex = componentController.getComponentIndex(); Component component = (Component)componentList.remove(componentIndex); thisComponentArrayPanel.remove(componentIndex); componentControllerList.remove(componentIndex); refreshComponentControllers(); componentDataSource.fireComponentDeleted(componentIndex, component); } }; final Runnable upRunnable = new Runnable() { public void run() { int componentIndex = componentController.getComponentIndex(); Component component = (Component)componentList.remove(componentIndex); componentList.add(componentIndex - 1, component); Component componentControl = thisComponentArrayPanel.getComponent(componentIndex); thisComponentArrayPanel.remove(componentIndex); thisComponentArrayPanel.add(componentControl, componentIndex - 1); componentControllerList.remove(componentIndex); componentControllerList.add(componentIndex - 1, componentController); refreshComponentControllers(); componentDataSource.fireComponentMovedUp(componentIndex, component); } }; final Runnable downRunnable = new Runnable() { public void run() { int componentIndex = componentController.getComponentIndex(); Component component = (Component)componentList.remove(componentIndex); componentList.add(componentIndex + 1, component); Component componentControl = thisComponentArrayPanel.getComponent(componentIndex); thisComponentArrayPanel.remove(componentIndex); thisComponentArrayPanel.add(componentControl, componentIndex + 1); componentControllerList.remove(componentIndex); componentControllerList.add(componentIndex + 1, componentController); refreshComponentControllers(); componentDataSource.fireComponentMovedDown(componentIndex, component); } }; addButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { addRunnable.run(); } }); upButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { upRunnable.run(); } }); downButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { downRunnable.run(); } }); deleteButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { deleteRunnable.run(); } }); componentPanel.add(component); } private void refreshComponentControllers() { for (int componentIndex = 0; componentIndex < componentControllerList.size(); ++componentIndex) { ComponentController componentController = (ComponentController)componentControllerList.get(componentIndex); componentController.setComponentIndex(componentIndex); this.revalidate(); this.repaint(); } } public interface ComponentDataSource { public Component createComponent(int componentIndex); public void fireComponentAdded(int componentIndex, Component component); public void fireComponentDeleted(int componentIndex, Component component); public void fireComponentMovedUp(int componentIndex, Component component); public void fireComponentMovedDown(int componentIndex, Component component); } private class ComponentController { private JLabel idLabel = null; private JButton addButton = null; private JButton upButton = null; private JButton downButton = null; private JButton deleteButton = null; private int componentIndex = -1; public ComponentController(int componentIndex) { this.componentIndex = componentIndex; } public int getComponentIndex() { return this.componentIndex; } public void setComponentIndex(int componentIndex) { this.componentIndex = componentIndex; configureControls(); } public void setControls(JLabel idLabel, JButton addButton, JButton upButton, JButton downButton, JButton deleteButton) { this.addButton = addButton; this.upButton = upButton; this.downButton = downButton; this.deleteButton = deleteButton; this.idLabel = idLabel; } private static final int FIRST_EVENT_POSITION = 0; private static final int OTHER_EVENT_POSITION = 1; private static final int LAST_EVENT_POSITION = 2; private static final int FIRST_AND_LAST_EVENT_POSITION = 3; public void configureControls() { int componentPosition = OTHER_EVENT_POSITION; if (componentIndex == 0) componentPosition = FIRST_EVENT_POSITION; if (componentIndex == (componentList.size() - 1)) componentPosition = LAST_EVENT_POSITION; if ((componentIndex == 0) && (componentIndex == (componentList.size() - 1))) componentPosition = FIRST_AND_LAST_EVENT_POSITION; if (null != upButton) { if ((componentPosition != FIRST_EVENT_POSITION) && (componentPosition != FIRST_AND_LAST_EVENT_POSITION)) { upButton.setEnabled(true); } else { upButton.setEnabled(false); } } if (null != downButton) { if ((componentPosition != LAST_EVENT_POSITION) && (componentPosition != FIRST_AND_LAST_EVENT_POSITION)) { downButton.setEnabled(true); } else { downButton.setEnabled(false); } } if (null != idLabel) { idLabel.setText("#" + String.valueOf(componentIndex) + " - "); } } } }