/* This file belongs to the Servoy development and deployment environment, Copyright (C) 1997-2010 Servoy BV This program is free software; you can redistribute it and/or modify it under the terms of the GNU Affero 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, see http://www.gnu.org/licenses or write to the Free Software Foundation,Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 */ package com.servoy.j2db.gui; import java.awt.Color; import java.awt.Component; import java.awt.Dimension; import java.awt.Font; import java.awt.Insets; import java.util.List; import javax.swing.BorderFactory; import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.JLabel; import javax.swing.JTable; import javax.swing.SwingConstants; import javax.swing.border.Border; import javax.swing.plaf.UIResource; import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.TableCellRenderer; import com.servoy.j2db.IApplication; import com.servoy.j2db.component.ComponentFactory; import com.servoy.j2db.persistence.Form; import com.servoy.j2db.persistence.GraphicalComponent; import com.servoy.j2db.smart.TableView; import com.servoy.j2db.smart.dataui.CellAdapter; import com.servoy.j2db.ui.IComponent; import com.servoy.j2db.util.IStyleRule; import com.servoy.j2db.util.IStyleSheet; import com.servoy.j2db.util.ImageLoader; import com.servoy.j2db.util.Pair; import com.servoy.j2db.util.Utils; import com.servoy.j2db.util.gui.MyImageIcon; /*** * Header renderer for table component(tableview or portal); used for normal header and labelfor header * * @author lvostinar */ public class LFAwareSortableHeaderRenderer extends DefaultTableCellRenderer implements IComponent, UIResource { private final TableView parentTable; private final CellAdapter cellAdapter; private final int columnIndex; private ImageIcon arrowDown = null; private ImageIcon arrowUp = null; private final int defaultHorizontalTextPosition; protected final GraphicalComponent gc; private static Border defaultBorder; private static Color defaultFgColor; private static Color defaultBgColor; private static Font defaultFont; private Border border; private Insets margin; public LFAwareSortableHeaderRenderer(IApplication app, TableView parentTable, CellAdapter cellAdapter, ImageIcon arrowUp, ImageIcon arrowDown, GraphicalComponent gc, Form formForStyles) { super(); setBorder(null); this.parentTable = parentTable; this.cellAdapter = cellAdapter; this.columnIndex = cellAdapter.getModelIndex(); this.arrowUp = arrowUp; this.arrowDown = arrowDown; this.defaultHorizontalTextPosition = getHorizontalTextPosition(); this.gc = gc; setHorizontalAlignment(CENTER); setVerticalAlignment(CENTER); if (gc != null) { int style_halign = -1; int style_valign = -1; Pair<IStyleSheet, IStyleRule> styleInfo = ComponentFactory.getStyleForBasicComponent(app, gc, formForStyles); if (styleInfo != null) { IStyleSheet ss = styleInfo.getLeft(); IStyleRule s = styleInfo.getRight(); if (ss != null && s != null) { style_valign = ss.getVAlign(s); style_halign = ss.getHAlign(s); if (ss.hasMargin(s)) { margin = ss.getMargin(s); } } } int halign = gc.getHorizontalAlignment(); if (halign != -1) { setHorizontalAlignment(halign); } else if (style_halign != -1) { setHorizontalAlignment(style_halign); } int valign = gc.getVerticalAlignment(); if (valign != -1) { setVerticalAlignment(valign); } else if (style_valign != -1) { setVerticalAlignment(style_valign); } int mediaId = gc.getImageMediaID(); if (mediaId > 0) { Icon icon = null; if (gc.getMediaOptions() != 1) { icon = new MyImageIcon(app, this, ComponentFactory.loadIcon(app.getFlattenedSolution(), new Integer(mediaId)), gc.getMediaOptions()); } else { icon = ImageLoader.getIcon(ComponentFactory.loadIcon(app.getFlattenedSolution(), new Integer(mediaId)), 0, 0, true); } if (icon != null) setIcon(icon); } if (gc != null && gc.getText() != null && gc.getText().length() > 0) { String text = gc.getText(); text = app.getI18NMessageIfPrefixed(text); parentTable.getColumnModel().getColumn(columnIndex).setHeaderValue(text); } setToolTipText(app.getI18NMessageIfPrefixed(gc.getToolTipText())); if (gc != null && gc.getMargin() != null) margin = gc.getMargin(); } } private Component lfComponent = null; private Object lfValue = null; @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { if (gc != null && gc.getImageMediaID() == 0) { if (!parentTable.getCurrentSortColumn().keySet().contains(new Integer(columnIndex)) || !parentTable.shouldDisplaySortIcons()) { this.setIcon(null); } else { if (parentTable.getCurrentSortColumn().get(new Integer(columnIndex)).booleanValue()) this.setIcon(arrowDown); else this.setIcon(arrowUp); this.setHorizontalTextPosition(SwingConstants.LEADING); } } else { this.setHorizontalTextPosition(defaultHorizontalTextPosition); } TableCellRenderer lfAwareRenderer = table.getTableHeader().getDefaultRenderer(); if (lfAwareRenderer != null) { // Ask the renderer to do the rendering for us. if (lfComponent == null || !Utils.equalObjects(value, lfValue)) { // cache value, this is an expensive operation into the look and feel renderer. lfComponent = lfAwareRenderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); lfValue = value; } if (defaultFgColor == null) defaultFgColor = ((JLabel)lfComponent).getForeground(); if (defaultBgColor == null) defaultBgColor = ((JLabel)lfComponent).getBackground(); if (defaultFont == null) defaultFont = ((JLabel)lfComponent).getFont(); if (lfComponent instanceof JLabel) { if (defaultBorder == null) defaultBorder = ((JLabel)lfComponent).getBorder(); } // If the returned component supports icons (is a JLabel), then add the needed icon to it. // Usually the returned component is a JLabel. if (gc == null) { Color styleBgColor = cellAdapter.getHeaderBgColor(parentTable); if (styleBgColor != null) lfComponent.setBackground(styleBgColor); else lfComponent.setBackground(defaultBgColor); Color styleFgColor = cellAdapter.getHeaderFgColor(parentTable); if (styleFgColor != null) lfComponent.setForeground(styleFgColor); else lfComponent.setForeground(defaultFgColor); Font styleFont = cellAdapter.getHeaderFont(parentTable); if (styleFont != null) lfComponent.setFont(styleFont); else lfComponent.setFont(defaultFont); if (lfComponent instanceof JLabel) { JLabel label = (JLabel)lfComponent; if (styleBgColor != null) { label.setOpaque(true); } else { label.setOpaque(false); } label.setToolTipText(null); Dimension preferredSize = label.getPreferredSize(); if (!parentTable.getCurrentSortColumn().keySet().contains(columnIndex)) { if (label.getIcon() != null) label.setIcon(null); } else if (parentTable.shouldDisplaySortIcons()) { if (parentTable.getCurrentSortColumn().get(new Integer(columnIndex)).booleanValue()) { if (label.getIcon() != arrowDown) label.setIcon(arrowDown); } else if (label.getIcon() != arrowUp) label.setIcon(arrowUp); } if (!"".equals(value)) label.setPreferredSize(preferredSize); if (label.getHorizontalTextPosition() != SwingConstants.LEADING) label.setHorizontalTextPosition(SwingConstants.LEADING); // If the text consists only of spaces, trim it down. // It seems that when we set a label to have no text, the text that arrives is " ", not "", // and this generates some "..." to be displayed if the width of the column is small. String text = ""; //$NON-NLS-1$ if (value != null && value.toString().trim().length() > 0) text = value.toString(); if (!text.equals(label.getText())) label.setText(text); } } else { if (getBackground() != null && !Utils.equalObjects(getBackground(), lfComponent.getBackground())) lfComponent.setBackground(getBackground()); if (!Utils.equalObjects(getForeground(), lfComponent.getForeground())) lfComponent.setForeground(getForeground()); if (!Utils.equalObjects(getFont(), lfComponent.getFont())) lfComponent.setFont(getFont()); if (lfComponent instanceof JLabel) { JLabel label = (JLabel)lfComponent; // If the text consists only of spaces, trim it down. // It seems that when we set a label to have no text, the text that arrives is " ", not "", // and this generates some "..." to be displayed if the width of the column is small. String text = ""; //$NON-NLS-1$ if (value != null && value.toString().trim().length() > 0) text = value.toString(); if (!text.equals(label.getText())) label.setText(text); if (!Utils.equalObjects(getIcon(), label.getIcon())) label.setIcon(getIcon()); if (label.isOpaque() != isOpaque()) label.setOpaque(isOpaque()); if (!Utils.equalObjects(getToolTipText(), label.getToolTipText())) label.setToolTipText(getToolTipText()); if (label.getHorizontalTextPosition() != SwingConstants.LEADING) label.setHorizontalTextPosition(SwingConstants.LEADING); } // take the height of the first column label if (column == 0) lfComponent.setPreferredSize(new Dimension(lfComponent.getPreferredSize().width, (int)gc.getSize().getHeight())); } if (lfComponent instanceof JLabel) { JLabel label = (JLabel)lfComponent; label.setHorizontalAlignment(getHorizontalAlignment()); label.setVerticalAlignment(getVerticalAlignment()); if (border == null) { Border styleBorder = cellAdapter.getHeaderBorder(parentTable); if (styleBorder != null) ((JLabel)lfComponent).setBorder(styleBorder); border = (getBorder() != null) ? getBorder() : (styleBorder != null && gc == null ? styleBorder : defaultBorder); if (margin != null) { border = BorderFactory.createCompoundBorder(border, BorderFactory.createEmptyBorder(margin.top, margin.left, margin.bottom, margin.right)); } } label.setBorder(border); } return lfComponent; } else { return this; } } public void setComponentEnabled(boolean enabled) { setEnabled(enabled); } public void setComponentVisible(boolean enabled) { setVisible(enabled); } public String getId() { return null; } public int getOnActionMethodID() { if (gc != null) return gc.getOnActionMethodID(); return 0; } public List<Object> getInstanceMethodArguments(String methodKey) { if (methodKey != null && gc != null) { return gc.getInstanceMethodArguments(methodKey); } return null; } @Override public String getName() { if (gc != null) return gc.getName(); return null; } }