/* * 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); } }