/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Lesser General Public License for more details. * * Copyright (c) 2001 - 2013 Object Refinery Ltd, Pentaho Corporation and Contributors.. All rights reserved. */ package org.pentaho.reporting.engine.classic.core.modules.gui.base.internal; import java.awt.Component; import java.awt.Dialog; import java.awt.FlowLayout; import java.awt.Frame; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.GridLayout; import java.awt.Window; import java.awt.event.ActionEvent; import java.awt.event.KeyEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.util.ResourceBundle; import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.BorderFactory; import javax.swing.Icon; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JDialog; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JSlider; import javax.swing.JTextField; import javax.swing.KeyStroke; import javax.swing.SwingConstants; import javax.swing.UIManager; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import org.pentaho.reporting.engine.classic.core.modules.gui.commonswing.FormValidator; import org.pentaho.reporting.engine.classic.core.modules.gui.commonswing.NumericDocument; import org.pentaho.reporting.engine.classic.core.modules.gui.commonswing.SwingCommonModule; import org.pentaho.reporting.libraries.designtime.swing.LibSwingUtil; /** * Creation-Date: 29.10.2007, 18:36:13 * * @author Thomas Morgner */ public class NumericInputDialog extends JDialog { private class SyncValuesHandler implements DocumentListener, ChangeListener { private boolean inStateChange; private SyncValuesHandler() { } public void insertUpdate( final DocumentEvent e ) { if ( inStateChange ) { return; } inStateChange = true; try { final Integer i = getInputValue(); if ( i != null ) { valueSlider.setValue( i.intValue() ); valueMessage.setText( String.valueOf( i ) ); } } finally { inStateChange = false; } } public void removeUpdate( final DocumentEvent e ) { if ( inStateChange ) { return; } inStateChange = true; try { final Integer i = getInputValue(); if ( i != null ) { valueSlider.setValue( i.intValue() ); valueMessage.setText( String.valueOf( i ) ); } } finally { inStateChange = false; } } public void changedUpdate( final DocumentEvent e ) { if ( inStateChange ) { return; } inStateChange = true; try { final Integer i = getInputValue(); if ( i != null ) { valueSlider.setValue( i.intValue() ); valueMessage.setText( String.valueOf( i ) ); } } finally { inStateChange = false; } } public void stateChanged( final ChangeEvent e ) { if ( inStateChange ) { return; } inStateChange = true; try { final String text = String.valueOf( valueSlider.getValue() ); textField.setText( text ); valueMessage.setText( text ); } finally { inStateChange = false; } } } /** * Internal action class to confirm the dialog and to validate the input. */ private class ConfirmAction extends AbstractAction { /** * Default constructor. */ protected ConfirmAction( final ResourceBundle resources ) { putValue( Action.NAME, resources.getString( "OptionPane.okButtonText" ) ); //$NON-NLS-1$ } /** * Receives notification that the action has occurred. * * @param e * the action event. */ public void actionPerformed( final ActionEvent e ) { if ( performValidate() ) { setConfirmed( true ); setVisible( false ); } } } /** * Internal action class to cancel the report processing. */ private class CancelAction extends AbstractAction { /** * Default constructor. */ protected CancelAction( final ResourceBundle resources ) { putValue( Action.NAME, resources.getString( "OptionPane.cancelButtonText" ) ); //$NON-NLS-1$ putValue( Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke( KeyEvent.VK_ESCAPE, 0 ) ); } /** * Receives notification that the action has occurred. * * @param e * the action event. */ public void actionPerformed( final ActionEvent e ) { setConfirmed( false ); setVisible( false ); } } private class DialogValidator extends FormValidator { protected DialogValidator() { } public boolean performValidate() { return NumericInputDialog.this.performValidate(); } public Action getConfirmAction() { return NumericInputDialog.this.getConfirmAction(); } } private class WindowCloseHandler extends WindowAdapter { protected WindowCloseHandler() { } /** * Invoked when a window is in the process of being closed. The close operation can be overridden at this point. */ public void windowClosing( final WindowEvent e ) { final Action cancelAction = getCancelAction(); if ( cancelAction != null ) { cancelAction.actionPerformed( null ); } else { setConfirmed( false ); setVisible( false ); } } } private Action cancelAction; private Action confirmAction; private boolean boundedRange; private JLabel icon; private JLabel message; private JLabel valueMessage; private JSlider valueSlider; private JTextField textField; private boolean confirmed; private FormValidator formValidator; public NumericInputDialog() { initialize(); } public NumericInputDialog( final Frame owner ) { super( owner ); initialize(); } public NumericInputDialog( final Frame owner, final boolean modal ) { super( owner, modal ); initialize(); } public NumericInputDialog( final Frame owner, final String title ) { super( owner, title ); initialize(); } public NumericInputDialog( final Dialog owner ) { super( owner ); initialize(); } public NumericInputDialog( final Dialog owner, final boolean modal ) { super( owner, modal ); initialize(); } public NumericInputDialog( final Dialog owner, final String title ) { super( owner, title ); initialize(); } public NumericInputDialog( final Frame owner, final String title, final boolean modal ) { super( owner, title, modal ); initialize(); } public NumericInputDialog( final Dialog owner, final String title, final boolean modal ) { super( owner, title, modal ); initialize(); } private void initialize() { final ResourceBundle resources = ResourceBundle.getBundle( SwingCommonModule.BUNDLE_NAME ); setDefaultCloseOperation( JDialog.DISPOSE_ON_CLOSE ); addWindowListener( new WindowCloseHandler() ); cancelAction = new CancelAction( resources ); confirmAction = new ConfirmAction( resources ); final SyncValuesHandler syncValuesHandler = new SyncValuesHandler(); message = new JLabel(); icon = new JLabel(); icon.setVisible( false ); icon.setBorder( BorderFactory.createEmptyBorder( 0, 0, 0, 5 ) ); valueMessage = new JLabel(); valueMessage.setVisible( false ); valueSlider = new JSlider(); textField = new JTextField(); textField.setDocument( new NumericDocument() ); textField.setColumns( 10 ); textField.setHorizontalAlignment( SwingConstants.TRAILING ); textField.getDocument().addDocumentListener( syncValuesHandler ); valueSlider.addChangeListener( syncValuesHandler ); final JPanel contentPane = new JPanel(); contentPane.setLayout( new GridBagLayout() ); contentPane.setBorder( BorderFactory.createEmptyBorder( 5, 5, 5, 5 ) ); GridBagConstraints gbc = new GridBagConstraints(); gbc.gridx = 0; gbc.gridy = 0; gbc.gridheight = 5; gbc.gridwidth = 1; gbc.anchor = GridBagConstraints.CENTER; contentPane.add( icon, gbc ); gbc = new GridBagConstraints(); gbc.gridx = 1; gbc.gridy = 0; gbc.gridheight = 1; gbc.gridwidth = 1; gbc.fill = GridBagConstraints.HORIZONTAL; contentPane.add( message, gbc ); gbc = new GridBagConstraints(); gbc.gridx = 1; gbc.gridy = 1; gbc.gridheight = 1; gbc.gridwidth = 1; gbc.fill = GridBagConstraints.HORIZONTAL; contentPane.add( valueSlider, gbc ); gbc = new GridBagConstraints(); gbc.gridx = 1; gbc.gridy = 2; gbc.gridheight = 1; gbc.gridwidth = 1; gbc.fill = GridBagConstraints.HORIZONTAL; contentPane.add( textField, gbc ); gbc = new GridBagConstraints(); gbc.gridx = 1; gbc.gridy = 3; gbc.gridheight = 1; gbc.gridwidth = 1; gbc.anchor = GridBagConstraints.EAST; contentPane.add( valueMessage, gbc ); gbc = new GridBagConstraints(); gbc.gridx = 1; gbc.gridy = 4; gbc.gridheight = 1; gbc.gridwidth = 1; contentPane.add( createButtonPanel(), gbc ); formValidator = new DialogValidator(); formValidator.setEnabled( true ); formValidator.registerTextField( textField ); setContentPane( contentPane ); } private JPanel createButtonPanel() { final JButton btnCancel = new JButton( getCancelAction() ); final JButton btnConfirm = new JButton( getConfirmAction() ); final JPanel buttonPanel = new JPanel(); buttonPanel.setLayout( new GridLayout( 1, 2, 5, 5 ) ); buttonPanel.add( btnConfirm ); buttonPanel.add( btnCancel ); btnConfirm.setDefaultCapable( true ); getRootPane().setDefaultButton( btnConfirm ); buttonPanel.registerKeyboardAction( getConfirmAction(), KeyStroke.getKeyStroke( KeyEvent.VK_ENTER, 0 ), JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT ); final JPanel buttonCarrier = new JPanel(); buttonCarrier.setLayout( new FlowLayout( FlowLayout.RIGHT ) ); buttonCarrier.add( buttonPanel ); return buttonCarrier; } public boolean getPaintTicks() { return valueSlider.getPaintTicks(); } public void setPaintTicks( final boolean b ) { valueSlider.setPaintTicks( b ); } public void setSnapToTicks( final boolean b ) { valueSlider.setSnapToTicks( b ); } public boolean getSnapToTicks() { return valueSlider.getSnapToTicks(); } public Action getCancelAction() { return cancelAction; } public Action getConfirmAction() { return confirmAction; } public void setIcon( final Icon icon ) { this.icon.setIcon( icon ); this.icon.setVisible( icon != null ); } public Icon getIcon() { return icon.getIcon(); } public String getMessage() { return message.getText(); } public void setMessage( final String message ) { this.message.setText( message ); } public int getSliderValue() { return valueSlider.getValue(); } public void setSliderValue( final int n ) { valueSlider.setValue( n ); } public int getMinimum() { return valueSlider.getMinimum(); } public void setMinimum( final int minimum ) { valueSlider.setMinimum( minimum ); } public int getMaximum() { return valueSlider.getMaximum(); } public void setMaximum( final int maximum ) { valueSlider.setMaximum( maximum ); } public boolean isConfirmed() { return confirmed; } public void setConfirmed( final boolean confirmed ) { this.confirmed = confirmed; } protected boolean performValidate() { final Integer value = getInputValue(); if ( value == null ) { return false; } if ( isBoundedRange() == false ) { return true; } final int iVal = value.intValue(); if ( iVal < valueSlider.getMinimum() || iVal > valueSlider.getMaximum() ) { return false; } return true; } public void setInputValue( final Integer value ) { if ( value == null ) { textField.setText( "" ); } else { textField.setText( String.valueOf( value ) ); } } public Integer getInputValue() { try { return new Integer( textField.getText() ); } catch ( NumberFormatException nfe ) { return null; } } public boolean isBoundedRange() { return boundedRange; } public void setBoundedRange( final boolean boundedRange ) { this.boundedRange = boundedRange; } public boolean isSliderVisible() { return valueSlider.isVisible(); } public void setSliderVisible( final boolean b ) { valueSlider.setVisible( b ); } public boolean isTextInputVisible() { return textField.isVisible(); } public void setTextInputVisible( final boolean b ) { textField.setVisible( b ); valueMessage.setVisible( !b ); } private static NumericInputDialog createDialog( final Component parent ) { if ( parent != null ) { final Window window = LibSwingUtil.getWindowAncestor( parent ); if ( window instanceof Dialog ) { return new NumericInputDialog( (Dialog) window, true ); } if ( window instanceof Frame ) { return new NumericInputDialog( (Frame) window, true ); } } final NumericInputDialog dialog = new NumericInputDialog(); dialog.setModal( true ); return dialog; } public static Integer showInputDialog( final Component parent, final int icon, final String title, final String message, final int minimum, final int maximum, final int initialValue, final boolean bounded ) { final NumericInputDialog dialog = createDialog( parent ); if ( title != null ) { dialog.setTitle( title ); } if ( message != null ) { dialog.setMessage( message ); } dialog.setIcon( createDefaultIcon( icon ) ); dialog.setMinimum( minimum ); dialog.setMaximum( maximum ); dialog.setInputValue( new Integer( initialValue ) ); dialog.setBoundedRange( bounded ); dialog.setPaintTicks( true ); dialog.pack(); LibSwingUtil.centerDialogInParent( dialog ); dialog.setVisible( true ); if ( dialog.isConfirmed() ) { return dialog.getInputValue(); } return null; } public static Integer showInputDialog( final Component parent, final int icon, final String title, final String message, final int initialValue, final boolean bounded ) { final NumericInputDialog dialog = createDialog( parent ); if ( title != null ) { dialog.setTitle( title ); } if ( message != null ) { dialog.setMessage( message ); } dialog.setIcon( createDefaultIcon( icon ) ); dialog.setInputValue( new Integer( initialValue ) ); dialog.setSliderVisible( false ); dialog.setBoundedRange( bounded ); dialog.pack(); LibSwingUtil.centerDialogInParent( dialog ); dialog.setVisible( true ); if ( dialog.isConfirmed() ) { return dialog.getInputValue(); } return null; } public static Integer showSliderDialog( final Component parent, final int icon, final String title, final String message, final int minimum, final int maximum, final int initialValue ) { final NumericInputDialog dialog = createDialog( parent ); if ( title != null ) { dialog.setTitle( title ); } if ( message != null ) { dialog.setMessage( message ); } dialog.setIcon( createDefaultIcon( icon ) ); dialog.setMinimum( minimum ); dialog.setMaximum( maximum ); dialog.setInputValue( new Integer( initialValue ) ); dialog.setBoundedRange( true ); dialog.setTextInputVisible( false ); dialog.pack(); LibSwingUtil.centerDialogInParent( dialog ); dialog.setVisible( true ); if ( dialog.isConfirmed() ) { return dialog.getInputValue(); } return null; } /** * Returns the icon to use for the passed in type. */ private static Icon createDefaultIcon( final int messageType ) { final String propertyName; switch ( messageType ) { case 0: propertyName = "OptionPane.errorIcon"; //$NON-NLS-1$ break; case 1: propertyName = "OptionPane.informationIcon"; //$NON-NLS-1$ break; case 2: propertyName = "OptionPane.warningIcon"; //$NON-NLS-1$ break; case 3: propertyName = "OptionPane.questionIcon"; //$NON-NLS-1$ break; default: return null; } return UIManager.getIcon( propertyName ); } }