/*
* Licensed Materials - Property of Perforce Software, Inc.
* © Copyright Perforce Software, Inc. 2014, 2021
* © Copyright IBM Corp. 2009, 2014
* © Copyright ILOG 1996, 2009
* All Rights Reserved.
*
* Note to U.S. Government Users Restricted Rights:
* The Software and Documentation were developed at private expense and
* are "Commercial Items" as that term is defined at 48 CFR 2.101,
* consisting of "Commercial Computer Software" and
* "Commercial Computer Software Documentation", as such terms are
* used in 48 CFR 12.212 or 48 CFR 227.7202-1 through 227.7202-4,
* as applicable.
*/
package shared.swing;
import ilog.views.util.styling.IlvStylable;
import ilog.views.util.swing.IlvSwingUtil;
import shared.AbstractExample;
import shared.Util;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;
/**
* <code>CSSComboBox</code> is a Swing combination box that allows the user to
* select a style sheet for a stylable chart.
*/
public class CSSComboBox extends JComboBox<String> {
/**
* The stylable chart.
*/
private IlvStylable chart;
/**
* The example that this combination box is associated with.
*/
private AbstractExample example;
/**
* The name of the data directory containing the CSS files.
*/
private String dataDirectory;
/**
* The list of sample CSS file names to use when the example is running as an
* applet. The files do not specify any path or extension. The files are
* assumed to be located in <code>dataDirectory</code> and have an extension
* of ".css".
*/
private String[] appletCSSFiles;
/**
* The list of CSS file names displayed by the combination box. The files do
* not specify any path and are assumed to be located in
* <code>dataDirectory</code>.
* The first element of the list is special and is used to indicate that
* styling should be disabled.
*/
private List<String> cssFileNames;
/**
* The list of URLs for each CSS file displayed by the combination box. This list
* parallels the <code>cssFileNames</code> list. The value of the first
* element is <code>null</code> and is used to indicate that styling should be
* disabled.
*/
private List<URL> cssFileURLs;
/**
* Creates a new <code>CSSComboBox</code> for the specified example.
*
* @param example The example that the combination box is associated with.
* @param chart The chart.
* @param dataDirectory The name of the data directory containing the CSS
* files.
* @param appletCSSFiles The list of sample CSS file names to use when the
* example is running as an applet. The files should be specified without any
* path or extension. The files are assumed to be located in
* <code>dataDirectory</code> and have an extension of ".css".
*/
public CSSComboBox(AbstractExample example,
IlvStylable chart,
String dataDirectory,
String[] appletCSSFiles) {
this.chart = chart;
this.example = example;
this.dataDirectory = dataDirectory;
this.appletCSSFiles = appletCSSFiles;
// Compute the list of available CSS files and their URLs. Then prepend the
// special item at index 0 to disable styling.
cssFileNames = new ArrayList<String>();
cssFileURLs = new ArrayList<URL>();
getCSSFiles(cssFileNames, cssFileURLs);
cssFileNames.add(0, "Default Style");
cssFileURLs.add(0, null);
// Set the list of CSS file names as the model of the combination box.
setModel(new DefaultComboBoxModel<String>(cssFileNames.toArray(new String[cssFileNames.size()])));
// Add the listener that will set the style sheet on the chart when a
// CSS file is selected in the combination box.
addActionListener(new ActionListener() {
Override
public void actionPerformed(ActionEvent evt) {
int idx = getSelectedIndex();
try {
if (idx <= 0) {
getChart().setStyleSheets(null);
} else {
URL cssURL = (URL) cssFileURLs.get(idx);
getChart().setStyleSheets(0, cssURL.toString());
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
// Initially select that styling is disabled.
setSelectedIndex(0);
}
/**
* Returns the chart.
*
* @return The chart.
*/
protected IlvStylable getChart() {
return chart;
}
/**
* Computes the list of available CSS files and their corresponding URLs.
*/
private void getCSSFiles(List<String> files, List<URL> urls) {
// In an application context, first list all CSS files in the data directory.
File[] css = Util.listDirectory(dataDirectory, "css");
for (int i = 0; i < css.length; i++) {
String fileName = css[i].getName();
try {
URL url = getDataFileURL(fileName);
files.add(fileName);
urls.add(url);
} catch (IOException ex) {
// Theoretically, there should be no problem accessing the URL of a file that
// we just listed from the data directory. So, we ignore any such problem files.
}
}
// Then add any CSS files that might be bundled into the applet or application jar.
// If a jar'd file duplicates one from the external file system, the external file
// takes precedence.
for (int i = 0; i < appletCSSFiles.length; i++) {
String fileName = appletCSSFiles[i] + ".css";
if (!files.contains(fileName)) {
try {
URL url = getDataFileURL(fileName);
files.add(fileName);
urls.add(url);
} catch (IOException ex) {
// In an applet context, the list of applet files is required.
IlvSwingUtil.showErrorDialog(this, ex);
}
}
}
}
/**
* Returns the URL of the specified data file.
*/
private URL getDataFileURL(String fileName)
throws IOException {
String file = dataDirectory + File.separator + fileName;
return example.getResourceURL(file);
}
}