# Calculator UI Example

The Calculator UI Example shows how to use forms created with Qt Designer in an application.

Simple | Normal | Dockable
--- | --- | ---

The example provides a calculator application that allows the user to choose the preferred user interface among Simple, Normal and Dockable. The main application window is provided by the `Calculator` class which extends the QMainWindow class.

## Calculator Class Definition

In general, you only have to subclass QWidget to implement the UI forms. The reason we have chosen to derive from QMainWindow (which is a QWidget subclass) instead, is rooted in the dockable version of our calculator. QWidget does not support dock widgets; QMainWindow does.

        public class Calculator extends QMainWindow {

            public static void main(String[] args) {

                QApplication.initialize(args);
                Calculator calculator = new Calculator();
                calculator.show();
                QApplication.exec();
            }

            private QLineEdit lineEdit;
            private QTextBrowser textBrowser;

            private Vector<Function> infixFunctions = new Vector<Function>();
            private Hashtable<String, Function> functions = new Hashtable<String,
                                                                          Function>();

In the `Calculator` class, we first provide a `main()` method to create and show the main application window when the example is run. While running the calculator, we will have to access the line edit to accept input and the text browser to display the calculations and results. For that reason, we declare corresponding variables in the application wide scope. We also have to provide functions that correspond to the application's user interface. All of this is taken care of in the `Calculator` class's constructor.

## Calculator Class Constructor

In the constructor, we first define the various user interfaces that the user can choose from, and the we use the QInputDialog class to retrieve the user's preferred alternative:

            public Calculator() {
                Vector<String> uiTypes = new Vector<String>(3);
                uiTypes.add("Simple");
                uiTypes.add("Normal");
                uiTypes.add("Dockable");
                ...
                String item = QInputDialog.getItem(this, tr("Ui selector"),
                                                   tr("Ui configurations:"), uiTypes,

The QInputDialog class provides a simple convenience dialog to get a single value from the user. The input value can be a string, a number or an item from a list. We use the static QInputDialog.getItem() convenience method to let the user select one of our predefined alternatives using a combobox.

When pressing the dialog's OK button, the getItem() method returns the text of the current item; otherwise it returns `null`.

                if (item == null || item.equals("Simple")) {
                    Ui_CalculatorSimple uiSimple = new Ui_CalculatorSimple();
                    uiSimple.setupUi(this);
                    lineEdit = uiSimple.lineEdit;
                    textBrowser = uiSimple.textBrowser;
                } else if (item.equals("Normal")) {
                    Ui_CalculatorNormal uiNormal = new Ui_CalculatorNormal();
                    uiNormal.setupUi(this);
                    lineEdit = uiNormal.lineEdit;
                    textBrowser = uiNormal.textBrowser;
                } else if (item.equals("Dockable")) {
                    Ui_CalculatorDockable uiDockable = new Ui_CalculatorDockable();
                    uiDockable.setupUi(this);
                    lineEdit = uiDockable.lineEdit;
                    textBrowser = uiDockable.textBrowser;
                }

Once we know which user interface the user prefer, we can create an object of the corresponding class. Note that you must run the user interface compiler for Qt (juic) to generate the latter class. For example, if the form created in Qt Designer is saved as `CalculatorSimple.jui`, running juic on the file will generate the corresponding `Ui_CalculatorSimple.java` file that defines the public `Ui_CalculatorSimple` class. The latter file must be located in the same directory as the application executable to be successfully loaded at runtime.

The generated class has a `setupUI()` method that we can use to set up the preferred user interface. We pass `this` as the argument to this method to use the `Calculator` widget itself as the container for the user interface. With the user interface in place, we can also establish the previously mentioned access to the input line edit and output text browser.

Then we create the calculator functionality:

                Function function= new Function("abs") {
                    public double result(double[] args) throws ParseException {
                        checkNumberOfArguments(1,args);
                        return Math.abs(args[0]);
                    }
                };
                functions.put(function.name, function);
                ...
            }

Each calculator operation is represented by a `Function` object. The `Function` class is a convenience class providing the functionality that is common for all operations. In addition, we define a operation specific `result()` method for each object, providing the operation's calculations. See the example code for more details.

## Connecting to the User Interface

In addition to creating the user interface, `setupUi()` automatically calls the QObject.connectSlotsByName() method, connecting signals from widgets on the form to methods in our code. To indicate which widgets and signals in the user interface that should be connected to each method, we use a predefined naming convention. For example:

            public void on_button_equal_clicked() {
                String expression = lineEdit.text();
                String result = "";
                boolean error = false;
                try {
                    result = Double.toString(evaluate(parse(expression)));
                } catch (ParseException exception) {
                    result = "Error: <font color=\"red\">"
                             + exception.getMessage() + "</font>";
                    error = true;
                }

                textBrowser.append(expression + "<b> = " + result + "</b><br>");
                if (error)
                    result = expression;
                lineEdit.setText(result);
            }
            ...
        }

The `on_button_equal_clicked()` method is called whenever the button called "button_equal" in the user interface emits the QAbstractButton.clicked() signal. By providing similar methods for all the buttons in the user interface we get a fully responsive calculator application.

Note that the `Calculator` class defines several other methods used to perform the various calculations, but these are beyond the scope of this documentation. Please see the example code for implementation details.