001: /*
002: * Copyright (C) 1999-2004 <A href="http://www-ist.massey.ac.nz/JBDietrich" target="_top">Jens Dietrich</a>
003: *
004: * This library is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU Lesser General Public
006: * License as published by the Free Software Foundation; either
007: * version 2 of the License, or (at your option) any later version.
008: *
009: * This library is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012: * Lesser General Public License for more details.
013: *
014: * You should have received a copy of the GNU Lesser General Public
015: * License along with this library; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
017: */
018: package org.mandarax.examples.crm.ui;
019:
020: import java.awt.*;
021: import java.awt.event.*;
022: import java.util.Collection;
023: import java.util.Iterator;
024: import javax.swing.*;
025: import org.apache.log4j.BasicConfigurator;
026: import org.mandarax.util.ProofAnalyzer;
027: import org.mandarax.examples.crm.DiscountCalculator;
028: import org.mandarax.examples.crm.KBLoader;
029: import org.mandarax.examples.crm.domainmodel.*;
030: import org.mandarax.kernel.*;
031:
032: /**
033: * A swing based interface for the discount calculator.
034: * The interface is actually a panel (in order to use it in an applet),
035: * but the main method will open it wrapped in a frame.
036: * @see org.mandarax.examples.crm.DiscountCalculator
037: * @author <A href="http://www-ist.massey.ac.nz/JBDietrich" target="_top">Jens Dietrich</A>
038: * @version 3.4 <7 March 05>
039: * @since 1.2
040: */
041: public class DiscountCalculatorView extends JPanel {
042:
043: // table model for customer details
044: class CustomerDetailsTableModel extends
045: javax.swing.table.AbstractTableModel {
046: // Constructor.
047: CustomerDetailsTableModel() {
048: super ();
049: }
050:
051: // Get the row count.
052: public int getRowCount() {
053: return Customer.ALL.length;
054: }
055:
056: // Get the column count.
057: public int getColumnCount() {
058: return 5;
059: }
060:
061: // Get the value at the position
062: public Object getValueAt(int rowIndex, int colIndex) {
063: Customer c = Customer.ALL[rowIndex];
064: if (colIndex == 0)
065: return String.valueOf(c.getId());
066: else if (colIndex == 1)
067: return c.getFirstName();
068: else if (colIndex == 2)
069: return c.getName();
070: else if (colIndex == 3)
071: return String.valueOf(c.getTurnover(12));
072: else if (colIndex == 4)
073: return String.valueOf(c.getTurnover(12,
074: KindOfPayment.COMPANY_VISA));
075: return null;
076: }
077:
078: // Get the column name.
079: public String getColumnName(int index) {
080: if (index == 0)
081: return "id";
082: else if (index == 1)
083: return "first name";
084: else if (index == 2)
085: return "name";
086: else if (index == 3)
087: return "turnover (last 12 month)";
088: else if (index == 4)
089: return "turnover (last 12 month, company credit card)";
090: return "column " + index;
091: }
092: }
093:
094: private JComboBox cbxCustomers = null;
095: private JLabel labResult = new JLabel("press \"calculate\"");
096: private JList listExplanation = new JList(new DefaultListModel());
097: private JList listKB = new JList(new DefaultListModel());
098: private JButton butCalculate = new JButton("calculate");
099: private JCheckBox checkAlias = new JCheckBox("use alias");
100: private JTable tabCustomerDetails = null;
101: private DiscountCalculator calc = new DiscountCalculator();
102: private Customer selectedCustomer = null;
103: private boolean useAlias = true;
104:
105: /**
106: * Constructor.
107: */
108: public DiscountCalculatorView() {
109: super ();
110: initialize();
111: }
112:
113: /**
114: * Calculate the discount for the selected customer and display it.
115: */
116: private void calculate() {
117: calc.calculateDiscount(selectedCustomer, KBLoader.getKB());
118: displayResult();
119: butCalculate.setEnabled(false);
120: }
121:
122: /**
123: * Validate the KB using the JUnit runner.
124: */
125: private void validateKB() {
126: String[] params = new String[] {
127: KnowledgeBaseValidator.class.getName(), "-noloading" }; // this class is the test suite
128: junit.swingui.TestRunner.main(params);
129: }
130:
131: /**
132: * Display the knowledge base.
133: */
134: private void displayKB() {
135:
136: // the derivation (as list, could also be displayed as tree)
137: DefaultListModel listModel = (DefaultListModel) listKB
138: .getModel();
139: listModel.removeAllElements();
140: for (Iterator iter = KBLoader.getKB().getClauseSets()
141: .iterator(); iter.hasNext();) {
142: ClauseSet nextCS = (ClauseSet) iter.next();
143: String value = nextCS.toString();
144: // try to get custom string stored as attached property
145: if (useAlias && nextCS.getProperty("alias") != null)
146: value = nextCS.getProperty("alias");
147: listModel.addElement(value);
148: }
149: }
150:
151: /**
152: * Display the result calculated.
153: */
154: private void displayResult() {
155:
156: // display the calculated discount
157: labResult.setText(calc.getDiscount().toString());
158: if (calc.getDerivation() == null) {
159: return;
160: }
161:
162: // the derivation (as list, could also be displayed as tree)
163: DefaultListModel listModel = (DefaultListModel) listExplanation
164: .getModel();
165: Collection usedKnowledge = ProofAnalyzer.getAppliedClauses(calc
166: .getDerivation());
167: listModel.removeAllElements();
168: for (Iterator iter = usedKnowledge.iterator(); iter.hasNext();) {
169: ClauseSet nextCS = (ClauseSet) iter.next();
170: if (nextCS != null) {
171: String value = nextCS.toString();
172: // try to get custom string stored as attached property
173: if (useAlias && nextCS.getProperty("alias") != null)
174: value = nextCS.getProperty("alias");
175: listModel.addElement(value);
176: }
177: }
178: }
179:
180: /**
181: * Initialize the events.
182: */
183: private void initEvents() {
184: cbxCustomers.addItemListener(new ItemListener() {
185: public void itemStateChanged(ItemEvent e) {
186: selectedCustomer = (Customer) e.getItem();
187: if (selectedCustomer != null) {
188: butCalculate.setEnabled(true);
189: }
190: reset();
191: }
192: });
193: butCalculate.addActionListener(new ActionListener() {
194: public void actionPerformed(ActionEvent e) {
195: calculate();
196: }
197: });
198: checkAlias.addActionListener(new ActionListener() {
199: public void actionPerformed(ActionEvent e) {
200: useAlias = checkAlias.isSelected();
201: displayResult();
202: displayKB();
203: }
204: });
205: }
206:
207: /**
208: * Initialize the object.
209: */
210: private void initialize() {
211:
212: // the northern panel
213: JPanel north = new JPanel(new GridLayout(2, 1, 3, 3));
214: JPanel inputPanel = new JPanel(
215: new FlowLayout(FlowLayout.CENTER));
216: JPanel outputPanel = new JPanel(new FlowLayout(
217: FlowLayout.CENTER));
218: // Vector custList = new Vector ();
219: cbxCustomers = new JComboBox(Customer.ALL);
220: cbxCustomers.setSelectedIndex(0);
221: selectedCustomer = Customer.ALL[0];
222:
223: inputPanel.add(new JLabel("Calculate discount for: "));
224: inputPanel.add(cbxCustomers);
225: inputPanel.add(butCalculate);
226:
227: JLabel labCalculated = new JLabel(" Calculated discount: ");
228:
229: labCalculated.setFont(new Font("dialog.bold", 1, 14));
230: labCalculated.setForeground(Color.black);
231: outputPanel.add(labCalculated);
232: labResult.setForeground(Color.red);
233: labResult.setFont(new Font("dialog.bold", 1, 14));
234: outputPanel.add(labResult);
235: outputPanel.setBorder(BorderFactory.createEtchedBorder());
236: outputPanel.setBackground(Color.white);
237: north.add(inputPanel);
238: north.add(outputPanel);
239:
240: // the central panel
241: JTabbedPane notebook = new JTabbedPane(JTabbedPane.TOP);
242: JPanel explanationPanel = new JPanel(new BorderLayout(5, 5));
243:
244: explanationPanel.add(new JScrollPane(listExplanation),
245: BorderLayout.CENTER);
246: explanationPanel.setBorder(BorderFactory.createEmptyBorder(5,
247: 5, 5, 5));
248: notebook.add("used rules", explanationPanel);
249:
250: JPanel tabPanel = new JPanel(new GridLayout(1, 1));
251:
252: tabCustomerDetails = new JTable(new CustomerDetailsTableModel());
253:
254: tabCustomerDetails
255: .sizeColumnsToFit(JTable.AUTO_RESIZE_ALL_COLUMNS);
256: tabPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
257: tabPanel.add(new JScrollPane(tabCustomerDetails));
258: notebook.add("customer details", tabPanel);
259: JPanel kbPanel = new JPanel(new GridLayout(1, 1));
260:
261: kbPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
262: kbPanel.add(new JScrollPane(listKB));
263: notebook.add("all rules", kbPanel);
264: displayKB();
265:
266: JPanel centralPanel = new JPanel(new BorderLayout(5, 5));
267: centralPanel
268: .add(
269: new JLabel(
270: "The calculation is based on the following rules and data:",
271: JLabel.CENTER), BorderLayout.NORTH);
272: centralPanel.add(notebook, BorderLayout.CENTER);
273:
274: JPanel aliasPanel = new JPanel(
275: new FlowLayout(FlowLayout.CENTER));
276:
277: checkAlias.setSelected(useAlias);
278: aliasPanel.add(checkAlias);
279: centralPanel.add(aliasPanel, BorderLayout.SOUTH);
280:
281: // the main panel
282: setLayout(new BorderLayout(5, 5));
283: add(north, BorderLayout.NORTH);
284: add(centralPanel, BorderLayout.CENTER);
285: add(new JPanel(), BorderLayout.WEST);
286: add(new JPanel(), BorderLayout.EAST);
287: initEvents();
288: }
289:
290: /**
291: * Application entry point.
292: * @param args the command line arguments
293: */
294: public static void main(String[] args) {
295: // init log4j first
296: BasicConfigurator.configure();
297:
298: // create UI
299: JFrame wrapper = new JFrame("Mandarax Discount Calculator");
300: wrapper.getContentPane().setLayout(new GridLayout(1, 1));
301:
302: DiscountCalculatorView view = new DiscountCalculatorView();
303: wrapper.getContentPane().add(view);
304: wrapper.setSize(700, 400);
305: wrapper.setLocation(100, 100);
306: wrapper.setVisible(true);
307: WindowAdapter wa = new WindowAdapter() {
308: public void windowClosing(WindowEvent e) {
309: System.exit(0);
310: }
311: };
312: wrapper.addWindowListener(wa);
313: }
314:
315: /**
316: * Reset the interface (if a new customer has been selected).
317: */
318: private void reset() {
319: labResult.setText("press \"calculate\"");
320: listExplanation.setModel(new DefaultListModel());
321: }
322: }
|