/*!
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software
* Foundation.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
* or from the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* 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 Lesser General Public License for more details.
*
* Copyright (c) 2002-2013 Pentaho Corporation.. All rights reserved.
*/
package org.pentaho.reporting.libraries.designtime.swing.colorchooser;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class SwatchColorChooser extends AbstractColorChooserPanel {
private class SwatchPanel extends JPanel implements Scrollable {
private Color[] colors;
private Dimension swatchSize;
private Dimension gap;
private int swatchCountPerRow;
private SwatchPanel() {
this( new Color[ 0 ] );
}
public SwatchPanel( final Color[] colors ) {
this.colors = colors;
swatchSize = new Dimension( 20, 20 );
gap = new Dimension( 2, 2 );
setOpaque( false );
}
public void setColors( final Color[] colors ) {
if ( colors == null ) {
throw new NullPointerException();
}
this.colors = colors;
invalidate();
revalidate();
repaint();
}
public Color getColorForPosition( final Point p ) {
final int width = getWidth();
if ( width == 0 ) {
return null;
}
final int cx = ( width - 1 ) / ( gap.width + swatchSize.width );
final int x = p.x / ( swatchSize.width + gap.width );
final int y = p.y / ( swatchSize.height + gap.height );
if ( y * cx + x < colors.length ) {
return ( colors[ y * cx + x ] );
}
return null;
}
protected void paintComponent( final Graphics g ) {
final int width = getWidth();
if ( width == 0 ) {
return;
}
final int cx = ( width - 1 ) / ( gap.width + swatchSize.width );
final int cy = (int) ( Math.ceil( Math.max( 1.0f, colors.length ) / cx ) );
final Color selectedColor = getColorSelectionModel().getSelectedColor();
for ( int y = 0; y < cy; y++ ) {
for ( int x = 0; x < cx; x++ ) {
final int px = x * ( swatchSize.width + gap.width );
final int py = y * ( swatchSize.height + gap.height );
if ( y * cx + x < colors.length ) {
final Color color = colors[ y * cx + x ];
g.setColor( color );
g.fillRect( px, py, swatchSize.width, swatchSize.height );
if ( selectedColor != null && selectedColor.equals( color ) ) {
g.setColor( Color.white );
} else {
g.setColor( Color.black );
}
g.drawRect( px, py, swatchSize.width, swatchSize.height );
}
}
}
}
public Dimension getPreferredScrollableViewportSize() {
return getPreferredSize();
}
public int getScrollableUnitIncrement( final Rectangle visibleRect, final int orientation, final int direction ) {
if ( orientation == SwingConstants.VERTICAL ) {
return swatchSize.height;
}
return swatchSize.width;
}
public int getScrollableBlockIncrement( final Rectangle visibleRect, final int orientation, final int direction ) {
return 5 * getScrollableUnitIncrement( visibleRect, orientation, direction );
}
public boolean getScrollableTracksViewportWidth() {
return true;
}
public boolean getScrollableTracksViewportHeight() {
return false;
}
public int getSwatchCountPerRow() {
return swatchCountPerRow;
}
public void setSwatchCountPerRow( final int swatchCountPerRow ) {
this.swatchCountPerRow = swatchCountPerRow;
}
public Dimension getPreferredSize() {
final int preferredSize;
if ( swatchCountPerRow <= 0 ) {
preferredSize = (int) Math.ceil( Math.sqrt( colors.length ) );
} else {
preferredSize = swatchCountPerRow;
}
if ( preferredSize == 0 ) {
return new Dimension( 0, 0 );
}
final int width = ( gap.width + swatchSize.width ) * preferredSize + gap.width;
final int height = (int) ( gap.height + ( swatchSize.height + gap.height ) * Math
.ceil( preferredSize / Math.min( 1, colors.length ) ) );
return new Dimension( width, height );
// return new Dimension(360, 360);
}
}
private class SchemaSelectionListener implements ItemListener {
private SchemaSelectionListener() {
}
public void itemStateChanged( final ItemEvent e ) {
final ColorSchema selectedKey = (ColorSchema) swatches.getSelectedItem();
if ( selectedKey != null ) {
colorList.setColors( selectedKey.getColors() );
}
}
}
private class SwatchPanelSelectionListener extends MouseAdapter {
private SwatchPanelSelectionListener() {
}
public void mouseClicked( final MouseEvent e ) {
if ( e.getButton() != MouseEvent.BUTTON1 ) {
return;
}
final Color color = colorList.getColorForPosition( e.getPoint() );
if ( color != null ) {
getColorSelectionModel().setSelectedColor( color );
}
}
}
private class ColorChooserRenderer extends DefaultListCellRenderer {
private ColorChooserRenderer() {
}
public Component getListCellRendererComponent( final JList list,
final Object value,
final int index,
final boolean isSelected,
final boolean cellHasFocus ) {
if ( value instanceof ColorSchema ) {
final ColorSchema cs = (ColorSchema) value;
return super.getListCellRendererComponent( list, cs.getName(), index, isSelected, cellHasFocus );
}
return super.getListCellRendererComponent( list, value, index, isSelected, cellHasFocus );
}
}
private DefaultComboBoxModel swatches;
private SwatchPanel colorList;
public SwatchColorChooser() {
swatches = new DefaultComboBoxModel();
colorList = new SwatchPanel();
colorList.addMouseListener( new SwatchPanelSelectionListener() );
final JComboBox comboBox = new JComboBox( swatches );
comboBox.addItemListener( new SchemaSelectionListener() );
comboBox.setRenderer( new ColorChooserRenderer() );
final JPanel selectorPanel = new JPanel();
selectorPanel.setLayout( new BorderLayout() );
selectorPanel.add( comboBox, BorderLayout.CENTER );
selectorPanel.add( new JLabel( ColorChooserMessages.getInstance().getString( "ColorSchema" ) ), BorderLayout.WEST );
final JScrollPane scrollPane = new JScrollPane( colorList, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER );
scrollPane.getViewport().setOpaque( false );
scrollPane.setOpaque( false );
setLayout( new BorderLayout() );
add( selectorPanel, BorderLayout.NORTH );
add( scrollPane, BorderLayout.CENTER );
addSwatches( new SwingColorSchema() );
addSwatches( new ExcelColorSchema() );
}
public void addSwatches( final ColorSchema colorSchema ) {
swatches.addElement( colorSchema );
if ( swatches.getSize() == 1 ) {
swatches.setSelectedItem( colorSchema );
}
}
public void removeSwatches( final ColorSchema colorSchema ) {
swatches.removeElement( colorSchema );
}
public void clearSwatches() {
swatches.removeAllElements();
}
public String getDisplayName() {
return ColorChooserMessages.getInstance().getString( "SwatchesTitle" );
}
public Icon getSmallDisplayIcon() {
return null;
}
protected void colorUpdated() {
colorList.repaint();
}
}