/*
* Copyright 2010-2015 Institut Pasteur.
*
* This file is part of Icy.
*
* Icy is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Icy is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Icy. If not, see <http://www.gnu.org/licenses/>.
*/
package icy.gui.inspector;
import icy.gui.component.IcyTextField;
import icy.gui.component.IcyTextField.TextChangeListener;
import icy.main.Icy;
import icy.resource.ResourceUtil;
import icy.swimmingPool.SwimmingObject;
import icy.swimmingPool.SwimmingPool;
import icy.swimmingPool.SwimmingPoolEvent;
import icy.swimmingPool.SwimmingPoolListener;
import icy.system.thread.ThreadUtil;
import icy.util.StringUtil;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.DefaultComboBoxModel;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
/**
* @author Stephane
*/
public class SwimmingPoolPanel extends JPanel implements TextChangeListener, ListSelectionListener,
SwimmingPoolListener
{
/**
*
*/
private static final long serialVersionUID = 1565643301342039659L;
static final String[] columnNames = {"", "Name", "Type"};
final SwimmingPool swimmingPool;
ArrayList<SwimmingObject> objects;
final AbstractTableModel tableModel;
final JTable table;
final JComboBox objectType;
final JPanel objectTypePanel;
final IcyTextField nameFilter;
final JButton refreshButton;
final JButton deleteAllButton;
final JButton deleteButton;
public SwimmingPoolPanel(boolean showTypeFilter, boolean showNameFilter, boolean showButtons)
{
super();
swimmingPool = Icy.getMainInterface().getSwimmingPool();
if (swimmingPool != null)
swimmingPool.addListener(this);
objects = new ArrayList<SwimmingObject>();
// GUI
objectType = new JComboBox(new DefaultComboBoxModel());
objectType.setToolTipText("Select type to display");
objectType.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
if (objectType.getSelectedIndex() != -1)
{
refreshObjects();
refreshTableData();
}
}
});
objectTypePanel = new JPanel();
objectTypePanel.setLayout(new BoxLayout(objectTypePanel, BoxLayout.PAGE_AXIS));
objectTypePanel.setVisible(showTypeFilter);
final JPanel internalRepPanel = new JPanel();
internalRepPanel.setLayout(new BoxLayout(internalRepPanel, BoxLayout.LINE_AXIS));
internalRepPanel.add(new JLabel("Object type :"));
internalRepPanel.add(Box.createHorizontalStrut(8));
internalRepPanel.add(objectType);
internalRepPanel.add(Box.createHorizontalGlue());
objectTypePanel.add(internalRepPanel);
objectTypePanel.add(Box.createVerticalStrut(8));
// need filter before load()
nameFilter = new IcyTextField();
nameFilter.addTextChangeListener(this);
nameFilter.setVisible(showNameFilter);
// build buttons panel
refreshButton = new JButton("Refresh");
refreshButton.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
// refresh list
refreshObjectTypeList();
refreshObjects();
}
});
deleteAllButton = new JButton("Delete all");
deleteAllButton.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
// delete all objects
swimmingPool.removeAll();
}
});
deleteButton = new JButton("Delete");
deleteButton.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
// delete selected objects
for (SwimmingObject so : getSelectedObjects())
swimmingPool.remove(so);
}
});
final JPanel buttonsPanel = new JPanel();
buttonsPanel.setBorder(BorderFactory.createEmptyBorder(4, 8, 8, 8));
buttonsPanel.setLayout(new BoxLayout(buttonsPanel, BoxLayout.LINE_AXIS));
buttonsPanel.setVisible(showButtons);
buttonsPanel.add(refreshButton);
buttonsPanel.add(Box.createHorizontalStrut(64));
buttonsPanel.add(deleteAllButton);
buttonsPanel.add(Box.createHorizontalStrut(8));
buttonsPanel.add(deleteButton);
buttonsPanel.add(Box.createHorizontalGlue());
// build table
tableModel = new AbstractTableModel()
{
/**
*
*/
private static final long serialVersionUID = -8573364273165723214L;
@Override
public int getColumnCount()
{
return columnNames.length;
}
@Override
public String getColumnName(int column)
{
return columnNames[column];
}
@Override
public int getRowCount()
{
return objects.size();
}
@Override
public Object getValueAt(int row, int column)
{
final SwimmingObject so = objects.get(row);
switch (column)
{
case 0:
return ResourceUtil.scaleIcon(so.getIcon(), 24);
case 1:
return so.getName();
case 2:
return so.getObjectSimpleClassName();
}
return "";
}
@Override
public boolean isCellEditable(int row, int column)
{
return false;
}
@Override
public Class<?> getColumnClass(int columnIndex)
{
if (columnIndex == 0)
return ImageIcon.class;
return String.class;
}
};
table = new JTable(tableModel);
final TableColumnModel colModel = table.getColumnModel();
TableColumn col;
// columns setting
col = colModel.getColumn(0);
col.setPreferredWidth(32);
col.setMinWidth(32);
col.setResizable(false);
col = colModel.getColumn(1);
col.setPreferredWidth(100);
col.setMinWidth(60);
col = colModel.getColumn(2);
col.setPreferredWidth(80);
col.setMinWidth(40);
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
table.getSelectionModel().addListSelectionListener(this);
table.setRowHeight(24);
table.setColumnSelectionAllowed(false);
table.setRowSelectionAllowed(true);
table.setShowVerticalLines(false);
table.setAutoCreateRowSorter(true);
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
add(Box.createVerticalStrut(2));
if (showTypeFilter)
add(objectTypePanel);
if (showNameFilter)
add(nameFilter);
if (showTypeFilter || showNameFilter)
add(Box.createVerticalStrut(8));
add(table.getTableHeader());
add(new JScrollPane(table));
if (showButtons)
add(buttonsPanel);
validate();
refreshObjectTypeList();
refreshObjects();
}
public void setTypeFilter(String type)
{
objectType.setSelectedItem(type);
}
public void setNameFilter(String name)
{
nameFilter.setText(name);
}
protected void refreshObjects()
{
if (swimmingPool != null)
objects = filterList(swimmingPool.getObjects(), nameFilter.getText());
else
objects.clear();
}
protected int getObjectIndex(SwimmingObject object)
{
return objects.indexOf(object);
}
protected int getObjectModelIndex(SwimmingObject object)
{
return getObjectIndex(object);
}
protected int getObjectTableIndex(SwimmingObject object)
{
final int ind = getObjectModelIndex(object);
if (ind == -1)
return ind;
try
{
return table.convertRowIndexToView(ind);
}
catch (IndexOutOfBoundsException e)
{
return -1;
}
}
public ArrayList<SwimmingObject> getSelectedObjects()
{
final ArrayList<SwimmingObject> result = new ArrayList<SwimmingObject>();
for (int rowIndex : table.getSelectedRows())
{
int index = -1;
if (rowIndex != -1)
{
try
{
index = table.convertRowIndexToModel(rowIndex);
}
catch (IndexOutOfBoundsException e)
{
// ignore
}
}
if ((index >= 0) || (index < objects.size()))
result.add(objects.get(index));
}
return result;
}
public void setSelectedObjects(ArrayList<SwimmingObject> sos)
{
table.clearSelection();
for (SwimmingObject so : sos)
{
final int index = getObjectTableIndex(so);
if (index > -1)
table.getSelectionModel().setSelectionInterval(index, index);
}
}
protected void refreshObjectTypeList()
{
final DefaultComboBoxModel model = (DefaultComboBoxModel) objectType.getModel();
final Object savedItem = model.getSelectedItem();
model.removeAllElements();
model.addElement("ALL");
if (swimmingPool != null)
{
for (String type : SwimmingObject.getObjectTypes(swimmingPool.getObjects()))
model.addElement(type);
}
if (savedItem != null)
model.setSelectedItem(savedItem);
else
objectType.setSelectedIndex(0);
}
private ArrayList<SwimmingObject> filterList(ArrayList<SwimmingObject> list, String nameFilterText)
{
final ArrayList<SwimmingObject> result = new ArrayList<SwimmingObject>();
final boolean typeEmpty = objectType.getSelectedIndex() == 0;
final boolean nameEmpty = StringUtil.isEmpty(nameFilterText, true);
final String typeFilter;
final String nameFilterUp;
if (!typeEmpty)
typeFilter = objectType.getSelectedItem().toString();
else
typeFilter = "";
if (!nameEmpty)
nameFilterUp = nameFilterText.toUpperCase();
else
nameFilterUp = "";
for (SwimmingObject so : list)
{
// search in name and type
if ((typeEmpty || so.getObjectSimpleClassName().equals(typeFilter))
&& (nameEmpty || (so.getName().indexOf(nameFilterUp) != -1)))
result.add(so);
}
return result;
}
protected void refreshTableData()
{
ThreadUtil.invokeLater(new Runnable()
{
@Override
public void run()
{
final ArrayList<SwimmingObject> sos = getSelectedObjects();
tableModel.fireTableDataChanged();
// restore previous selected objects if possible
setSelectedObjects(sos);
}
});
}
protected void refreshButtonsPanel()
{
deleteButton.setEnabled(getSelectedObjects().size() > 0);
deleteAllButton.setEnabled(objects.size() > 0);
}
protected void pluginsChanged()
{
refreshObjects();
refreshTableData();
refreshButtonsPanel();
}
@Override
public void textChanged(IcyTextField source, boolean validate)
{
pluginsChanged();
}
@Override
public void valueChanged(ListSelectionEvent e)
{
refreshButtonsPanel();
// TODO : send event to notify selection change
}
@Override
public void swimmingPoolChangeEvent(SwimmingPoolEvent swimmingPoolEvent)
{
refreshObjectTypeList();
refreshObjects();
}
}