/*
* FurnitureLibraryTable.java 18 d�c. 2009
*
* Furniture Library Editor, Copyright (c) 2009 Emmanuel PUYBARET / eTeks <info@eteks.com>
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package com.eteks.furniturelibraryeditor.swing;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Rectangle;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.math.BigDecimal;
import java.text.Collator;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Currency;
import java.util.List;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.TransferHandler;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableColumnModel;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
import javax.swing.table.TableModel;
import com.eteks.furniturelibraryeditor.model.FurnitureLibraryUserPreferences;
import com.eteks.furniturelibraryeditor.model.FurnitureLibrary;
import com.eteks.furniturelibraryeditor.viewcontroller.FurnitureLanguageController;
import com.eteks.furniturelibraryeditor.viewcontroller.FurnitureLibraryController;
import com.eteks.sweethome3d.model.CatalogPieceOfFurniture;
import com.eteks.sweethome3d.model.CollectionEvent;
import com.eteks.sweethome3d.model.CollectionListener;
import com.eteks.sweethome3d.model.Content;
import com.eteks.sweethome3d.model.SelectionEvent;
import com.eteks.sweethome3d.model.SelectionListener;
import com.eteks.sweethome3d.model.UserPreferences;
import com.eteks.sweethome3d.swing.IconManager;
import com.eteks.sweethome3d.tools.URLContent;
import com.eteks.sweethome3d.viewcontroller.View;
/**
* A table used to edit furniture library.
* @author Emmanuel Puybaret
*/
public class FurnitureLibraryTable extends JTable implements View {
private ListSelectionListener tableSelectionListener;
public FurnitureLibraryTable(FurnitureLibrary furnitureLibrary,
FurnitureLibraryUserPreferences preferences,
FurnitureLibraryController furnitureLibraryController,
FurnitureLanguageController furnitureLanguageController) {
super(new FurnitureLibraryTableModel(furnitureLibrary, furnitureLanguageController),
new FurnitureLibraryTableColumnModel(furnitureLibrary, preferences, furnitureLanguageController));
addTableHeaderListener();
setAutoResizeMode(AUTO_RESIZE_OFF);
updateTableColumnsWidth();
if (furnitureLibraryController != null) {
addSelectionListeners(furnitureLibraryController);
addMouseListener(furnitureLibraryController);
addFurnitureLanguageListener(furnitureLanguageController);
setTransferHandler(new TableTransferHandler(furnitureLibraryController));
}
addUserPreferencesListener(preferences);
}
/**
* Adds a listener to <code>preferences</code> to repaint this table
* and its header when unit changes.
*/
private void addUserPreferencesListener(UserPreferences preferences) {
preferences.addPropertyChangeListener(
UserPreferences.Property.UNIT, new UserPreferencesChangeListener(this));
}
/**
* Preferences property listener bound to this table with a weak reference to avoid
* strong link between user preferences and this table.
*/
private static class UserPreferencesChangeListener implements PropertyChangeListener {
private WeakReference<FurnitureLibraryTable> furnitureLibraryTable;
public UserPreferencesChangeListener(FurnitureLibraryTable furnitureTable) {
this.furnitureLibraryTable = new WeakReference<FurnitureLibraryTable>(furnitureTable);
}
public void propertyChange(PropertyChangeEvent ev) {
// If furniture table was garbage collected, remove this listener from preferences
FurnitureLibraryTable furnitureLibraryTable = this.furnitureLibraryTable.get();
if (furnitureLibraryTable == null) {
((UserPreferences)ev.getSource()).removePropertyChangeListener(
UserPreferences.Property.valueOf(ev.getPropertyName()), this);
} else {
furnitureLibraryTable.repaint();
furnitureLibraryTable.getTableHeader().repaint();
}
}
}
/**
* Adds selection listeners to this table.
*/
private void addSelectionListeners(final FurnitureLibraryController controller) {
final SelectionListener controllerSelectionListener = new SelectionListener() {
public void selectionChanged(SelectionEvent ev) {
setSelectedFurniture(controller.getSelectedFurniture());
}
};
this.tableSelectionListener = new ListSelectionListener () {
public void valueChanged(ListSelectionEvent ev) {
if (!ev.getValueIsAdjusting()) {
controller.removeSelectionListener(controllerSelectionListener);
int [] selectedRows = getSelectedRows();
// Build the list of selected furniture
List<CatalogPieceOfFurniture> selectedFurniture =
new ArrayList<CatalogPieceOfFurniture>(selectedRows.length);
TableModel tableModel = getModel();
for (int index : selectedRows) {
// Add to selectedFurniture table model value that stores piece
selectedFurniture.add((CatalogPieceOfFurniture)tableModel.getValueAt(index, 0));
}
// Set the new selection in controller
controller.setSelectedFurniture(selectedFurniture);
controller.addSelectionListener(controllerSelectionListener);
}
}
};
getSelectionModel().addListSelectionListener(this.tableSelectionListener);
controller.addSelectionListener(controllerSelectionListener);
}
/**
* Adds a double click mouse listener to modify selected furniture.
*/
private void addMouseListener(final FurnitureLibraryController controller) {
addMouseListener(new MouseAdapter () {
@Override
public void mouseClicked(MouseEvent ev) {
if (ev.getClickCount() == 2) {
controller.modifySelectedFurniture();
}
}
});
}
/**
* Adds a mouse listener on table header that will sort furniture.
*/
private void addTableHeaderListener() {
// Sort on click in column header
getTableHeader().addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent ev) {
FurnitureLibraryTableModel tableModel = (FurnitureLibraryTableModel)getModel();
List<CatalogPieceOfFurniture> selectedFurniture = new ArrayList<CatalogPieceOfFurniture>();
for (int index : getSelectedRows()) {
selectedFurniture.add((CatalogPieceOfFurniture)tableModel.getValueAt(index, 0));
}
int columnIndex = getTableHeader().columnAtPoint(ev.getPoint());
Object columnIdentifier = getColumnModel().getColumn(columnIndex).getIdentifier();
if (columnIdentifier instanceof String) {
String propertyKey = (String)columnIdentifier;
if (columnIdentifier.equals(tableModel.getSortProperty())) {
if (tableModel.isDescendingOrder()) {
tableModel.setSortProperty(null);
} else {
tableModel.setDescendingOrder(true);
}
} else if (tableModel.getFurnitureComparator(propertyKey) != null) {
tableModel.setSortProperty(propertyKey);
tableModel.setDescendingOrder(false);
}
}
getTableHeader().repaint();
setSelectedFurniture(selectedFurniture);
}
});
}
/**
* Selects furniture in table.
*/
private void setSelectedFurniture(List<CatalogPieceOfFurniture> selectedFurniture) {
getSelectionModel().removeListSelectionListener(this.tableSelectionListener);
clearSelection();
FurnitureLibraryTableModel tableModel = (FurnitureLibraryTableModel)getModel();
int minIndex = Integer.MAX_VALUE;
int maxIndex = Integer.MIN_VALUE;
for (CatalogPieceOfFurniture piece : selectedFurniture) {
if (piece instanceof CatalogPieceOfFurniture) {
// Search index of piece in sorted table model
int index = tableModel.getPieceOfFurnitureIndex((CatalogPieceOfFurniture)piece);
// If the piece was found (during the addition of a piece to library, the model may not be updated yet)
if (index != -1) {
addRowSelectionInterval(index, index);
minIndex = Math.min(minIndex, index);
maxIndex = Math.max(maxIndex, index);
}
}
}
if (minIndex != Integer.MIN_VALUE) {
makeRowsVisible(minIndex, maxIndex);
}
getSelectionModel().addListSelectionListener(this.tableSelectionListener);
}
/**
* Ensures the rectangle which displays rows from <code>minIndex</code> to <code>maxIndex</code> is visible.
*/
private void makeRowsVisible(int minRow, int maxRow) {
// Compute the rectangle that includes a row
Rectangle includingRectangle = getCellRect(minRow, 0, true);
if (minRow != maxRow) {
includingRectangle = includingRectangle.
union(getCellRect(maxRow, 0, true));
}
if (getAutoResizeMode() == AUTO_RESIZE_OFF) {
int lastColumn = getColumnCount() - 1;
includingRectangle = includingRectangle.
union(getCellRect(minRow, lastColumn, true));
if (minRow != maxRow) {
includingRectangle = includingRectangle.
union(getCellRect(maxRow, lastColumn, true));
}
}
scrollRectToVisible(includingRectangle);
}
/**
* Adds a listener on furniture language change to resort furniture.
*/
private void addFurnitureLanguageListener(FurnitureLanguageController controller) {
controller.addPropertyChangeListener(FurnitureLanguageController.Property.FURNITURE_LANGUAGE,
new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent ev) {
FurnitureLibraryTableModel tableModel = (FurnitureLibraryTableModel)getModel();
List<CatalogPieceOfFurniture> selectedFurniture = new ArrayList<CatalogPieceOfFurniture>();
for (int index : getSelectedRows()) {
selectedFurniture.add((CatalogPieceOfFurniture)tableModel.getValueAt(index, 0));
}
tableModel.sortFurniture();
setSelectedFurniture(selectedFurniture);
}
});
}
/**
* Updates table columns width from the content of its cells.
*/
private void updateTableColumnsWidth() {
int intercellWidth = getIntercellSpacing().width;
TableColumnModel columnModel = getColumnModel();
TableModel tableModel = getModel();
for (int columnIndex = 0, n = columnModel.getColumnCount(); columnIndex < n; columnIndex++) {
TableColumn column = columnModel.getColumn(columnIndex);
int modelColumnIndex = convertColumnIndexToModel(columnIndex);
int preferredWidth = column.getPreferredWidth();
preferredWidth = Math.max(preferredWidth, column.getHeaderRenderer().getTableCellRendererComponent(
this, column.getHeaderValue(), false, false, -1, columnIndex).getPreferredSize().width);
for (int rowIndex = 0, m = tableModel.getRowCount(); rowIndex < m; rowIndex++) {
preferredWidth = Math.max(preferredWidth,
column.getCellRenderer().getTableCellRendererComponent(
this, tableModel.getValueAt(rowIndex, modelColumnIndex), false, false, -1, columnIndex).
getPreferredSize().width);
}
column.setPreferredWidth(preferredWidth + intercellWidth);
column.setWidth(preferredWidth + intercellWidth);
}
}
/**
* Returns a tooltip for furniture pieces described in this table.
*/
@Override
public String getToolTipText(MouseEvent ev) {
int column = columnAtPoint(ev.getPoint());
if (column != -1
&& FurnitureLibrary.FURNITURE_ICON_PROPERTY.equals(getColumnModel().getColumn(column).getIdentifier())) {
int row = rowAtPoint(ev.getPoint());
if (row != -1) {
CatalogPieceOfFurniture piece = (CatalogPieceOfFurniture)getModel().getValueAt(row, 0);
if (piece.getIcon() instanceof URLContent) {
String tooltip = "<html><center><img width='128' height='128' src='"
+ ((URLContent)piece.getIcon()).getURL() + "'>";
return tooltip;
}
}
}
return null;
}
@Override
public Dimension getPreferredScrollableViewportSize() {
return new Dimension(getPreferredSize().width, 400);
}
/**
* Model used by furniture table.
*/
private static class FurnitureLibraryTableModel extends AbstractTableModel {
private final FurnitureLibrary furnitureLibrary;
private final FurnitureLanguageController controller;
private List<CatalogPieceOfFurniture> sortedFurniture;
private String sortProperty;
private boolean descendingOrder;
public FurnitureLibraryTableModel(FurnitureLibrary furnitureLibrary,
FurnitureLanguageController controller) {
this.furnitureLibrary = furnitureLibrary;
this.controller = controller;
addFurnitureLibraryListener(furnitureLibrary);
sortFurniture();
}
private void addFurnitureLibraryListener(final FurnitureLibrary furnitureLibrary) {
furnitureLibrary.addListener(new CollectionListener<CatalogPieceOfFurniture>() {
public void collectionChanged(CollectionEvent<CatalogPieceOfFurniture> ev) {
CatalogPieceOfFurniture piece = ev.getItem();
int pieceIndex = ev.getIndex();
switch (ev.getType()) {
case ADD :
int insertionIndex = getPieceOfFurnitureInsertionIndex(piece, furnitureLibrary, pieceIndex);
if (insertionIndex != -1) {
sortedFurniture.add(insertionIndex, piece);
fireTableRowsInserted(insertionIndex, insertionIndex);
}
break;
case DELETE :
int deletionIndex = getPieceOfFurnitureDeletionIndex(piece, furnitureLibrary, pieceIndex);
if (deletionIndex != -1) {
sortedFurniture.remove(deletionIndex);
fireTableRowsDeleted(deletionIndex, deletionIndex);
}
break;
}
}
/**
* Returns the index of an added <code>piece</code> in furniture table, with a default index
* of <code>pieceIndex</code> if furniture library isn't sorted.
* If <code>piece</code> isn't added to furniture table, the returned value is
* equals to the insertion index where piece should be added.
*/
private int getPieceOfFurnitureInsertionIndex(CatalogPieceOfFurniture piece,
FurnitureLibrary furnitureLibrary,
int pieceIndex) {
if (sortProperty == null) {
return pieceIndex;
}
// Default case when piece is included and furniture is sorted
int sortedIndex = Collections.binarySearch(sortedFurniture, piece, getFurnitureComparator(sortProperty));
if (sortedIndex >= 0) {
return sortedIndex;
} else {
return -(sortedIndex + 1);
}
}
/**
* Returns the index of an existing <code>piece</code> in furniture table, with a default index
* of <code>pieceIndex</code> if furniture isn't sorted.
*/
private int getPieceOfFurnitureDeletionIndex(CatalogPieceOfFurniture piece,
FurnitureLibrary furnitureLibrary,
int pieceIndex) {
if (sortProperty == null) {
return pieceIndex;
}
return getPieceOfFurnitureIndex(piece);
}
});
}
@Override
public String getColumnName(int columnIndex) {
// Column name is set by TableColumn instances themselves
return null;
}
public int getColumnCount() {
// Column count is set by TableColumnModel itself
return 0;
}
public int getRowCount() {
return this.sortedFurniture.size();
}
public Object getValueAt(int rowIndex, int columnIndex) {
// Always return piece itself, the real property displayed at screen is chosen by renderer
return this.sortedFurniture.get(rowIndex);
}
/**
* Returns the index of <code>piece</code> in furniture table, or -1.
*/
public int getPieceOfFurnitureIndex(CatalogPieceOfFurniture searchedPiece) {
for (int i = 0, n = this.sortedFurniture.size(); i < n; i++) {
CatalogPieceOfFurniture piece = this.sortedFurniture.get(i);
if (searchedPiece == piece) {
return i;
}
}
return -1;
}
/**
* Sorts furniture.
*/
public void sortFurniture() {
int previousRowCount = this.sortedFurniture != null
? this.sortedFurniture.size()
: 0;
List<CatalogPieceOfFurniture> libraryFurniture = this.furnitureLibrary.getFurniture();
this.sortedFurniture = new ArrayList<CatalogPieceOfFurniture>(libraryFurniture);
// Sort it if necessary
if (this.sortProperty != null) {
Comparator<CatalogPieceOfFurniture> furnitureComparator = getFurnitureComparator(this.sortProperty);
Collections.sort(this.sortedFurniture, furnitureComparator);
}
if (previousRowCount != this.sortedFurniture.size()) {
fireTableDataChanged();
} else {
fireTableRowsUpdated(0, getRowCount() - 1);
}
}
public Comparator<CatalogPieceOfFurniture> getFurnitureComparator(final String propertyKey) {
final Collator collator = Collator.getInstance();
Comparator<CatalogPieceOfFurniture> furnitureComparator = null;
if (FurnitureLibrary.FURNITURE_ID_PROPERTY.equals(propertyKey)) {
furnitureComparator = new Comparator<CatalogPieceOfFurniture>() {
public int compare(CatalogPieceOfFurniture piece1, CatalogPieceOfFurniture piece2) {
if (piece1.getId() == null) {
return -1;
} else if (piece2.getId() == null) {
return 1;
} else {
return collator.compare(piece1.getId(), piece2.getId());
}
}
};
} else if (FurnitureLibrary.FURNITURE_NAME_PROPERTY.equals(propertyKey)) {
furnitureComparator = new Comparator<CatalogPieceOfFurniture>() {
public int compare(CatalogPieceOfFurniture piece1, CatalogPieceOfFurniture piece2) {
String piece1Name = (String)furnitureLibrary.getPieceOfFurnitureLocalizedData(
piece1, controller.getFurnitureLangauge(), propertyKey, piece1.getName());
String piece2Name = (String)furnitureLibrary.getPieceOfFurnitureLocalizedData(
piece2, controller.getFurnitureLangauge(), propertyKey, piece2.getName());
return collator.compare(piece1Name, piece2Name);
}
};
} else if (FurnitureLibrary.FURNITURE_DESCRIPTION_PROPERTY.equals(propertyKey)) {
furnitureComparator = new Comparator<CatalogPieceOfFurniture>() {
public int compare(CatalogPieceOfFurniture piece1, CatalogPieceOfFurniture piece2) {
String piece1Description = (String)furnitureLibrary.getPieceOfFurnitureLocalizedData(
piece1, controller.getFurnitureLangauge(), propertyKey, piece1.getDescription());
if (piece1Description == null) {
return -1;
} else {
String piece2Description = (String)furnitureLibrary.getPieceOfFurnitureLocalizedData(
piece2, controller.getFurnitureLangauge(), propertyKey, piece2.getDescription());
if (piece2Description == null) {
return 1;
} else {
return collator.compare(piece1Description, piece2Description);
}
}
}
};
} else if (FurnitureLibrary.FURNITURE_CREATOR_PROPERTY.equals(propertyKey)) {
furnitureComparator = new Comparator<CatalogPieceOfFurniture>() {
public int compare(CatalogPieceOfFurniture piece1, CatalogPieceOfFurniture piece2) {
return collator.compare(piece1.getCreator(), piece2.getCreator());
}
};
} else if (FurnitureLibrary.FURNITURE_CATEGORY_PROPERTY.equals(propertyKey)) {
furnitureComparator = new Comparator<CatalogPieceOfFurniture>() {
public int compare(CatalogPieceOfFurniture piece1, CatalogPieceOfFurniture piece2) {
String piece1Category = (String)furnitureLibrary.getPieceOfFurnitureLocalizedData(
piece1, controller.getFurnitureLangauge(), propertyKey, piece1.getCategory().getName());
String piece2Category = (String)furnitureLibrary.getPieceOfFurnitureLocalizedData(
piece2, controller.getFurnitureLangauge(), propertyKey, piece2.getCategory().getName());
return collator.compare(piece1Category, piece2Category);
}
};
} else if (FurnitureLibrary.FURNITURE_PRICE_PROPERTY.equals(propertyKey)) {
furnitureComparator = new Comparator<CatalogPieceOfFurniture>() {
public int compare(CatalogPieceOfFurniture piece1, CatalogPieceOfFurniture piece2) {
if (piece1.getPrice() == null) {
return -1;
} else if (piece2.getPrice() == null) {
return 1;
} else {
return piece1.getPrice().compareTo(piece2.getPrice());
}
}
};
} else if (FurnitureLibrary.FURNITURE_VALUE_ADDED_TAX_PERCENTAGE_PROPERTY.equals(propertyKey)) {
furnitureComparator = new Comparator<CatalogPieceOfFurniture>() {
public int compare(CatalogPieceOfFurniture piece1, CatalogPieceOfFurniture piece2) {
if (piece1.getValueAddedTaxPercentage() == null) {
return -1;
} else if (piece2.getValueAddedTaxPercentage() == null) {
return 1;
} else {
return piece1.getValueAddedTaxPercentage().compareTo(piece2.getValueAddedTaxPercentage());
}
}
};
} else if (FurnitureLibrary.FURNITURE_WIDTH_PROPERTY.equals(propertyKey)) {
furnitureComparator = new Comparator<CatalogPieceOfFurniture>() {
public int compare(CatalogPieceOfFurniture piece1, CatalogPieceOfFurniture piece2) {
return piece1.getWidth() < piece2.getWidth()
? -1
: (piece1.getWidth() == piece2.getWidth()
? 0 : 1);
}
};
} else if (FurnitureLibrary.FURNITURE_DEPTH_PROPERTY.equals(propertyKey)) {
furnitureComparator = new Comparator<CatalogPieceOfFurniture>() {
public int compare(CatalogPieceOfFurniture piece1, CatalogPieceOfFurniture piece2) {
return piece1.getDepth() < piece2.getDepth()
? -1
: (piece1.getDepth() == piece2.getDepth()
? 0 : 1);
}
};
} else if (FurnitureLibrary.FURNITURE_HEIGHT_PROPERTY.equals(propertyKey)) {
furnitureComparator = new Comparator<CatalogPieceOfFurniture>() {
public int compare(CatalogPieceOfFurniture piece1, CatalogPieceOfFurniture piece2) {
return piece1.getHeight() < piece2.getHeight()
? -1
: (piece1.getHeight() == piece2.getHeight()
? 0 : 1);
}
};
} else if (FurnitureLibrary.FURNITURE_MOVABLE_PROPERTY.equals(propertyKey)) {
furnitureComparator = new Comparator<CatalogPieceOfFurniture>() {
public int compare(CatalogPieceOfFurniture piece1, CatalogPieceOfFurniture piece2) {
return piece1.isMovable() == piece2.isMovable()
? 0
: (piece1.isMovable()
? -1 : 1);
}
};
} else if (FurnitureLibrary.FURNITURE_DOOR_OR_WINDOW_PROPERTY.equals(propertyKey)) {
furnitureComparator = new Comparator<CatalogPieceOfFurniture>() {
public int compare(CatalogPieceOfFurniture piece1, CatalogPieceOfFurniture piece2) {
return piece1.isDoorOrWindow() == piece2.isDoorOrWindow()
? 0
: (piece1.isDoorOrWindow()
? -1 : 1);
}
};
} else if (FurnitureLibrary.FURNITURE_ELEVATION_PROPERTY.equals(propertyKey)) {
furnitureComparator = new Comparator<CatalogPieceOfFurniture>() {
public int compare(CatalogPieceOfFurniture piece1, CatalogPieceOfFurniture piece2) {
return piece1.getElevation() < piece2.getElevation()
? -1
: (piece1.getElevation() == piece2.getElevation()
? 0 : 1);
}
};
} else if (FurnitureLibrary.FURNITURE_RESIZABLE_PROPERTY.equals(propertyKey)) {
furnitureComparator = new Comparator<CatalogPieceOfFurniture>() {
public int compare(CatalogPieceOfFurniture piece1, CatalogPieceOfFurniture piece2) {
return piece1.isResizable() == piece2.isResizable()
? 0
: (piece1.isResizable()
? -1 : 1);
}
};
} else if (FurnitureLibrary.FURNITURE_DEFORMABLE_PROPERTY.equals(propertyKey)) {
furnitureComparator = new Comparator<CatalogPieceOfFurniture>() {
public int compare(CatalogPieceOfFurniture piece1, CatalogPieceOfFurniture piece2) {
return piece1.isDeformable() == piece2.isDeformable()
? 0
: (piece1.isDeformable()
? -1 : 1);
}
};
} else {
furnitureComparator = new Comparator<CatalogPieceOfFurniture>() {
@SuppressWarnings("unchecked")
public int compare(CatalogPieceOfFurniture piece1, CatalogPieceOfFurniture piece2) {
Object piece1Property = furnitureLibrary.getPieceOfFurnitureLocalizedData(
piece1, controller.getFurnitureLangauge(), propertyKey);
if (piece1Property == null
|| !(piece1Property instanceof Comparable)) {
return -1;
} else {
Object piece2Property = furnitureLibrary.getPieceOfFurnitureLocalizedData(
piece2, controller.getFurnitureLangauge(), propertyKey, piece2.getDescription());
return ((Comparable)piece1Property).compareTo(piece2Property);
}
}
};
}
if (this.descendingOrder) {
furnitureComparator = Collections.reverseOrder(furnitureComparator);
}
return furnitureComparator;
}
public String getSortProperty() {
return this.sortProperty;
}
public void setSortProperty(String sortProperty) {
this.sortProperty = sortProperty;
sortFurniture();
}
public boolean isDescendingOrder() {
return this.descendingOrder;
}
public void setDescendingOrder(boolean descendingOrder) {
this.descendingOrder = descendingOrder;
sortFurniture();
}
}
/**
* Column table model used by furniture library table.
*/
private static class FurnitureLibraryTableColumnModel extends DefaultTableColumnModel {
public FurnitureLibraryTableColumnModel(FurnitureLibrary furnitureLibrary,
FurnitureLibraryUserPreferences preferences,
FurnitureLanguageController controller) {
createColumns(furnitureLibrary, preferences, controller);
addLanguageListener(preferences);
}
/**
* Creates the list of available columns from furniture sortable properties.
*/
private void createColumns(FurnitureLibrary furnitureLibrary,
FurnitureLibraryUserPreferences preferences,
FurnitureLanguageController controller) {
// Create the list of custom columns
TableCellRenderer headerRenderer = getHeaderRenderer();
for (String columnProperty : preferences.getEditedProperties()) {
if (columnProperty != "MODEL_ROTATION"
&& columnProperty != "MODEL") {
TableColumn tableColumn = new TableColumn();
tableColumn.setIdentifier(columnProperty);
tableColumn.setHeaderValue(getColumnName(columnProperty, preferences));
tableColumn.setPreferredWidth(getColumnPreferredWidth(columnProperty));
tableColumn.setCellRenderer(getColumnRenderer(columnProperty, furnitureLibrary, preferences, controller));
tableColumn.setHeaderRenderer(headerRenderer);
addColumn(tableColumn);
}
}
}
/**
* Adds a property change listener to <code>preferences</code> to update
* column names when preferred language changes.
*/
private void addLanguageListener(UserPreferences preferences) {
preferences.addPropertyChangeListener(UserPreferences.Property.LANGUAGE,
new LanguageChangeListener(this));
}
/**
* Preferences property listener bound to this component with a weak reference to avoid
* strong link between preferences and this component.
*/
private static class LanguageChangeListener implements PropertyChangeListener {
private WeakReference<FurnitureLibraryTableColumnModel> furnitureTableColumnModel;
public LanguageChangeListener(FurnitureLibraryTableColumnModel furnitureTable) {
this.furnitureTableColumnModel = new WeakReference<FurnitureLibraryTableColumnModel>(furnitureTable);
}
public void propertyChange(PropertyChangeEvent ev) {
// If furniture table column model was garbage collected, remove this listener from preferences
FurnitureLibraryTableColumnModel furnitureTableColumnModel = this.furnitureTableColumnModel.get();
UserPreferences preferences = (UserPreferences)ev.getSource();
if (furnitureTableColumnModel == null) {
preferences.removePropertyChangeListener(UserPreferences.Property.LANGUAGE, this);
} else {
// Change column name and renderer from current locale
for (int i = 0; i < furnitureTableColumnModel.getColumnCount(); i++) {
TableColumn tableColumn = furnitureTableColumnModel.getColumn(i);
Object columnIdentifier = tableColumn.getIdentifier();
if (columnIdentifier instanceof String) {
try {
tableColumn.setHeaderValue(furnitureTableColumnModel.getColumnName(
(String)columnIdentifier, preferences));
} catch (IllegalArgumentException ex) {
// Don't change unknown columns
}
}
}
}
}
}
/**
* Returns localized column names.
*/
private String getColumnName(String propertyKey,
UserPreferences preferences) {
if (FurnitureLibrary.FURNITURE_ID_PROPERTY.equals(propertyKey)) {
return preferences.getLocalizedString(FurnitureLibraryTable.class, "idColumn");
} else if (FurnitureLibrary.FURNITURE_NAME_PROPERTY.equals(propertyKey)) {
return preferences.getLocalizedString(FurnitureLibraryTable.class, "nameColumn");
} else if (FurnitureLibrary.FURNITURE_DESCRIPTION_PROPERTY.equals(propertyKey)) {
return preferences.getLocalizedString(FurnitureLibraryTable.class, "descriptionColumn");
} else if (FurnitureLibrary.FURNITURE_CREATOR_PROPERTY.equals(propertyKey)) {
return preferences.getLocalizedString(FurnitureLibraryTable.class, "creatorColumn");
} else if (FurnitureLibrary.FURNITURE_CATEGORY_PROPERTY.equals(propertyKey)) {
return preferences.getLocalizedString(FurnitureLibraryTable.class, "categoryColumn");
} else if (FurnitureLibrary.FURNITURE_PRICE_PROPERTY.equals(propertyKey)) {
return preferences.getLocalizedString(FurnitureLibraryTable.class, "priceColumn");
} else if (FurnitureLibrary.FURNITURE_VALUE_ADDED_TAX_PERCENTAGE_PROPERTY.equals(propertyKey)) {
return preferences.getLocalizedString(FurnitureLibraryTable.class, "valueAddedTaxPercentageColumn");
} else if (FurnitureLibrary.FURNITURE_ICON_PROPERTY.equals(propertyKey)) {
return preferences.getLocalizedString(FurnitureLibraryTable.class, "iconColumn");
} else if (FurnitureLibrary.FURNITURE_PLAN_ICON_PROPERTY.equals(propertyKey)) {
return preferences.getLocalizedString(FurnitureLibraryTable.class, "planIconColumn");
} else if (FurnitureLibrary.FURNITURE_MODEL_PROPERTY.equals(propertyKey)) {
return preferences.getLocalizedString(FurnitureLibraryTable.class, "modelColumn");
} else if (FurnitureLibrary.FURNITURE_WIDTH_PROPERTY.equals(propertyKey)) {
return preferences.getLocalizedString(FurnitureLibraryTable.class, "widthColumn");
} else if (FurnitureLibrary.FURNITURE_DEPTH_PROPERTY.equals(propertyKey)) {
return preferences.getLocalizedString(FurnitureLibraryTable.class, "depthColumn");
} else if (FurnitureLibrary.FURNITURE_HEIGHT_PROPERTY.equals(propertyKey)) {
return preferences.getLocalizedString(FurnitureLibraryTable.class, "heightColumn");
} else if (FurnitureLibrary.FURNITURE_MOVABLE_PROPERTY.equals(propertyKey)) {
return preferences.getLocalizedString(FurnitureLibraryTable.class, "movableColumn");
} else if (FurnitureLibrary.FURNITURE_DOOR_OR_WINDOW_PROPERTY.equals(propertyKey)) {
return preferences.getLocalizedString(FurnitureLibraryTable.class, "doorOrWindowColumn");
} else if (FurnitureLibrary.FURNITURE_ELEVATION_PROPERTY.equals(propertyKey)) {
return preferences.getLocalizedString(FurnitureLibraryTable.class, "elevationColumn");
} else if (FurnitureLibrary.FURNITURE_MODEL_ROTATION_PROPERTY.equals(propertyKey)) {
return preferences.getLocalizedString(FurnitureLibraryTable.class, "modelRotationColumn");
} else if (FurnitureLibrary.FURNITURE_RESIZABLE_PROPERTY.equals(propertyKey)) {
return preferences.getLocalizedString(FurnitureLibraryTable.class, "resizableColumn");
} else if (FurnitureLibrary.FURNITURE_DEFORMABLE_PROPERTY.equals(propertyKey)) {
return preferences.getLocalizedString(FurnitureLibraryTable.class, "deformableColumn");
} else {
throw new IllegalArgumentException("Unknown key " + propertyKey);
}
}
/**
* Returns the preferred width of a column.
*/
private int getColumnPreferredWidth(String propertyKey) {
if (FurnitureLibrary.FURNITURE_ID_PROPERTY.equals(propertyKey)) {
return 120;
} else if (FurnitureLibrary.FURNITURE_NAME_PROPERTY.equals(propertyKey)) {
return 100;
} else if (FurnitureLibrary.FURNITURE_DESCRIPTION_PROPERTY.equals(propertyKey)) {
return 150;
} else if (FurnitureLibrary.FURNITURE_CREATOR_PROPERTY.equals(propertyKey)) {
return 100;
} else if (FurnitureLibrary.FURNITURE_CATEGORY_PROPERTY.equals(propertyKey)) {
return 70;
} else if (FurnitureLibrary.FURNITURE_PRICE_PROPERTY.equals(propertyKey)) {
return 70;
} else if (FurnitureLibrary.FURNITURE_VALUE_ADDED_TAX_PERCENTAGE_PROPERTY.equals(propertyKey)) {
return 50;
} else if (FurnitureLibrary.FURNITURE_ICON_PROPERTY.equals(propertyKey)
|| FurnitureLibrary.FURNITURE_PLAN_ICON_PROPERTY.equals(propertyKey)) {
return 50;
} else if (FurnitureLibrary.FURNITURE_MODEL_PROPERTY.equals(propertyKey)) {
return 70;
} else if (FurnitureLibrary.FURNITURE_WIDTH_PROPERTY.equals(propertyKey)
|| FurnitureLibrary.FURNITURE_DEPTH_PROPERTY.equals(propertyKey)
|| FurnitureLibrary.FURNITURE_HEIGHT_PROPERTY.equals(propertyKey)
|| FurnitureLibrary.FURNITURE_ELEVATION_PROPERTY.equals(propertyKey)) {
return 45;
} else if (FurnitureLibrary.FURNITURE_MOVABLE_PROPERTY.equals(propertyKey)
|| FurnitureLibrary.FURNITURE_DOOR_OR_WINDOW_PROPERTY.equals(propertyKey)
|| FurnitureLibrary.FURNITURE_RESIZABLE_PROPERTY.equals(propertyKey)
|| FurnitureLibrary.FURNITURE_DEFORMABLE_PROPERTY.equals(propertyKey)) {
return 20;
} else if (FurnitureLibrary.FURNITURE_MODEL_ROTATION_PROPERTY.equals(propertyKey)) {
return 70;
} else {
throw new IllegalArgumentException("Unknown key " + propertyKey);
}
}
/**
* Returns column renderers.
*/
private TableCellRenderer getColumnRenderer(String propertyKey,
FurnitureLibrary furnitureLibrary,
UserPreferences preferences,
FurnitureLanguageController controller) {
if (FurnitureLibrary.FURNITURE_ID_PROPERTY.equals(propertyKey)
|| FurnitureLibrary.FURNITURE_NAME_PROPERTY.equals(propertyKey)
|| FurnitureLibrary.FURNITURE_DESCRIPTION_PROPERTY.equals(propertyKey)
|| FurnitureLibrary.FURNITURE_CATEGORY_PROPERTY.equals(propertyKey)
|| FurnitureLibrary.FURNITURE_CREATOR_PROPERTY.equals(propertyKey)) {
return getStringRenderer(propertyKey, furnitureLibrary, controller);
} else if (FurnitureLibrary.FURNITURE_ICON_PROPERTY.equals(propertyKey)
|| FurnitureLibrary.FURNITURE_PLAN_ICON_PROPERTY.equals(propertyKey)) {
return getIconRenderer(propertyKey);
} else if (FurnitureLibrary.FURNITURE_MODEL_PROPERTY.equals(propertyKey)) {
return getButtonRenderer(propertyKey, preferences);
} else if (FurnitureLibrary.FURNITURE_PRICE_PROPERTY.equals(propertyKey)) {
return getPriceRenderer(preferences);
} else if (FurnitureLibrary.FURNITURE_VALUE_ADDED_TAX_PERCENTAGE_PROPERTY.equals(propertyKey)) {
return getValueAddedTaxPercentageRenderer();
} else if (FurnitureLibrary.FURNITURE_WIDTH_PROPERTY.equals(propertyKey)
|| FurnitureLibrary.FURNITURE_DEPTH_PROPERTY.equals(propertyKey)
|| FurnitureLibrary.FURNITURE_HEIGHT_PROPERTY.equals(propertyKey)
|| FurnitureLibrary.FURNITURE_ELEVATION_PROPERTY.equals(propertyKey)) {
return getSizeRenderer(propertyKey, preferences);
} else if (FurnitureLibrary.FURNITURE_MOVABLE_PROPERTY.equals(propertyKey)
|| FurnitureLibrary.FURNITURE_DOOR_OR_WINDOW_PROPERTY.equals(propertyKey)
|| FurnitureLibrary.FURNITURE_RESIZABLE_PROPERTY.equals(propertyKey)
|| FurnitureLibrary.FURNITURE_DEFORMABLE_PROPERTY.equals(propertyKey)) {
return getBooleanRenderer(propertyKey);
} else if (FurnitureLibrary.FURNITURE_MODEL_ROTATION_PROPERTY.equals(propertyKey)) {
return getButtonRenderer(propertyKey, preferences);
} else {
throw new IllegalArgumentException("Unknown key " + propertyKey);
}
}
/**
* Returns a renderer that displays a string property of a piece of furniture.
*/
private TableCellRenderer getStringRenderer(final String propertyKey,
final FurnitureLibrary furnitureLibrary,
final FurnitureLanguageController controller) {
if (FurnitureLibrary.FURNITURE_ID_PROPERTY.equals(propertyKey)) {
return new DefaultTableCellRenderer() {
@Override
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
return super.getTableCellRendererComponent(
table, ((CatalogPieceOfFurniture)value).getId(), isSelected, hasFocus, row, column);
}
};
} else if (FurnitureLibrary.FURNITURE_NAME_PROPERTY.equals(propertyKey)) {
return new DefaultTableCellRenderer() {
@Override
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
CatalogPieceOfFurniture piece = (CatalogPieceOfFurniture)value;
String pieceName = (String)furnitureLibrary.getPieceOfFurnitureLocalizedData(
piece, controller.getFurnitureLangauge(), propertyKey, piece.getName());
return super.getTableCellRendererComponent(
table, pieceName, isSelected, hasFocus, row, column);
}
};
} else if (FurnitureLibrary.FURNITURE_DESCRIPTION_PROPERTY.equals(propertyKey)) {
return new DefaultTableCellRenderer() {
@Override
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
CatalogPieceOfFurniture piece = (CatalogPieceOfFurniture)value;
String pieceDescription = (String)furnitureLibrary.getPieceOfFurnitureLocalizedData(
piece, controller.getFurnitureLangauge(), propertyKey, piece.getDescription());
return super.getTableCellRendererComponent(
table, pieceDescription, isSelected, hasFocus, row, column);
}
};
} else if (FurnitureLibrary.FURNITURE_CATEGORY_PROPERTY.equals(propertyKey)) {
return new DefaultTableCellRenderer() {
@Override
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
CatalogPieceOfFurniture piece = (CatalogPieceOfFurniture)value;
String pieceCategory = (String)furnitureLibrary.getPieceOfFurnitureLocalizedData(
piece, controller.getFurnitureLangauge(), propertyKey, piece.getCategory().getName());
return super.getTableCellRendererComponent(
table, pieceCategory, isSelected, hasFocus, row, column);
}
};
} else if (FurnitureLibrary.FURNITURE_CREATOR_PROPERTY.equals(propertyKey)) {
return new DefaultTableCellRenderer() {
@Override
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
return super.getTableCellRendererComponent(
table, ((CatalogPieceOfFurniture)value).getCreator(), isSelected, hasFocus, row, column);
}
};
} else {
throw new IllegalArgumentException(propertyKey + " column not a string column");
}
}
/**
* Returns a renderer that displays a button.
*/
private TableCellRenderer getButtonRenderer(String propertyKey,
final UserPreferences preferences) {
if (FurnitureLibrary.FURNITURE_MODEL_PROPERTY.equals(propertyKey)
|| FurnitureLibrary.FURNITURE_MODEL_ROTATION_PROPERTY.equals(propertyKey)) {
return new TableCellRenderer() {
private JButton component = new JButton();
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
component.setText(preferences.getLocalizedString(FurnitureLibraryTable.class, "modifyButton"));
return component;
}
};
} else {
throw new IllegalArgumentException(propertyKey + " column not a button column");
}
}
/**
* Returns a renderer that displays the icons of a piece of furniture.
*/
private TableCellRenderer getIconRenderer(final String propertyKey) {
return new DefaultTableCellRenderer() {
@Override
public Component getTableCellRendererComponent(JTable table,
Object value, boolean isSelected, boolean hasFocus,
int row, int column) {
CatalogPieceOfFurniture piece = (CatalogPieceOfFurniture)value;
JLabel label = (JLabel)super.getTableCellRendererComponent(
table, "", isSelected, hasFocus, row, column);
Content iconContent;
if (FurnitureLibrary.FURNITURE_ICON_PROPERTY.equals(propertyKey)) {
iconContent = piece.getIcon();
} else {
iconContent = piece.getPlanIcon();
}
if (iconContent != null) {
label.setIcon(IconManager.getInstance().getIcon(
iconContent, table.getRowHeight(), table));
label.setHorizontalAlignment(JLabel.CENTER);
} else {
label.setIcon(null);
}
return label;
}
};
}
/**
* Returns a renderer that converts the displayed <code>property</code> of a piece of furniture
* to inch in case preferences unit us equal to INCH.
*/
private TableCellRenderer getSizeRenderer(String propertyKey,
final UserPreferences preferences) {
// Renderer super class used to display sizes
class SizeRenderer extends DefaultTableCellRenderer {
public Component getTableCellRendererComponent(JTable table,
Object value, boolean isSelected, boolean hasFocus,
int row, int column) {
value = preferences.getLengthUnit().getFormat().format((Float)value);
setHorizontalAlignment(JLabel.RIGHT);
return super.getTableCellRendererComponent(
table, value, isSelected, hasFocus, row, column);
}
};
if (FurnitureLibrary.FURNITURE_WIDTH_PROPERTY.equals(propertyKey)) {
return new SizeRenderer() {
@Override
public Component getTableCellRendererComponent(JTable table,
Object value, boolean isSelected, boolean hasFocus, int row, int column) {
return super.getTableCellRendererComponent(table,
((CatalogPieceOfFurniture)value).getWidth(), isSelected, hasFocus, row, column);
}
};
} else if (FurnitureLibrary.FURNITURE_DEPTH_PROPERTY.equals(propertyKey)) {
return new SizeRenderer() {
@Override
public Component getTableCellRendererComponent(JTable table,
Object value, boolean isSelected, boolean hasFocus, int row, int column) {
return super.getTableCellRendererComponent(table,
((CatalogPieceOfFurniture)value).getDepth(), isSelected, hasFocus, row, column);
}
};
} else if (FurnitureLibrary.FURNITURE_HEIGHT_PROPERTY.equals(propertyKey)) {
return new SizeRenderer() {
@Override
public Component getTableCellRendererComponent(JTable table,
Object value, boolean isSelected, boolean hasFocus, int row, int column) {
return super.getTableCellRendererComponent(table,
((CatalogPieceOfFurniture)value).getHeight(), isSelected, hasFocus, row, column);
}
};
} else if (FurnitureLibrary.FURNITURE_ELEVATION_PROPERTY.equals(propertyKey)) {
return new SizeRenderer() {
@Override
public Component getTableCellRendererComponent(JTable table,
Object value, boolean isSelected, boolean hasFocus, int row, int column) {
return super.getTableCellRendererComponent(table,
((CatalogPieceOfFurniture)value).getElevation(), isSelected, hasFocus, row, column);
}
};
} else {
throw new IllegalArgumentException(propertyKey + " column not a size column");
}
}
/**
* Returns a renderer that displays the price of a piece of furniture.
*/
private TableCellRenderer getPriceRenderer(final UserPreferences preferences) {
return new DefaultTableCellRenderer() {
public Component getTableCellRendererComponent(JTable table,
Object value, boolean isSelected, boolean hasFocus,
int row, int column) {
value = ((CatalogPieceOfFurniture)value).getPrice();
if (value != null) {
String currency = preferences.getCurrency();
NumberFormat currencyFormat;
if (currency != null) {
currencyFormat = DecimalFormat.getCurrencyInstance();
currencyFormat.setCurrency(Currency.getInstance(currency));
} else {
currencyFormat = new DecimalFormat("##0.00");
}
value = currencyFormat.format(value);
} else {
value = "";
}
setHorizontalAlignment(JLabel.RIGHT);
return super.getTableCellRendererComponent(
table, value, isSelected, hasFocus, row, column);
}
};
}
/**
* Returns a renderer that displays the value added tax percentage property of a piece of furniture.
*/
private TableCellRenderer getValueAddedTaxPercentageRenderer() {
return new DefaultTableCellRenderer() {
@Override
public Component getTableCellRendererComponent(JTable table,
Object value, boolean isSelected, boolean hasFocus,
int row, int column) {
BigDecimal valueAddedTaxPercentage = ((CatalogPieceOfFurniture)value).getValueAddedTaxPercentage();
if (valueAddedTaxPercentage != null) {
NumberFormat percentInstance = DecimalFormat.getPercentInstance();
percentInstance.setMinimumFractionDigits(valueAddedTaxPercentage.scale() - 2);
value = percentInstance.format(valueAddedTaxPercentage);
} else {
value = "";
}
setHorizontalAlignment(JLabel.RIGHT);
return super.getTableCellRendererComponent(
table, value, isSelected, hasFocus, row, column);
}
};
}
/**
* Returns a renderer that displays a property of a piece of furniture
* with <code>JTable</code> default boolean renderer.
*/
private TableCellRenderer getBooleanRenderer(String propertyKey) {
// Renderer super class used to display booleans
class BooleanRenderer implements TableCellRenderer {
private TableCellRenderer booleanRenderer;
public Component getTableCellRendererComponent(JTable table,
Object value, boolean isSelected, boolean hasFocus, int row, int column) {
if (this.booleanRenderer == null) {
this.booleanRenderer = table.getDefaultRenderer(Boolean.class);
}
return this.booleanRenderer.getTableCellRendererComponent(
table, value, isSelected, hasFocus, row, column);
}
};
if (FurnitureLibrary.FURNITURE_MOVABLE_PROPERTY.equals(propertyKey)) {
return new BooleanRenderer() {
@Override
public Component getTableCellRendererComponent(JTable table,
Object value, boolean isSelected, boolean hasFocus, int row, int column) {
return super.getTableCellRendererComponent(table,
((CatalogPieceOfFurniture)value).isMovable(), isSelected, hasFocus, row, column);
}
};
} else if (FurnitureLibrary.FURNITURE_DOOR_OR_WINDOW_PROPERTY.equals(propertyKey)) {
return new BooleanRenderer() {
@Override
public Component getTableCellRendererComponent(JTable table,
Object value, boolean isSelected, boolean hasFocus, int row, int column) {
return super.getTableCellRendererComponent(table,
((CatalogPieceOfFurniture)value).isDoorOrWindow(), isSelected, hasFocus, row, column);
}
};
} else if (FurnitureLibrary.FURNITURE_RESIZABLE_PROPERTY.equals(propertyKey)) {
return new BooleanRenderer() {
@Override
public Component getTableCellRendererComponent(JTable table,
Object value, boolean isSelected, boolean hasFocus, int row, int column) {
return super.getTableCellRendererComponent(table,
((CatalogPieceOfFurniture)value).isResizable(), isSelected, hasFocus, row, column);
}
};
} else if (FurnitureLibrary.FURNITURE_DEFORMABLE_PROPERTY.equals(propertyKey)) {
return new BooleanRenderer() {
@Override
public Component getTableCellRendererComponent(JTable table,
Object value, boolean isSelected, boolean hasFocus, int row, int column) {
return super.getTableCellRendererComponent(table,
((CatalogPieceOfFurniture)value).isDeformable(), isSelected, hasFocus, row, column);
}
};
} else {
throw new IllegalArgumentException(propertyKey + " column not a boolean column");
}
}
/**
* Returns column header renderer that displays an ascending or a descending icon
* when column is sorted, beside column name.
*/
private TableCellRenderer getHeaderRenderer() {
// Return a table renderer that displays the icon matching current sort
return new TableCellRenderer() {
private TableCellRenderer headerRenderer;
private ImageIcon ascendingSortIcon = new ImageIcon(getClass().getResource("resources/ascending.png"));
private ImageIcon descendingSortIcon = new ImageIcon(getClass().getResource("resources/descending.png"));
public Component getTableCellRendererComponent(JTable table,
Object value, boolean isSelected, boolean hasFocus, int row, int column) {
if (this.headerRenderer == null) {
this.headerRenderer = table.getTableHeader().getDefaultRenderer();
}
// Get default label
JLabel label = (JLabel)this.headerRenderer.getTableCellRendererComponent(
table, value, isSelected, hasFocus, row, column);
// Add to column an icon matching sort
FurnitureLibraryTableModel model = (FurnitureLibraryTableModel)table.getModel();
if (getColumn(column).getIdentifier().equals(model.getSortProperty())) {
label.setHorizontalTextPosition(JLabel.LEADING);
if (model.isDescendingOrder()) {
label.setIcon(descendingSortIcon);
} else {
label.setIcon(ascendingSortIcon);
}
} else {
label.setIcon(null);
}
return label;
}
};
}
}
/**
* Table transfer handler.
*/
private class TableTransferHandler extends TransferHandler {
private final FurnitureLibraryController furnitureController;
/**
* Creates a handler able to receive furniture files.
*/
public TableTransferHandler(FurnitureLibraryController furnitureController) {
this.furnitureController = furnitureController;
}
@Override
public int getSourceActions(JComponent source) {
return NONE;
}
/**
* Returns <code>true</code> if flavors contains
* <code>DataFlavor.javaFileListFlavor</code> flavor.
*/
@Override
public boolean canImport(JComponent destination, DataFlavor [] flavors) {
return this.furnitureController != null
&& Arrays.asList(flavors).contains(DataFlavor.javaFileListFlavor);
}
/**
* Add to library the furniture contained in <code>transferable</code>.
*/
@SuppressWarnings("unchecked")
@Override
public boolean importData(JComponent destination, Transferable transferable) {
if (canImport(destination, transferable.getTransferDataFlavors())) {
try {
List<File> files = (List<File>)transferable.getTransferData(DataFlavor.javaFileListFlavor);
final List<String> importableModels = new ArrayList<String>();
for (File file : files) {
if (!file.isDirectory()) {
String absolutePath = file.getAbsolutePath();
importableModels.add(absolutePath);
}
}
EventQueue.invokeLater(new Runnable() {
public void run() {
furnitureController.importFurniture(importableModels.toArray(new String [importableModels.size()]));
}
});
return !importableModels.isEmpty();
} catch (UnsupportedFlavorException ex) {
throw new RuntimeException("Can't import", ex);
} catch (IOException ex) {
throw new RuntimeException("Can't access to data", ex);
}
} else {
return false;
}
}
}
}