/* * Copyright 2013 Cenote GmbH. * * Licensed 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 de.cenote.jasperstarter.gui; import java.awt.Component; import java.awt.Dialog; import java.awt.Dimension; import java.awt.Frame; import java.awt.KeyboardFocusManager; import java.awt.Rectangle; import java.awt.Window; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.Map; import java.util.concurrent.atomic.AtomicBoolean; import javax.swing.BorderFactory; import javax.swing.BoxLayout; import javax.swing.JComponent; import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import net.sf.jasperreports.engine.JRParameter; /** * * @author Volker Voßkämper <vvo at cenote.de> * @version $Revision$ */ public class ParameterPrompt { Component parent; JRParameter[] jrParameters; Map params; JScrollPane scrollPane; String reportName; AtomicBoolean valid = new AtomicBoolean(); public ParameterPrompt(Component parent, JRParameter[] jrParameters, Map<String, Object> params, String reportName, boolean isForPromptingOnly, boolean isUserDefinedOnly, boolean emptyOnly) { this.valid.set(true); this.parent = parent; this.jrParameters = jrParameters; this.params = params; this.reportName = reportName; final JPanel panel = new JPanel(); panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS)); scrollPane = new JScrollPane(panel); scrollPane.setPreferredSize(new Dimension(600, 250)); for (JRParameter param : jrParameters) { if (!param.isSystemDefined() || !isUserDefinedOnly) { if (param.isForPrompting() || !isForPromptingOnly) { if (params.get(param.getName()) == null || !emptyOnly) { panel.add(new ParameterPanel(param, params, this.valid)); } } } } panel.add(new javax.swing.JSeparator()); // let the focus scroll the scrollPane KeyboardFocusManager.getCurrentKeyboardFocusManager(). addPropertyChangeListener( "focusOwner", new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) { if (!(evt.getNewValue() instanceof JComponent)) { return; } JComponent focused = (JComponent) evt.getNewValue(); if (panel.isAncestorOf(focused)) { JComponent myComponent = (JComponent) focused.getParent().getParent(); myComponent.scrollRectToVisible(new Rectangle(0, 0, 0, 80)); } } }); } public int show() { final JOptionPane optionPane = new JOptionPane(scrollPane, JOptionPane.PLAIN_MESSAGE, JOptionPane.OK_CANCEL_OPTION); final JDialog dialog; JFrame frame = new JFrame(); if (parent == null) { // use a dummy frame to have it on taskbar frame.setTitle("JasperStarter - Parameter Prompt: " + reportName); frame.setUndecorated(true); // (invisible) frame.setLocationRelativeTo(null); frame.setVisible(true); dialog = new JDialog(frame); } else if (parent instanceof Window) { dialog = new JDialog((Window) parent); } else if (parent instanceof Frame) { dialog = new JDialog((Frame) parent); } else if (parent instanceof Dialog) { dialog = new JDialog((Dialog) parent); } else { dialog = new JDialog(); } dialog.setTitle("JasperStarter - Parameter Prompt: " + reportName); dialog.setContentPane(optionPane); dialog.setModalityType(Dialog.ModalityType.APPLICATION_MODAL); dialog.setDefaultCloseOperation( JDialog.DO_NOTHING_ON_CLOSE); // set the size to have the dialog properly centered dialog.setSize(636, 344); dialog.setLocationRelativeTo(parent); dialog.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent we) { // trigger a PropertyChangeEvent optionPane.setValue(new Integer( JOptionPane.CANCEL_OPTION)); } }); optionPane.addPropertyChangeListener( new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent e) { String prop = e.getPropertyName(); if (dialog.isVisible() && (e.getSource() == optionPane) && (prop.equals(JOptionPane.VALUE_PROPERTY))) { //If you were going to check something //before closing the window, you'd do //it here. if (valid.get() | ((Integer) optionPane.getValue()) .intValue() == JOptionPane.CANCEL_OPTION) { // cancel is possible on invalid options too dialog.setVisible(false); } else { // reset to an unused option so next click on the // same button triggers PropertyChangeEvent again optionPane.setValue(new Integer(JOptionPane.NO_OPTION)); } } } }); dialog.pack(); dialog.setVisible(true); int retval = ((Integer) optionPane.getValue()).intValue(); dialog.dispose(); frame.dispose(); return retval; } }