All Downloads are FREE. Search and download functionalities are using the official Maven repository.

edu.cmu.tetradapp.app.NumberFormatAction Maven / Gradle / Ivy

The newest version!
///////////////////////////////////////////////////////////////////////////////
// For information as to what this class does, see the Javadoc, below.       //
// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,       //
// 2007, 2008, 2009, 2010, 2014, 2015, 2022 by Peter Spirtes, Richard        //
// Scheines, Joseph Ramsey, and Clark Glymour.                               //
//                                                                           //
// This program is free software; you can redistribute it and/or modify      //
// it under the terms of the GNU General Public License as published by      //
// the Free Software Foundation; either version 2 of the License, or         //
// (at your option) any later version.                                       //
//                                                                           //
// 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 General Public License for more details.                              //
//                                                                           //
// You should have received a copy of the GNU General Public License         //
// along with this program; if not, write to the Free Software               //
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA //
///////////////////////////////////////////////////////////////////////////////

package edu.cmu.tetradapp.app;

import edu.cmu.tetrad.util.JOptionUtils;
import edu.cmu.tetrad.util.NumberFormatUtil;

import javax.swing.*;
import javax.swing.border.TitledBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.ClipboardOwner;
import java.awt.datatransfer.Transferable;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.prefs.Preferences;

/**
 * Presents a dialog allowing the user to change the number format used to render real numbers throughout Tetrad.
 *
 * @author josephramsey
 */
final class NumberFormatAction extends AbstractAction
        implements ClipboardOwner {

    /**
     * This is a class field because it's accessed from multiple places.
     */
    private final JTextField formatField = new JTextField(
            Preferences.userRoot().get("numberFormat", "0.0000"));

    /**
     * Constructs a new number format action.
     */
    public NumberFormatAction() {
        super("Number Format");
    }

    /**
     * {@inheritDoc}
     * 

* Required by the AbstractAction interface; shows a dialog allowing the user to change the number format used to * render real numbers throughout Tetrad. */ public void actionPerformed(ActionEvent e) { // Set up basic tab. final double sample = 23.5; JTextField renderFieldBasic = new JTextField( new DecimalFormat(constructSimpleFormatString()).format(sample)); renderFieldBasic.setMaximumSize(new Dimension(150, 50)); renderFieldBasic.setEditable(false); renderFieldBasic.setBackground(Color.WHITE); JCheckBox scientific = new JCheckBox( "Use scientific notation", Preferences.userRoot().getBoolean("scientificNotation", false)); scientific.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { JCheckBox checkBox = (JCheckBox) e.getSource(); Preferences.userRoot().putBoolean("scientificNotation", checkBox.isSelected()); renderFieldBasic.setText(new DecimalFormat(constructSimpleFormatString()).format(sample)); NumberFormatAction.this.formatField.setText(constructSimpleFormatString()); } }); SpinnerModel model = new SpinnerNumberModel( Preferences.userRoot().getInt("numDecimals", 4), 0, 300, 1); JSpinner numDecimals = new JSpinner(model); numDecimals.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent e) { JSpinner spinner = (JSpinner) e.getSource(); SpinnerNumberModel model = (SpinnerNumberModel) spinner.getModel(); int value = (Integer) model.getValue(); Preferences.userRoot().putInt("numDecimals", value); renderFieldBasic.setText(new DecimalFormat(constructSimpleFormatString()).format(sample)); NumberFormatAction.this.formatField.setText(constructSimpleFormatString()); } }); numDecimals.setMaximumSize(numDecimals.getPreferredSize()); boolean decimalsOptional = Preferences.userRoot().getBoolean("decimalsOptimal", false); JRadioButton optional = new JRadioButton("Optional", decimalsOptional); JRadioButton fixed = new JRadioButton("Fixed", !decimalsOptional); ButtonGroup group = new ButtonGroup(); group.add(optional); group.add(fixed); optional.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { Preferences.userRoot().putBoolean("decimalsOptional", true); renderFieldBasic.setText(new DecimalFormat(constructSimpleFormatString()).format(sample)); NumberFormatAction.this.formatField.setText(constructSimpleFormatString()); } }); fixed.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { Preferences.userRoot().putBoolean("decimalsOptional", false); renderFieldBasic.setText(new DecimalFormat(constructSimpleFormatString()).format(sample)); NumberFormatAction.this.formatField.setText(constructSimpleFormatString()); } }); if (!Preferences.userRoot().getBoolean("numFormatAdvanced", false)) { this.formatField.setText(constructSimpleFormatString()); } // Set up basic panel. Box a = Box.createVerticalBox(); a.setBorder(new TitledBorder("Simple Formats")); Box a2 = Box.createHorizontalBox(); a2.add(scientific); a2.add(Box.createHorizontalGlue()); a.add(a2); Box a3 = Box.createHorizontalBox(); a3.add(new JLabel("Number of decimal places = ")); a3.add(numDecimals); a3.add(Box.createHorizontalGlue()); a.add(a3); Box a4 = Box.createHorizontalBox(); a4.add(Box.createRigidArea(new Dimension(20, 0))); a4.add(optional); a4.add(Box.createHorizontalGlue()); a.add(a4); Box a5 = Box.createHorizontalBox(); a5.add(Box.createRigidArea(new Dimension(20, 0))); a5.add(fixed); a5.add(Box.createHorizontalGlue()); a.add(a5); a.add(Box.createVerticalStrut(20)); Box a6 = Box.createHorizontalBox(); a6.add(new JLabel("Renders as: ")); a6.add(renderFieldBasic); a.add(a6); a.add(Box.createVerticalGlue()); Box basic = Box.createVerticalBox(); basic.add(a); JPanel basicPanel = new JPanel(); basicPanel.setLayout(new BorderLayout()); basicPanel.add(basic, BorderLayout.CENTER); // Set up advanced panel. JTextField sampleFieldAdvanced = new JTextField("" + sample); JTextField renderFieldAdvanced = new JTextField(getNumberFormat().format(sample)); renderFieldAdvanced.setEditable(false); renderFieldAdvanced.setBackground(Color.WHITE); this.formatField.addKeyListener(new KeyAdapter() { public void keyReleased(KeyEvent e) { updateAdvancedFields(sampleFieldAdvanced, renderFieldAdvanced); } }); sampleFieldAdvanced.addKeyListener(new KeyAdapter() { public void keyReleased(KeyEvent e) { updateAdvancedFields(sampleFieldAdvanced, renderFieldAdvanced); } }); Box z = Box.createVerticalBox(); Box z1 = Box.createHorizontalBox(); z1.add(new JLabel("Refer to DecimalFormat in the ")); z1.add(Box.createHorizontalGlue()); z.add(z1); Box z2 = Box.createHorizontalBox(); z2.add(new JLabel("documentation for Java.")); z2.add(Box.createHorizontalGlue()); z.add(z2); z.add(Box.createVerticalStrut(10)); Box advanced = Box.createVerticalBox(); advanced.add(z); Box f = Box.createVerticalBox(); f.setBorder(new TitledBorder("Format String")); Box f1 = Box.createHorizontalBox(); f1.add(this.formatField); f.add(f1); advanced.add(f); Box c = Box.createVerticalBox(); c.setBorder(new TitledBorder("Example")); Box c1 = Box.createHorizontalBox(); c1.add(sampleFieldAdvanced); c.add(c1); Box c2 = Box.createHorizontalBox(); c2.add(new JLabel("Renders as: ")); c2.add(Box.createHorizontalGlue()); c.add(c2); Box c3 = Box.createHorizontalBox(); c3.add(renderFieldAdvanced); c.add(c3); advanced.add(c); JPanel advancedPanel = new JPanel(); advancedPanel.setLayout(new BorderLayout()); advancedPanel.add(advanced, BorderLayout.CENTER); JTabbedPane tabbedPane = new JTabbedPane(); tabbedPane.addTab("Basic", basicPanel); tabbedPane.addTab("Advanced", advancedPanel); if (Preferences.userRoot().getBoolean("numFormatAdvanced", false)) { tabbedPane.setSelectedComponent(advancedPanel); } tabbedPane.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent e) { JTabbedPane tabbedPane = (JTabbedPane) e.getSource(); JPanel panel = (JPanel) tabbedPane.getSelectedComponent(); Preferences.userRoot().putBoolean("numFormatAdvanced", panel == advancedPanel); if (panel == basicPanel) { String format = constructSimpleFormatString(); NumberFormatAction.this.formatField.setText(format); renderFieldBasic.setText(new DecimalFormat(format).format(sample)); } } }); JPanel panel = new JPanel(); panel.setLayout(new BorderLayout()); panel.add(tabbedPane, BorderLayout.CENTER); JOptionPane.showMessageDialog(JOptionUtils.centeringComp(), panel, "Formatting for All Real Numbers", JOptionPane.INFORMATION_MESSAGE); NumberFormatUtil.getInstance().setNumberFormat(getNumberFormat()); } /** * @return the most recent number format, whether from the basic or from the advanced tab. * @throws RuntimeException if the getModel format string cannot be accepted by DecimalFormat. */ private NumberFormat getNumberFormat() throws IllegalStateException { return new DecimalFormat(getFormatString()); } /** * @return the most recent format string, whether from the basic or from the advanced tab. * @throws RuntimeException if the stored format string cannot be accepted by DecimalFormat. */ private String getFormatString() throws RuntimeException { String format = this.formatField.getText(); try { new DecimalFormat(format); } catch (Exception e) { throw new RuntimeException("Illegal format string: " + format); } return format; } /** * {@inheritDoc} *

* Required by the AbstractAction interface; does nothing. */ public void lostOwnership(Clipboard clipboard, Transferable contents) { } /** * This sets up the behavior in the advanced tab where when you change the format or the example numnber, it updates * the rendering. It also sets the color of the format or example to red when it's ill-formatted. * * @param sampleFieldAdvanced The example field. * @param renderFieldAdvanced The render field. */ private void updateAdvancedFields(JTextField sampleFieldAdvanced, JTextField renderFieldAdvanced) { try { Double.parseDouble(sampleFieldAdvanced.getText()); } catch (Exception e1) { sampleFieldAdvanced.setForeground(Color.RED); return; } String format = this.formatField.getText(); try { new DecimalFormat(format); } catch (Exception e2) { this.formatField.setForeground(Color.RED); return; } double sample = Double.parseDouble(sampleFieldAdvanced.getText()); NumberFormat nf = new DecimalFormat(format); renderFieldAdvanced.setText(nf.format(sample)); sampleFieldAdvanced.setForeground(Color.BLACK); this.formatField.setForeground(Color.BLACK); Preferences.userRoot().put("numberFormat", format); } private String constructSimpleFormatString() { boolean scientificNotation = Preferences.userRoot() .getBoolean("scientificNotation", false); int numDecimals = Preferences.userRoot() .getInt("numDecimals", 4); boolean optional = Preferences.userRoot() .getBoolean("decimalsOptional", false); StringBuilder buf = new StringBuilder(); buf.append("0."); if (optional) { for (int i = 0; i < numDecimals; i++) { buf.append("#"); } } else { for (int i = 0; i < numDecimals; i++) { buf.append("0"); } } if (scientificNotation) { buf.append("E0"); } String formatString = buf.toString(); // formatField.setText(formatString); Preferences.userRoot().put("numberFormat", formatString); return formatString; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy