/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package org.montsuqi.client; import java.awt.Color; import java.awt.Component; import java.awt.Container; import java.awt.EventQueue; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import javax.swing.JComponent; import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JMenuItem; import javax.swing.SwingUtilities; import org.apache.logging.log4j.Level; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import org.montsuqi.client.widgethandlers.WidgetHandler; import org.montsuqi.monsia.Interface; import org.montsuqi.monsia.Style; import org.montsuqi.util.SystemEnvironment; import org.montsuqi.widgets.ExceptionDialog; import org.montsuqi.widgets.PandaTimer; import org.montsuqi.widgets.TopWindow; import org.montsuqi.widgets.Window; /** * * @author mihara */ public class UIControl { protected static final Logger logger = LogManager.getLogger(UIControl.class); private final HashMap<String, Node> nodeTable; private String sessionTitle; private Color sessionBGColor; private Interface xml; private final TopWindow topWindow; private final Map styleMap; private final Map<String, Component> changedWidgetMap; private final Map<String, Object> screenTemplateMap; private final Client client; private final long timerPeriod; public UIControl(Client client, URL styleURL, long timerPeriod) throws IOException { nodeTable = new HashMap<>(); sessionTitle = ""; sessionBGColor = null; topWindow = new TopWindow(); changedWidgetMap = new HashMap<>(); screenTemplateMap = new HashMap<>(); this.client = client; styleMap = loadStyles(styleURL); this.timerPeriod = timerPeriod; } public Object getScreenTemplate(String window) { return screenTemplateMap.get(window); } public void addScreenTemplate(String window, Object object) { screenTemplateMap.put(window, object); } public void updateScreenTemplate(Object tmpl, Object upd) { try { if (upd != null && tmpl.getClass() == upd.getClass()) { if (tmpl instanceof JSONObject && upd instanceof JSONObject) { JSONObject tmplObj = (JSONObject) tmpl; JSONObject updObj = (JSONObject) upd; for (Iterator i = tmplObj.keys(); i.hasNext();) { String key = (String) i.next(); Object c1 = tmplObj.get(key); Object c2 = null; if (updObj.has(key)) { c2 = updObj.get(key); } if (c1 instanceof JSONObject || c1 instanceof JSONArray) { updateScreenTemplate(c1, c2); } else if (c2 != null && c1.getClass() == c2.getClass()) { tmplObj.put(key, c2); } else if (c1 instanceof java.lang.Boolean) { tmplObj.put(key, true); } else if (c1 instanceof java.lang.Integer) { tmplObj.put(key, 0); } else if (c1 instanceof java.lang.Double) { tmplObj.put(key, 0.0); } else if (c1 instanceof java.lang.String) { tmplObj.put(key, ""); } } } else if (tmpl instanceof JSONArray && upd instanceof JSONArray) { JSONArray tmplArr = (JSONArray) tmpl; JSONArray updArr = (JSONArray) upd; for (int i = 0; i < tmplArr.length(); i++) { Object c1 = tmplArr.get(i); Object c2 = null; if (i < updArr.length()) { c2 = updArr.get(i); } if (c1 instanceof JSONObject || c1 instanceof JSONArray) { updateScreenTemplate(c1, c2); } else if (c2 != null && c1.getClass() == c2.getClass()) { tmplArr.put(i, c2); } else if (c1 instanceof java.lang.Boolean) { tmplArr.put(i, true); } else if (c1 instanceof java.lang.Integer) { tmplArr.put(i, 0); } else if (c1 instanceof java.lang.Double) { tmplArr.put(i, 0.0); } else if (c1 instanceof java.lang.String) { tmplArr.put(i, ""); } } } else { System.out.println("tmpl ----"); System.out.println(tmpl); System.out.println("upd ----"); System.out.println(upd); } } else if (tmpl instanceof JSONObject) { JSONObject tmplObj = (JSONObject) tmpl; for (Iterator i = tmplObj.keys(); i.hasNext();) { String key = (String) i.next(); Object c1 = tmplObj.get(key); if (c1 instanceof JSONObject || c1 instanceof JSONArray) { updateScreenTemplate(c1, null); } else if (c1 instanceof java.lang.Boolean) { tmplObj.put(key, true); } else if (c1 instanceof java.lang.Integer) { tmplObj.put(key, 0); } else if (c1 instanceof java.lang.Double) { tmplObj.put(key, 0.0); } else if (c1 instanceof java.lang.String) { tmplObj.put(key, ""); } } } else if (tmpl instanceof JSONArray) { JSONArray tmplArr = (JSONArray) tmpl; for (int i = 0; i < tmplArr.length(); i++) { Object c1 = tmplArr.get(i); if (c1 instanceof JSONObject || c1 instanceof JSONArray) { updateScreenTemplate(c1, null); } else if (c1 instanceof java.lang.Boolean) { tmplArr.put(i, true); } else if (c1 instanceof java.lang.Integer) { tmplArr.put(i, 0); } else if (c1 instanceof java.lang.Double) { tmplArr.put(i, 0.0); } else if (c1 instanceof java.lang.String) { tmplArr.put(i, ""); } } } } catch (JSONException ex) { logger.catching(Level.FATAL, ex); } } public long getTimerPeriod() { return timerPeriod; } public Client getClient() { return client; } private Map loadStyles(URL url) throws IOException { logger.debug("loading styles from URL: {0}", url); InputStream in = url.openStream(); return Style.load(in); } public String getWindowName(Component widget) { String name = widget.getName(); return name.substring(0, name.indexOf(".")); } public Window getTopWindow() { return topWindow; } public Node getNode(String name) { return (Node) nodeTable.get(name); } public Node getNode(Component component) { return getNode(getWindowName(component)); } public void putNode(String wName, Node node) { nodeTable.put(wName, node); } public void setWidget(Interface xml, Component widget, Object obj) throws JSONException { if (widget == null) { return; } if (obj == null) { return; } Class clazz = widget.getClass(); WidgetHandler handler = WidgetHandler.getHandler(clazz); if (handler != null) { long t1 = System.currentTimeMillis(); handler.set(this, widget, (JSONObject) obj, styleMap); long t2 = System.currentTimeMillis(); if (System.getProperty("monsia.do_profile") != null) { //logger.info("" + (t2-t1) + "ms " + clazz.getName()+ " " + name); } } if (obj instanceof JSONObject) { JSONObject j = (JSONObject) obj; for (Iterator i = j.keys(); i.hasNext();) { String key = (String) i.next(); Component child = xml.getWidgetByLongName(widget.getName() + "." + key); if (child != null) { setWidget(xml, child, j.get(key)); } } } } public void showWindow(String name) { Node node = getNode(name); if (node == null) { return; } xml = node.getInterface(); topWindow.setXml(xml); topWindow.ReScale(); Window window = node.getWindow(); window.setSessionTitle(sessionTitle); if (window.isDialog()) { Component parent = topWindow; JDialog dialog = window.getDialog(); topWindow.showBusyCursor(); dialog = window.createDialog(topWindow, topWindow); window.getChild().setBackground(this.sessionBGColor); dialog.validate(); resetTimer(dialog); } else { topWindow.showWindow(window); window.getChild().setBackground(this.sessionBGColor); resetTimer(window.getChild()); topWindow.validate(); } } public void closeWindow(String name) { Node node = getNode(name); if (node == null) { return; } Window window = node.getWindow(); if (window.isDialog()) { JDialog dialog = window.getDialog(); stopTimer(window.getDialog()); window.destroyDialog(); } else { stopTimer(window.getChild()); window.getChild().setEnabled(false); } } public void setFocus(String focusWindowName, String focusWidgetName) { if (focusWindowName == null || focusWidgetName == null) { return; } if (focusWindowName.startsWith("_")) { return; } Node node = getNode(focusWindowName); if (node != null && node.getInterface() != null && focusWindowName.equals(client.getFocusedWindow())) { Interface thisXML = node.getInterface(); Component widget = thisXML.getWidget(focusWidgetName); if (widget == null || !widget.isFocusable()) { widget = thisXML.getAnyWidget(); } final Component focusWidget = widget; if (focusWidget != null && focusWidget.isFocusable()) { if (SystemEnvironment.isMacOSX()) { EventQueue.invokeLater(new Runnable() { @Override public void run() { focusWidget.requestFocus(); } }); } else { focusWidget.requestFocusInWindow(); } } } } public void exceptionOccured(IOException e) { ExceptionDialog.showExceptionDialog(e); System.exit(1); } private void stopTimer(Component widget) { if (widget instanceof PandaTimer) { ((PandaTimer) widget).stopTimer(); } else if (widget instanceof Container) { Container container = (Container) widget; for (int i = 0, n = container.getComponentCount(); i < n; i++) { stopTimer(container.getComponent(i)); } } } private void resetTimer(Component widget) { if (widget instanceof PandaTimer) { ((PandaTimer) widget).reset(); } else if (widget instanceof Container) { Container container = (Container) widget; for (int i = 0, n = container.getComponentCount(); i < n; i++) { resetTimer(container.getComponent(i)); } } } private String getTitle(java.awt.Window window) { String title = ""; if (window instanceof JFrame) { title = ((JFrame) window).getTitle(); } else if (window instanceof JDialog) { title = ((JDialog) window).getTitle(); } return title; } private void setTitle(java.awt.Window window, String title) { if (window instanceof JFrame) { ((JFrame) window).setTitle(title); } else if (window instanceof JDialog) { ((JDialog) window).setTitle(title); } } static private String getWidgetName(String str) { int index; index = str.lastIndexOf('.'); if (index == -1) { return str; } else { return str.substring(index + 1); } } public void sendEvent(Component widget, Object userData) { if (client.isReceiving()) { return; } try { client.startReceiving(); java.awt.Window window; if (widget instanceof JMenuItem) { JComponent c = (JComponent) widget; window = (java.awt.Window) c.getClientProperty("window"); } else { window = SwingUtilities.windowForComponent(widget); } if (window == null || widget == null) { return; } if (!window.getName().equals(client.getFocusedWindow())) { return; } String oldTitle = getTitle(window); setTitle(window, Messages.getString("Client.loading")); String _windowName = getWidgetName(window.getName()); String _widgetName = getWidgetName(widget.getName()); String event; if (userData == null) { event = _widgetName; } else { event = userData.toString(); if (event.length() == 0) { event = _widgetName; } } org.montsuqi.widgets.Window.busyAllWindows(); client.sendEvent(_windowName, _widgetName, event); if (Messages.getString("Client.loading").equals(getTitle(window))) { setTitle(window, oldTitle); } } finally { client.stopReceiving(); } } public void addChangedWidget(Component widget) { if (client.isReceiving()) { return; } _addChangedWidget(widget); } public void _addChangedWidget(Component widget) { changedWidgetMap.put(widget.getName(), widget); } public void clearChangedWidget() { changedWidgetMap.clear(); } public Interface getInterface() { return xml; } public JSONObject updateScreenData(Interface xml, Component widget, Object obj) throws JSONException { if (!(obj instanceof JSONObject)) { return null; } JSONObject ret = new JSONObject(); JSONObject jobj = (JSONObject) obj; for (Iterator i = jobj.keys(); i.hasNext();) { String key = (String) i.next(); Component child = xml.getWidgetByLongName(widget.getName() + "." + key); Object childObj = jobj.get(key); if (child != null) { JSONObject childRet = updateScreenData(xml, child, childObj); if (childRet != null) { ret.put(key, childRet); } } } if (changedWidgetMap.containsKey(widget.getName())) { Class clazz = widget.getClass(); WidgetHandler handler = WidgetHandler.getHandler(clazz); if (handler != null) { handler.get(this, widget, ret); } } if (ret.length() <= 0) { return null; } return ret; } public synchronized void setSessionTitle(String title) { sessionTitle = title; } public synchronized void setSessionBGColor(Color color) { sessionBGColor = color; } }