package jadex.tools.debugger;
import jadex.bridge.IComponentDescription;
import jadex.bridge.ICMSComponentListener;
import jadex.bridge.IComponentManagementService;
import jadex.commons.ChangeEvent;
import jadex.commons.IBreakpointPanel;
import jadex.commons.IChangeListener;
import jadex.commons.SGUI;
import jadex.commons.SUtil;
import jadex.commons.concurrent.SwingDefaultResultListener;
import jadex.commons.service.IServiceProvider;
import jadex.commons.service.SServiceProvider;
import jadex.rules.tools.common.TableSorter;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Insets;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import javax.swing.AbstractCellEditor;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JToggleButton;
import javax.swing.UIDefaults;
import javax.swing.UIManager;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableModel;
/**
* A panel for viewing the breakpoints.
*/
public class BreakpointPanel extends JPanel implements IBreakpointPanel
{
//-------- static part --------
/** The image icons. */
protected static UIDefaults icons = new UIDefaults(new Object[]
{
"breakpoint", SGUI.makeIcon(BreakpointPanel.class, "/jadex/rules/tools/reteviewer/images/lockoverlay.png"),
});
//-------- attributes --------
/** The breakpoints. */
protected List breakpoints;
/** The component description. */
protected IComponentDescription description;
/** The service container. */
protected IServiceProvider container;
/** The list. */
protected JTable list;
/** The listeners (if any). */
protected List listeners;
//-------- constructors --------
/**
* Create a new rulebase panel.
*/
public BreakpointPanel(Collection breakpoints, final IComponentDescription description, IServiceProvider container)
{
this.breakpoints = new ArrayList(breakpoints);
this.description = description;
this.container = container;
SServiceProvider.getServiceUpwards(container, IComponentManagementService.class).addResultListener(new SwingDefaultResultListener(BreakpointPanel.this)
{
public void customResultAvailable(Object source, Object result)
{
IComponentManagementService cms = (IComponentManagementService)result;
cms.addComponentListener(description.getName(), new ICMSComponentListener()
{
public void componentRemoved(IComponentDescription desc, Map results)
{
}
public void componentChanged(IComponentDescription desc)
{
BreakpointPanel.this.description = desc;
// Todo: update gui?
}
public void componentAdded(IComponentDescription desc)
{
}
});
TableModel lm = new AbstractTableModel()
{
public int getColumnCount()
{
return 2;
}
public int getRowCount()
{
return BreakpointPanel.this.breakpoints.size();
}
public Object getValueAt(int row, int column)
{
return column==1 ? BreakpointPanel.this.breakpoints.get(row) : null;
}
public boolean isCellEditable(int row, int column)
{
return column==0;
}
public Class getColumnClass(int column)
{
return column==0 ? JToggleButton.class : String.class;
}
};
list = new JTable(new TableSorter(lm));
TableSorter sorter = (TableSorter)list.getModel();
sorter.setTableHeader(list.getTableHeader());
setLayout(new BorderLayout());
JScrollPane sp = new JScrollPane(list);
add(sp, BorderLayout.CENTER);
// this.setBorder(BorderFactory.createTitledBorder("Rulebase"));
// Hack!!! Set header preferred size and afterwards set title text to "" (bug in JDK1.5).
list.getTableHeader().setPreferredSize(list.getTableHeader().getPreferredSize());
list.getColumnModel().getColumn(0).setHeaderRenderer(new DefaultTableCellRenderer()
{
public Component getTableCellRendererComponent(JTable table,
Object obj, boolean selected, boolean focus, int row, int column)
{
setIcon(icons.getIcon("breakpoint"));
setBorder(UIManager.getBorder("TableHeader.cellBorder"));
setHorizontalAlignment(JLabel.CENTER);
setToolTipText("Use checkbox to enable/disable breakpoint on a rule.");
return this;
}
});
list.getColumnModel().getColumn(1).setHeaderValue("Breakpoints");
list.setDefaultRenderer(JToggleButton.class, new ButtonCellManager(cms));
list.setDefaultEditor(JToggleButton.class, new ButtonCellManager(cms));
JCheckBox but = new JCheckBox();
but.setMargin(new Insets(0,0,0,0));
list.getColumnModel().getColumn(0).setMaxWidth(but.getPreferredSize().width+4);
list.getSelectionModel().addListSelectionListener(new ListSelectionListener()
{
public void valueChanged(ListSelectionEvent e)
{
if(!e.getValueIsAdjusting() && listeners!=null)
{
ChangeEvent ce = new ChangeEvent(this, EVENT_TYPE_SELECTED);
for(int i=0; i<listeners.size(); i++)
{
((IChangeListener)listeners.get(i)).changeOccurred(ce);
}
}
}
});
}
});
}
/**
* Dispose the panel
* and remove all listeners.
*/
public void dispose()
{
}
/**
* Get the currently selected breakpoints.
*/
public String[] getSelectedBreakpoints()
{
List selected = new ArrayList();
TableSorter sorter = (TableSorter)list.getModel();
for(int i=0; i<list.getRowCount(); i++)
{
if(list.isRowSelected(i))
selected.add(breakpoints.get(sorter.modelIndex(i)));
}
return (String[])selected.toArray(new String[selected.size()]);
}
/**
* Set the currently selected breakpoints.
*/
public void setSelectedBreakpoints(String[] breakpoints)
{
list.clearSelection();
for(int i=0; i<breakpoints.length; i++)
{
int index = this.breakpoints.indexOf(breakpoints[i]);
if(index!=-1)
list.getSelectionModel().addSelectionInterval(index, index);
}
}
/**
* Add a change listener to be notified of rule selection changes.
*/
public void addBreakpointListener(IChangeListener listener)
{
if(listeners==null)
listeners = new ArrayList();
listeners.add(listener);
}
/**
* Remove a change listener.
*/
public void removeBreakpointListener(IChangeListener listener)
{
listeners.remove(listener);
if(listeners.isEmpty())
listeners = null;
}
/**
* Table cell renderer / editor using add delete buttons.
*/
public class ButtonCellManager extends AbstractCellEditor implements TableCellRenderer, TableCellEditor
{
protected IComponentManagementService cms;
public ButtonCellManager(IComponentManagementService cms)
{
this.cms = cms;
}
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int rowIndex, int column)
{
TableSorter sorter = (TableSorter)list.getModel();
boolean selected = SUtil.arrayContains(description.getBreakpoints(), breakpoints.get(sorter.modelIndex(rowIndex)));
JPanel ret = new JPanel(new BorderLayout());
JCheckBox but = new JCheckBox((String)null, selected);
ret.add(but, BorderLayout.CENTER);
ret.setToolTipText("Enable/disable breakpoint.");
return ret;
}
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, final int rowIndex, int column)
{
final TableSorter sorter = (TableSorter)list.getModel();
boolean selected = SUtil.arrayContains(description.getBreakpoints(), breakpoints.get(sorter.modelIndex(rowIndex)));
JPanel ret = new JPanel(new BorderLayout());
final JCheckBox but = new JCheckBox((String)null, selected);
ret.add(but, BorderLayout.CENTER);
ret.setToolTipText("Enable/disable breakpoint.");
but.addActionListener(new ActionListener()
{
public void actionPerformed(java.awt.event.ActionEvent e)
{
List bps = new ArrayList(Arrays.asList(description.getBreakpoints()));
if(but.isSelected())
{
bps.add(breakpoints.get(sorter.modelIndex(rowIndex)));
}
else
{
bps.remove(breakpoints.get(sorter.modelIndex(rowIndex)));
}
cms.setComponentBreakpoints(description.getName(), (String[])bps.toArray(new String[bps.size()]));
}
});
return ret;
}
public Object getCellEditorValue()
{
return "";
}
}
}