/*
* Copyright (C) 2014 Alec Dhuse
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package co.foldingmap.GUISupport;
import co.foldingmap.Logger;
import co.foldingmap.map.DigitalMap;
import co.foldingmap.map.MapObject;
import co.foldingmap.map.MapObjectList;
import co.foldingmap.map.vector.VectorObject;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.JTableHeader;
/**
*
* @author Alec
*/
public class DataSheetPanel extends JPanel implements ActionListener,
ListSelectionListener,
MouseListener,
TableModelListener,
Updateable {
private ArrayList<String> fields;
private ArrayList<Updateable> updates;
private boolean updating;
private DefaultTableModel tableModel;
private DigitalMap mapData;
private int selectedColumnIndex;
private JMenuItem deleteColumn;
private JPopupMenu columnMenu;
private JScrollPane mainPane;
private DataTable table;
private JTableHeader tableHeader;
private MapObjectList<MapObject> objects;
public DataSheetPanel(DigitalMap mapData) {
this.mapData = mapData;
this.updates = new ArrayList<Updateable>();
this.updating = false;
init();
}
@Override
public void actionPerformed(ActionEvent ae) {
if (ae.getSource() == deleteColumn) {
deleteColumn();
}
}
public void addUpdateable(Updateable u) {
updates.add(u);
}
private void deleteColumn() {
String columnLabel;
VectorObject vectorObject;
if (selectedColumnIndex >= 0) {
columnLabel = tableModel.getColumnName(selectedColumnIndex);
for (MapObject object: objects) {
vectorObject = (VectorObject) object;
vectorObject.removeCustomDataField(columnLabel);
}
table.removeColumn(table.getColumnModel().getColumn(selectedColumnIndex));
}
}
private void init() {
try {
this.setLayout(new BorderLayout());
fields = mapData.getAllCustomDataFields();
objects = mapData.getAllMapObjects();
columnMenu = new JPopupMenu();
deleteColumn = new JMenuItem("Delete Column");
tableModel = new DefaultTableModel();
table = new DataTable(tableModel);
mainPane = new JScrollPane(table);
tableHeader = table.getTableHeader();
this.add(mainPane, BorderLayout.CENTER);
//Add Column Names
tableModel.addColumn("Name");
for (String field: fields)
tableModel.addColumn(field);
table.getSelectionModel().addListSelectionListener(this);
columnMenu.add(deleteColumn);
tableModel.addTableModelListener(this);
tableHeader.addMouseListener(this);
deleteColumn.addActionListener(this);
update();
} catch (Exception e) {
Logger.log(Logger.ERR, "Error in DataSheetPanel.init() - " + e);
}
}
@Override
public void mouseClicked(MouseEvent me) {
selectedColumnIndex = -1;
if (me.getButton() == 3) {
if (me.getSource() == tableHeader) {
selectedColumnIndex = tableHeader.columnAtPoint(me.getPoint());
columnMenu.show(this, me.getX(), me.getY());
}
}
}
@Override
public void mouseEntered(MouseEvent me) {
}
@Override
public void mouseExited(MouseEvent me) {
}
@Override
public void mousePressed(MouseEvent me) {
}
@Override
public void mouseReleased(MouseEvent me) {
}
@Override
public void setPreferredSize(Dimension d) {
mainPane.setPreferredSize(d);
mainPane.setMaximumSize(d);
this.setMaximumSize(d);
}
@Override
public void tableChanged(TableModelEvent tme) {
int editedRow, editedColumn;
VectorObject object;
if (!updating) {
editedRow = tme.getFirstRow();
editedColumn = tme.getColumn();
if (editedColumn > 0) {
object = (VectorObject) objects.get(editedRow);
object.setCustomDataField(fields.get(editedColumn - 1), (String) tableModel.getValueAt(editedRow, editedColumn));
}
}
}
@Override
public void update() {
try {
VectorObject object;
String newRow[] = new String[fields.size() + 1];
String field, value;
updating = true;
for (int row = 0; row < objects.size(); row++) {
object = (VectorObject) objects.get(row);
newRow[0] = object.getName();
for (int i = 0; i < fields.size(); i++) {
field = fields.get(i);
value = object.getCustomDataFieldValue(field);
if (object.getCustomDataFieldValue(field) != null) {
newRow[i+1] = value;
//tableModel.setValueAt(value, row, i);
} else {
newRow[i+1] = "";
//tableModel.setValueAt("", row, i);
}
}
tableModel.addRow(newRow);
}
tableModel.fireTableDataChanged();
table.validate();
updating = false;
} catch (Exception e) {
Logger.log(Logger.ERR, "DataSheetPanel.update() - " + e);
updating = false;
}
}
@Override
public void valueChanged(ListSelectionEvent lse) {
int selectedIndex;
VectorObject object;
mapData.deselectObjects();
selectedIndex = table.getSelectedRow();
object = (VectorObject) this.objects.get(selectedIndex);
mapData.setSelected(object);
for (Updateable u: updates)
u.update();
}
}