CSSeparation.java
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.pdfbox.debugger.colorpane;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.util.Dictionary;
import java.util.Hashtable;
import javax.swing.BoxLayout;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.JTextField;
import javax.swing.border.BevelBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import org.apache.pdfbox.cos.COSArray;
import org.apache.pdfbox.pdmodel.graphics.color.PDSeparation;
/**
* A class that provides the necessary UI and functionalities to show the Separation color space.
*
* @author Khyrul Bashar.
*/
public class CSSeparation implements ChangeListener, ActionListener
{
private JSlider slider;
private JTextField tintField;
private JLabel colorBar;
private JPanel panel;
private final PDSeparation separation;
private float tintValue = 1;
/**
* Constructor
*
* @param array COSArray instance of the Separation color space.
*
* @throws IOException if the instance could not be created
*/
public CSSeparation(COSArray array) throws IOException
{
separation = new PDSeparation(array, null);
initUI();
initValues();
}
/**
* initialize all the UI elements and arrange them.
*/
private void initUI() throws IOException
{
Font boldFont = new Font(Font.MONOSPACED, Font.BOLD, 20);
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(2, 2, 2, 2);
JPanel inputPanel = new JPanel(new GridBagLayout());
slider = new JSlider(0, 100, 50);
slider.setMajorTickSpacing(50);
slider.setPaintTicks(true);
@SuppressWarnings({"squid:S1149"})
Dictionary<Integer, JLabel> labelTable = new Hashtable<>();
JLabel lightest = new JLabel("lightest");
lightest.setFont(new Font(Font.MONOSPACED, Font.BOLD, 10));
JLabel darkest = new JLabel("darkest");
darkest.setFont(new Font(Font.MONOSPACED, Font.BOLD, 10));
JLabel midPoint = new JLabel("0.5");
midPoint.setFont(new Font(Font.MONOSPACED, Font.BOLD, 10));
labelTable.put(0, lightest);
labelTable.put(50, midPoint);
labelTable.put(100, darkest);
slider.setPaintLabels(true);
slider.setLabelTable(labelTable);
slider.addChangeListener(this);
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridwidth = 10;
gbc.weightx = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
inputPanel.add(slider, gbc);
JLabel tintLabel = new JLabel("Tint Value:");
tintLabel.setFont(boldFont);
gbc.gridx = 0;
gbc.gridy = 1;
gbc.weightx = 0.5;
gbc.gridwidth = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
inputPanel.add(tintLabel, gbc);
tintField = new JTextField();
tintField.addActionListener(this);
tintField.setPreferredSize(new Dimension(10, 30));
gbc.gridx = 1;
gbc.weightx = 0.5;
gbc.gridwidth = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
inputPanel.add(tintField, gbc);
JPanel contentPanel = new JPanel(new GridBagLayout());
GridBagConstraints gbc2 = new GridBagConstraints();
gbc2.gridx = 0;
gbc2.gridy = 0;
gbc2.gridwidth = 2;
gbc2.weightx = 0.3;
gbc2.weighty = 1;
gbc2.fill = GridBagConstraints.HORIZONTAL;
contentPanel.add(inputPanel, gbc2);
colorBar = new JLabel();
colorBar.setOpaque(true);
gbc2.gridx = 2;
gbc2.weightx = 0.7;
gbc2.gridwidth = 4;
gbc2.gridheight = 2;
gbc2.fill = GridBagConstraints.BOTH;
contentPanel.add(colorBar, gbc2);
setColorBarBorder();
JPanel mainpanel = new JPanel(new GridBagLayout());
JLabel colorantNameLabel = new JLabel("Colorant: " + separation.getColorantName());
colorantNameLabel.setFont(boldFont);
GridBagConstraints maingbc = new GridBagConstraints();
maingbc.gridx = 0;
maingbc.gridy = 0;
maingbc.weightx = 1;
maingbc.weighty = 0.03;
maingbc.anchor = GridBagConstraints.FIRST_LINE_START;
mainpanel.add(colorantNameLabel, maingbc);
maingbc.gridx = 0;
maingbc.gridy = 1;
maingbc.weighty = 0.97;
maingbc.gridwidth = 10;
maingbc.fill = GridBagConstraints.HORIZONTAL;
mainpanel.add(contentPanel, maingbc);
panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
panel.setPreferredSize(new Dimension(300, 500));
JLabel colorSpaceLabel = new JLabel("Separation colorspace");
colorSpaceLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
colorSpaceLabel.setFont(new Font(Font.MONOSPACED, Font.BOLD, 30));
panel.add(colorSpaceLabel);
panel.add(mainpanel);
}
private void initValues()
{
slider.setValue(getIntRepresentation(tintValue));
tintField.setText(Float.toString(tintValue));
}
/**
* return the main panel that hold all the UI elements.
* @return JPanel instance
*/
public JPanel getPanel()
{
return panel;
}
/**
* input changed in slider.
*
* @param changeEvent the event of the change
*/
@Override
public void stateChanged(ChangeEvent changeEvent)
{
int value = slider.getValue();
tintValue = getFloatRepresentation(value);
tintField.setText(Float.toString(tintValue));
try
{
updateColorBar();
}
catch (IOException ex)
{
tintField.setText(ex.getMessage());
}
}
/**
* input changed in text field.
*
* @param actionEvent the event of the action
*/
@Override
public void actionPerformed(ActionEvent actionEvent)
{
String input = tintField.getText();
try
{
tintValue= Float.parseFloat(input);
slider.setValue(getIntRepresentation(tintValue));
updateColorBar();
}
catch (NumberFormatException e)
{
tintField.setText(Float.toString(tintValue));
}
catch (IOException ex)
{
tintField.setText(ex.getMessage());
}
}
private void updateColorBar() throws IOException
{
float[] rgbValues = separation.toRGB(new float[] {tintValue});
colorBar.setBackground(new Color(rgbValues[0], rgbValues[1], rgbValues[2]));
}
/**
* Set a little border around colorbar. color of the border is the darkest of the colorant.
*/
private void setColorBarBorder() throws IOException
{
float[] rgbValues = separation.toRGB(new float[] {1});
Color darkest= new Color(rgbValues[0], rgbValues[1], rgbValues[2]);
colorBar.setBorder(new BevelBorder(BevelBorder.LOWERED, darkest, darkest));
}
private float getFloatRepresentation(int value)
{
return (float) value/100;
}
private int getIntRepresentation(float value)
{
return (int) (value*100);
}
}