| /* |
| |
| 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.batik.util.gui; |
| |
| import java.awt.BorderLayout; |
| import java.awt.Component; |
| import java.awt.FlowLayout; |
| import java.awt.GridBagConstraints; |
| import java.awt.GridBagLayout; |
| import java.awt.Insets; |
| import java.awt.event.ActionEvent; |
| import java.util.ArrayList; |
| import java.util.Enumeration; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Locale; |
| import java.util.Map; |
| import java.util.ResourceBundle; |
| import java.util.StringTokenizer; |
| |
| import javax.swing.AbstractAction; |
| import javax.swing.Action; |
| import javax.swing.BorderFactory; |
| import javax.swing.DefaultListModel; |
| import javax.swing.JButton; |
| import javax.swing.JComboBox; |
| import javax.swing.JDialog; |
| import javax.swing.JLabel; |
| import javax.swing.JList; |
| import javax.swing.JOptionPane; |
| import javax.swing.JPanel; |
| import javax.swing.JScrollPane; |
| import javax.swing.ListSelectionModel; |
| import javax.swing.event.ListDataEvent; |
| import javax.swing.event.ListDataListener; |
| import javax.swing.event.ListSelectionEvent; |
| import javax.swing.event.ListSelectionListener; |
| |
| import org.apache.batik.util.gui.resource.ActionMap; |
| import org.apache.batik.util.gui.resource.ButtonFactory; |
| import org.apache.batik.util.gui.resource.MissingListenerException; |
| import org.apache.batik.util.resources.ResourceManager; |
| |
| /** |
| * This class represents a panel to edit/add/remove CSS media. |
| * |
| * @author <a href="mailto:tkormann@apache.org">Thierry Kormann</a> |
| * @version $Id$ |
| */ |
| public class CSSMediaPanel extends JPanel implements ActionMap { |
| |
| /** |
| * The resource file name |
| */ |
| protected static final String RESOURCES = |
| "org.apache.batik.util.gui.resources.CSSMediaPanel"; |
| |
| /** |
| * The resource bundle |
| */ |
| protected static ResourceBundle bundle; |
| |
| /** |
| * The resource manager |
| */ |
| protected static ResourceManager resources; |
| |
| static { |
| bundle = ResourceBundle.getBundle(RESOURCES, Locale.getDefault()); |
| resources = new ResourceManager(bundle); |
| } |
| |
| /** |
| * The button to remove a CSS medium from the list. |
| */ |
| protected JButton removeButton; |
| |
| /** |
| * The button to add a CSS medium from the list. |
| */ |
| protected JButton addButton; |
| |
| /** |
| * The button to clear the CSS media list. |
| */ |
| protected JButton clearButton; |
| |
| /** |
| * The list that represents the CSS media. |
| */ |
| protected DefaultListModel listModel = new DefaultListModel(); |
| |
| /** |
| * The list that represents the CSS media. |
| */ |
| protected JList mediaList; |
| |
| /** |
| * Constructs a new panel to edit CSS media. |
| */ |
| public CSSMediaPanel() { |
| super(new GridBagLayout()); |
| |
| listeners.put("AddButtonAction", new AddButtonAction()); |
| listeners.put("RemoveButtonAction", new RemoveButtonAction()); |
| listeners.put("ClearButtonAction", new ClearButtonAction()); |
| |
| setBorder(BorderFactory.createTitledBorder |
| (BorderFactory.createEtchedBorder(), |
| resources.getString("Panel.title"))); |
| |
| ExtendedGridBagConstraints constraints = |
| new ExtendedGridBagConstraints(); |
| |
| constraints.insets = new Insets(5, 5, 5, 5); |
| |
| mediaList = new JList(); |
| mediaList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); |
| mediaList.setModel(listModel); |
| mediaList.addListSelectionListener(new MediaListSelectionListener()); |
| listModel.addListDataListener(new MediaListDataListener()); |
| |
| JScrollPane scrollPane = new JScrollPane(); |
| scrollPane.setBorder(BorderFactory.createLoweredBevelBorder()); |
| constraints.weightx = 1.0; |
| constraints.weighty = 1.0; |
| constraints.fill = GridBagConstraints.BOTH; |
| constraints.setGridBounds(0, 0, 1, 3); |
| scrollPane.getViewport().add(mediaList); |
| add(scrollPane, constraints); |
| |
| ButtonFactory bf = new ButtonFactory(bundle, this); |
| constraints.weightx = 0; |
| constraints.weighty = 0; |
| constraints.fill = GridBagConstraints.HORIZONTAL; |
| constraints.anchor = GridBagConstraints.NORTH; |
| |
| addButton = bf.createJButton("AddButton"); |
| constraints.setGridBounds(1, 0, 1, 1); |
| add(addButton, constraints); |
| |
| removeButton = bf.createJButton("RemoveButton"); |
| constraints.setGridBounds(1, 1, 1, 1); |
| add(removeButton, constraints); |
| |
| clearButton = bf.createJButton("ClearButton"); |
| constraints.setGridBounds(1, 2, 1, 1); |
| add(clearButton, constraints); |
| |
| updateButtons(); |
| } |
| |
| /** |
| * Updates the button states. |
| */ |
| protected void updateButtons() { |
| removeButton.setEnabled(!mediaList.isSelectionEmpty()); |
| clearButton.setEnabled(!listModel.isEmpty()); |
| } |
| |
| /** |
| * Sets the list of media to edit. |
| * |
| * @param mediaList the list of media to edit |
| */ |
| public void setMedia(List mediaList) { |
| listModel.removeAllElements(); |
| for (Object aMediaList : mediaList) { |
| listModel.addElement(aMediaList); |
| } |
| } |
| |
| /** |
| * Sets the list of media to edit to the specified media list (separated by |
| * space). |
| * |
| * @param media the media separated by space |
| */ |
| public void setMedia(String media) { |
| listModel.removeAllElements(); |
| StringTokenizer tokens = new StringTokenizer(media, " "); |
| while (tokens.hasMoreTokens()) { |
| listModel.addElement(tokens.nextToken()); |
| } |
| } |
| |
| /** |
| * Returns the list of media. |
| */ |
| public List getMedia() { |
| List media = new ArrayList(listModel.size()); |
| Enumeration e = listModel.elements(); |
| while (e.hasMoreElements()) { |
| media.add(e.nextElement()); |
| } |
| return media; |
| } |
| |
| /** |
| * Returns the media list as a string separated by space. |
| */ |
| public String getMediaAsString() { |
| StringBuffer buffer = new StringBuffer(); |
| Enumeration e = listModel.elements(); |
| while (e.hasMoreElements()) { |
| buffer.append((String)e.nextElement()); |
| buffer.append( ' ' ); |
| } |
| return buffer.toString(); |
| } |
| |
| /** |
| * Brings up a modal dialog to edit/add/remove CSS media. |
| * |
| * @param parent the parent of this dialog |
| * @param title the title of this dialog |
| */ |
| public static int showDialog(Component parent, String title) { |
| return showDialog(parent, title, ""); |
| } |
| |
| /** |
| * Brings up a modal dialog to edit/add/remove CSS media. |
| * |
| * @param parent the parent of this dialog |
| * @param title the title of this dialog |
| * @param mediaList the list of media |
| */ |
| public static int showDialog(Component parent, |
| String title, |
| List mediaList) { |
| Dialog dialog = new Dialog(parent, title, mediaList); |
| dialog.setModal(true); |
| dialog.pack(); |
| dialog.setVisible(true); |
| return dialog.getReturnCode(); |
| } |
| |
| /** |
| * Brings up a modal dialog to edit/add/remove CSS media. |
| * |
| * @param parent the parent of this dialog |
| * @param title the title of this dialog |
| * @param media the list of media |
| */ |
| public static int showDialog(Component parent, |
| String title, |
| String media) { |
| Dialog dialog = new Dialog(parent, title, media); |
| dialog.setModal(true); |
| dialog.pack(); |
| dialog.setVisible(true); |
| return dialog.getReturnCode(); |
| } |
| |
| /** |
| * The map that contains the listeners |
| */ |
| protected Map listeners = new HashMap(); |
| |
| /** |
| * Returns the action associated with the given string or null on error |
| * |
| * @param key the key mapped with the action to get |
| * @throws MissingListenerException if the action is not found |
| */ |
| public Action getAction(String key) throws MissingListenerException { |
| return (Action)listeners.get(key); |
| } |
| |
| /** |
| * The action associated with the 'Add' button |
| */ |
| protected class AddButtonAction extends AbstractAction { |
| public void actionPerformed(ActionEvent e) { |
| AddMediumDialog dialog = new AddMediumDialog(CSSMediaPanel.this); |
| dialog.pack(); |
| dialog.setVisible(true); |
| |
| if ((dialog.getReturnCode() == AddMediumDialog.CANCEL_OPTION) || |
| (dialog.getMedium() == null)) { |
| return; |
| } |
| |
| String medium = dialog.getMedium().trim(); |
| if (medium.length() == 0 || listModel.contains(medium)) { |
| return; |
| } |
| |
| for (int i = 0; i < listModel.size() && medium != null; ++i) { |
| String s = (String)listModel.getElementAt(i); |
| int c = medium.compareTo(s); |
| if (c == 0) { |
| medium = null; |
| } else if (c < 0) { |
| listModel.insertElementAt(medium, i); |
| medium = null; |
| } |
| } |
| if (medium != null) { |
| listModel.addElement(medium); |
| } |
| } |
| } |
| |
| /** |
| * The action associated with the 'Remove' button |
| */ |
| protected class RemoveButtonAction extends AbstractAction { |
| public void actionPerformed(ActionEvent e) { |
| int index = mediaList.getSelectedIndex(); |
| mediaList.clearSelection(); |
| if (index >= 0) { |
| listModel.removeElementAt(index); |
| } |
| } |
| } |
| |
| /** |
| * The action associated with the 'Clear' button |
| */ |
| protected class ClearButtonAction extends AbstractAction { |
| public void actionPerformed(ActionEvent e) { |
| mediaList.clearSelection(); |
| listModel.removeAllElements(); |
| } |
| } |
| |
| /** |
| * To manage selection modifications |
| */ |
| protected class MediaListSelectionListener |
| implements ListSelectionListener { |
| |
| public void valueChanged(ListSelectionEvent e) { |
| updateButtons(); |
| } |
| } |
| |
| /** |
| * To manage data modifications in the media list. |
| */ |
| protected class MediaListDataListener implements ListDataListener { |
| |
| public void contentsChanged(ListDataEvent e) { |
| updateButtons(); |
| } |
| |
| public void intervalAdded(ListDataEvent e) { |
| updateButtons(); |
| } |
| |
| public void intervalRemoved(ListDataEvent e) { |
| updateButtons(); |
| } |
| } |
| |
| /////////////////////////////////////////////////////////////////////////// |
| |
| /** |
| * A dialog to add a new CSS medium. |
| */ |
| public static class AddMediumDialog extends JDialog implements ActionMap { |
| |
| /** |
| * The return value if 'OK' is chosen. |
| */ |
| public static final int OK_OPTION = 0; |
| |
| /** |
| * The return value if 'Cancel' is chosen. |
| */ |
| public static final int CANCEL_OPTION = 1; |
| |
| /** |
| * The new medium. |
| */ |
| protected JComboBox medium; |
| |
| /** |
| * The return code. |
| */ |
| protected int returnCode; |
| |
| /** |
| * Constructs a new AddMediumDialog. |
| * |
| * @param parent the parent of this dialog |
| */ |
| public AddMediumDialog(Component parent) { |
| super(JOptionPane.getFrameForComponent(parent), |
| resources.getString("AddMediumDialog.title")); |
| setModal(true); |
| |
| listeners.put("OKButtonAction", new OKButtonAction()); |
| listeners.put("CancelButtonAction", new CancelButtonAction()); |
| |
| getContentPane().add(createContentPanel(), BorderLayout.CENTER); |
| getContentPane().add(createButtonsPanel(), BorderLayout.SOUTH); |
| } |
| |
| /** |
| * Returns the medium that might be added or null if any. |
| */ |
| public String getMedium() { |
| return (String)medium.getSelectedItem(); |
| } |
| |
| /** |
| * Returns the panel to enter a new CSS medium. |
| */ |
| protected Component createContentPanel() { |
| JPanel panel = new JPanel(new BorderLayout()); |
| panel.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4)); |
| panel.add(new JLabel(resources.getString("AddMediumDialog.label")), |
| BorderLayout.WEST); |
| |
| medium = new JComboBox(); |
| medium.setEditable(true); |
| String media = resources.getString("Media.list"); |
| StringTokenizer tokens = new StringTokenizer(media, " "); |
| while (tokens.hasMoreTokens()) { |
| medium.addItem(tokens.nextToken()); |
| } |
| panel.add(medium, BorderLayout.CENTER); |
| return panel; |
| } |
| |
| /** |
| * Returns the button panel. |
| */ |
| protected Component createButtonsPanel() { |
| JPanel panel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); |
| ButtonFactory bf = new ButtonFactory(bundle, this); |
| panel.add(bf.createJButton("OKButton")); |
| panel.add(bf.createJButton("CancelButton")); |
| return panel; |
| } |
| |
| /** |
| * Returns the code that describes how the dialog has been closed (OK or |
| * CANCEL). |
| */ |
| public int getReturnCode() { |
| return returnCode; |
| } |
| |
| /** |
| * The map that contains the listeners |
| */ |
| protected Map listeners = new HashMap(); |
| |
| /** |
| * Returns the action associated with the given string or null on error |
| * |
| * @param key the key mapped with the action to get |
| * @throws MissingListenerException if the action is not found |
| */ |
| public Action getAction(String key) throws MissingListenerException { |
| return (Action)listeners.get(key); |
| } |
| |
| /** |
| * The action associated with the 'OK' button |
| */ |
| protected class OKButtonAction extends AbstractAction { |
| public void actionPerformed(ActionEvent e) { |
| returnCode = OK_OPTION; |
| dispose(); |
| } |
| } |
| |
| /** |
| * The action associated with the 'Cancel' button |
| */ |
| protected class CancelButtonAction extends AbstractAction { |
| public void actionPerformed(ActionEvent e) { |
| returnCode = CANCEL_OPTION; |
| dispose(); |
| } |
| } |
| } |
| |
| /////////////////////////////////////////////////////////////////////////// |
| |
| /** |
| * A dialog to edit/add/remove CSS media. |
| */ |
| public static class Dialog extends JDialog implements ActionMap { |
| |
| /** |
| * The return value if 'OK' is chosen. |
| */ |
| public static final int OK_OPTION = 0; |
| |
| /** |
| * The return value if 'Cancel' is chosen. |
| */ |
| public static final int CANCEL_OPTION = 1; |
| |
| /** |
| * The return code. |
| */ |
| protected int returnCode; |
| |
| /** |
| * Constructs a new Dialog to edit/add/remove CSS media. |
| */ |
| public Dialog() { |
| this(null, "", ""); |
| } |
| |
| /** |
| * Constructs a new Dialog to edit/add/remove CSS media. |
| * |
| * @param parent the parent of this dialog |
| * @param title the title of this dialog |
| * @param mediaList the media list |
| */ |
| public Dialog(Component parent, String title, List mediaList) { |
| super(JOptionPane.getFrameForComponent(parent), title); |
| |
| listeners.put("OKButtonAction", new OKButtonAction()); |
| listeners.put("CancelButtonAction", new CancelButtonAction()); |
| |
| CSSMediaPanel panel = new CSSMediaPanel(); |
| panel.setMedia(mediaList); |
| getContentPane().add(panel, BorderLayout.CENTER); |
| getContentPane().add(createButtonsPanel(), BorderLayout.SOUTH); |
| } |
| |
| /** |
| * Constructs a new Dialog to edit/add/remove CSS media. |
| * |
| * @param parent the parent of this dialog |
| * @param title the title of this dialog |
| * @param media the media list |
| */ |
| public Dialog(Component parent, String title, String media) { |
| super(JOptionPane.getFrameForComponent(parent), title); |
| |
| listeners.put("OKButtonAction", new OKButtonAction()); |
| listeners.put("CancelButtonAction", new CancelButtonAction()); |
| |
| CSSMediaPanel panel = new CSSMediaPanel(); |
| panel.setMedia(media); |
| getContentPane().add(panel, BorderLayout.CENTER); |
| getContentPane().add(createButtonsPanel(), BorderLayout.SOUTH); |
| } |
| |
| /** |
| * Returns the code that describes how the dialog has been closed (OK or |
| * CANCEL). |
| */ |
| public int getReturnCode() { |
| return returnCode; |
| } |
| |
| /** |
| * Creates the OK/Cancel buttons panel |
| */ |
| protected JPanel createButtonsPanel() { |
| JPanel p = new JPanel(new FlowLayout(FlowLayout.RIGHT)); |
| ButtonFactory bf = new ButtonFactory(bundle, this); |
| p.add(bf.createJButton("OKButton")); |
| p.add(bf.createJButton("CancelButton")); |
| return p; |
| } |
| |
| /** |
| * The map that contains the listeners |
| */ |
| protected Map listeners = new HashMap(); |
| |
| /** |
| * Returns the action associated with the given string or null on error |
| * |
| * @param key the key mapped with the action to get |
| * @throws MissingListenerException if the action is not found |
| */ |
| public Action getAction(String key) throws MissingListenerException { |
| return (Action)listeners.get(key); |
| } |
| |
| /** |
| * The action associated with the 'OK' button |
| */ |
| protected class OKButtonAction extends AbstractAction { |
| public void actionPerformed(ActionEvent e) { |
| returnCode = OK_OPTION; |
| dispose(); |
| } |
| } |
| |
| /** |
| * The action associated with the 'Cancel' button |
| */ |
| protected class CancelButtonAction extends AbstractAction { |
| public void actionPerformed(ActionEvent e) { |
| returnCode = CANCEL_OPTION; |
| dispose(); |
| } |
| } |
| } |
| |
| /** |
| * Main - debug - |
| */ |
| public static void main(String [] args) { |
| String media = "all aural braille embossed handheld print projection screen tty tv"; |
| int code = CSSMediaPanel.showDialog(null, "Test", media); |
| System.out.println(code); |
| System.exit(0); |
| } |
| } |