package org.geogebra.desktop.gui.util;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ButtonGroup;
import javax.swing.JMenu;
import javax.swing.JRadioButtonMenuItem;
import org.geogebra.common.gui.menubar.OptionsMenu;
import org.geogebra.common.kernel.StringTemplate;
import org.geogebra.common.kernel.arithmetic.ExpressionNodeConstants.StringType;
import org.geogebra.common.main.App;
import org.geogebra.desktop.main.AppD;
/**
* Utility class to support non-default number formatting in a component.
* Includes methods to store a user-selected number format, to apply the format
* and to create a "Rounding" menu.
*
* Code is adapted from gui.menubar.OptionsMenu
*
* @author G. Sturr
*
*/
public class SpecialNumberFormat implements ActionListener {
private AppD app;
private SpecialNumberFormatInterface invoker;
private JMenu menuDecimalPlaces;
/**
* Default number format
*/
private int printFigures = -1;
private int printDecimals = 4;
/**
* Constructor
*
* @param app
* @param invoker
* : the component utilizing this number format class
*/
public SpecialNumberFormat(AppD app, SpecialNumberFormatInterface invoker) {
this.app = app;
this.invoker = invoker;
}
public int getPrintFigures() {
return printFigures;
}
public int getPrintDecimals() {
return printDecimals;
}
/**
* Converts number to string using the currently selected format
*
* @param x
* number
* @return formated string
*/
public String format(double x) {
StringTemplate highPrecision;
// override the default decimal place setting
if (printDecimals >= 0) {
highPrecision = StringTemplate.printDecimals(StringType.GEOGEBRA,
printDecimals, false);
} else {
highPrecision = StringTemplate.printFigures(StringType.GEOGEBRA,
printFigures, false);
}
// get the formatted string
String result = app.getKernel().format(x, highPrecision);
return result;
}
/**
* Creates a menu with number format options Note: this menu is derived from
*
* @return
*/
public JMenu createMenuDecimalPlaces() {
menuDecimalPlaces = new JMenu(
app.getLocalization().getMenu("Rounding"));
String[] strDecimalSpaces = app.getLocalization().getRoundingMenu();
addRadioButtonMenuItems(menuDecimalPlaces, this, strDecimalSpaces,
App.getStrDecimalSpacesAC(), 0);
updateMenuDecimalPlaces();
return menuDecimalPlaces;
}
/**
* Update the menu to select the current format.
*/
private void updateMenuDecimalPlaces() {
if (menuDecimalPlaces == null) {
return;
}
int pos = -1;
if (printFigures >= 0) {
if (printFigures > 0
&& printFigures < OptionsMenu.figuresLookupLength()) {
pos = OptionsMenu.figuresLookup(printFigures);
}
} else {
if (printDecimals > 0
&& printDecimals < OptionsMenu.decimalsLookupLength()) {
pos = OptionsMenu.decimalsLookup(printDecimals);
}
}
try {
((JRadioButtonMenuItem) menuDecimalPlaces.getMenuComponent(pos))
.setSelected(true);
} catch (Exception e) {
}
app.setComponentOrientation(menuDecimalPlaces);
}
/**
* Create a set of radio buttons automatically.
*
* @param menu
* @param al
* @param items
* @param actionCommands
* @param selectedPos
*/
private void addRadioButtonMenuItems(JMenu menu, ActionListener al,
String[] items, String[] actionCommands, int selectedPos) {
JRadioButtonMenuItem mi;
ButtonGroup bg = new ButtonGroup();
// String label;
for (int i = 0; i < items.length; i++) {
if ("---".equals(items[i])) {
menu.addSeparator();
} else {
String text = app.getLocalization().getMenu(items[i]);
mi = new JRadioButtonMenuItem(text);
mi.setFont(app.getFontCanDisplayAwt(text));
if (i == selectedPos) {
mi.setSelected(true);
}
mi.setActionCommand(actionCommands[i]);
mi.addActionListener(al);
bg.add(mi);
menu.add(mi);
}
}
}
/**
* Listener for the Rounding menu. Notifies the invoking component of a
* format change with invoker.changedNumberFormat().
*/
@Override
public void actionPerformed(ActionEvent e) {
String cmd = e.getActionCommand();
// decimal places
if (cmd.endsWith("decimals")) {
try {
String decStr = cmd.substring(0, 2).trim();
int decimals = Integer.parseInt(decStr);
// Application.debug("decimals " + decimals);
printDecimals = decimals;
printFigures = -1;
invoker.changedNumberFormat();
} catch (Exception ex) {
app.showError(e.toString());
}
}
// significant figures
else if (cmd.endsWith("figures")) {
try {
String decStr = cmd.substring(0, 2).trim();
int figures = Integer.parseInt(decStr);
// Application.debug("figures " + figures);
printFigures = figures;
printDecimals = -1;
invoker.changedNumberFormat();
} catch (Exception ex) {
app.showError(e.toString());
}
}
}
}