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