| /******************************************************************************* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| *******************************************************************************/ |
| package org.ofbiz.pos.screen; |
| |
| import java.awt.Component; |
| import java.awt.Container; |
| import java.awt.Dimension; |
| import java.awt.Frame; |
| import java.awt.Point; |
| import java.awt.Window; |
| import java.awt.event.ActionEvent; |
| import java.awt.event.ActionListener; |
| import java.awt.event.WindowEvent; |
| import java.awt.event.WindowListener; |
| import java.awt.event.FocusListener; |
| import java.awt.event.FocusEvent; |
| import java.awt.event.ComponentListener; |
| import java.awt.event.ComponentEvent; |
| import javax.swing.JButton; |
| import javax.swing.JDialog; |
| import javax.swing.JRootPane; |
| import javax.swing.SwingUtilities; |
| |
| import net.xoetrope.swing.XButton; |
| import net.xoetrope.swing.XTextArea; |
| import net.xoetrope.xui.XPage; |
| import net.xoetrope.xui.XProjectManager; |
| |
| import org.ofbiz.base.util.Debug; |
| import org.ofbiz.base.util.cache.Cache; |
| import org.ofbiz.base.util.cache.UtilCache; |
| |
| public class PosDialog { |
| |
| public static final String module = PosDialog.class.getName(); |
| private static final Cache<XPage, PosDialog> instances = UtilCache.createUtilCache("pos.Dialogs", 0, 0); |
| |
| protected final Frame clientFrame = XProjectManager.getCurrentProject().getAppFrame(); |
| protected final Window appWindow = XProjectManager.getCurrentProject().getAppWindow(); |
| |
| protected DialogCallback cb = null; |
| protected Component parent = null; |
| |
| protected JDialog dialog = null; |
| protected XTextArea output = null; |
| protected XButton closeBtn = null; |
| protected XPage page = null; |
| protected boolean modal = true; |
| protected int padding = 0; |
| protected boolean posDialogVisible = false; |
| |
| public static PosDialog getInstance(XPage page) { |
| return getInstance(page, true, 0); |
| } |
| |
| public static PosDialog getInstance(XPage page, boolean modal, int padding) { |
| PosDialog dialog = instances.get(page); |
| if (dialog == null) { |
| dialog = instances.putIfAbsentAndGet(page, new PosDialog(page, modal, padding)); |
| } |
| |
| dialog.modal = modal; |
| dialog.padding = padding; |
| dialog.pack(); |
| return dialog; |
| } |
| |
| protected PosDialog(XPage page, boolean modal, int padding) { |
| this.page = page; |
| this.modal = modal; |
| this.padding = padding; |
| this.configure(); |
| } |
| |
| protected void configure() { |
| // create the new dialog box |
| this.dialog = new JDialog(clientFrame, "Alert", modal); |
| dialog.setUndecorated(true); |
| dialog.setResizable(false); |
| dialog.setSize(page.getSize()); |
| dialog.getRootPane().setWindowDecorationStyle(JRootPane.PLAIN_DIALOG); |
| |
| // find the output edit object |
| this.output = (XTextArea) page.findComponent("dialog_output"); |
| if (this.output != null) { |
| this.output.setWrapStyleWord(true); |
| this.output.setLineWrap(true); |
| this.output.setEditable(false); |
| } |
| |
| // set the page pieces |
| Component[] coms = page.getComponents(); |
| for (int i = 0; i < coms.length; i++) { |
| dialog.getContentPane().add(coms[i]); |
| coms[i].setVisible(true); |
| } |
| |
| // set the close button |
| this.setCloseBtn(dialog); |
| |
| // fix the layout and size |
| this.pack(); |
| |
| // adjust the dialog location |
| Dimension wSize = dialog.getSize(); |
| dialog.setLocation(appWindow.getLocation().x + (appWindow.getSize().width / 2 - wSize.width / 2), |
| appWindow.getLocation().y + (appWindow.getSize().height / 2 - wSize.height / 2)); |
| |
| // set the component listener |
| final PosDialog thisPosDialog = this; |
| dialog.addComponentListener(new ComponentListener() { |
| |
| public void componentResized(ComponentEvent event) { |
| this.reset(); |
| } |
| |
| public void componentMoved(ComponentEvent event) { |
| this.reset(); |
| } |
| |
| public void componentShown(ComponentEvent event) { |
| this.reset(); |
| } |
| |
| public void componentHidden(ComponentEvent event) { |
| this.reset(); |
| } |
| |
| public void reset() { |
| if (dialog.isEnabled()) { |
| thisPosDialog.checkSize(); |
| Dimension wSize = dialog.getSize(); |
| dialog.setLocation(appWindow.getLocation().x + (appWindow.getSize().width / 2 - wSize.width / 2), |
| appWindow.getLocation().y + (appWindow.getSize().height / 2 - wSize.height / 2)); |
| dialog.requestFocus(); |
| } |
| } |
| }); |
| |
| // set the window listener |
| dialog.addWindowListener(new WindowListener() { |
| public void windowClosing(WindowEvent e) { |
| close(); |
| } |
| |
| public void windowActivated(WindowEvent e) { |
| } |
| |
| public void windowDeactivated(WindowEvent e) { |
| this.reset(); |
| } |
| |
| public void windowClosed(WindowEvent e) { |
| } |
| |
| public void windowOpened(WindowEvent e) { |
| } |
| |
| public void windowDeiconified(WindowEvent e) { |
| } |
| |
| public void windowIconified(WindowEvent e) { |
| } |
| |
| public void reset() { |
| // always keep focus if we are enabled |
| if (dialog.isEnabled()) { |
| dialog.requestFocus(); |
| } |
| } |
| }); |
| |
| // set the focus listener |
| dialog.addFocusListener(new FocusListener() { |
| |
| public void focusGained(FocusEvent event) { |
| } |
| |
| public void focusLost(FocusEvent event) { |
| if (dialog.isEnabled()) { |
| Component focused = event.getOppositeComponent(); |
| if (focused == null || !"closeBtn".equals(focused.getName())) { |
| dialog.requestFocus(); |
| } |
| } |
| } |
| }); |
| } |
| |
| public void showDialog(Container parent, DialogCallback cb, String text) { |
| this.parent = parent; |
| this.cb = cb; |
| if (text != null) { |
| this.setText(text); |
| } |
| |
| // don't allow the main window to take focus |
| appWindow.setFocusable(false); |
| parent.setFocusable(false); |
| |
| dialog.setFocusable(true); |
| dialog.setEnabled(true); |
| dialog.requestFocus(); |
| dialog.repaint(); |
| dialog.pack(); |
| posDialogSetVisible(true); |
| } |
| |
| public void setText(String text) { |
| if (this.output != null) { |
| this.output.setText(text); |
| } else if (this.closeBtn != null) { |
| this.closeBtn.setText("<html><center>" + text + "</center></html>"); |
| } else { |
| Debug.logInfo("PosDialog output edit box is NULL!", module); |
| } |
| } |
| |
| public String getName() { |
| return page.getName(); |
| } |
| |
| protected void close() { |
| // close down the dialog |
| dialog.setEnabled(false); |
| dialog.setVisible(false); |
| dialog.setFocusable(false); |
| |
| // refocus the parent window |
| appWindow.setFocusable(true); |
| appWindow.requestFocus(); |
| parent.setFocusable(true); |
| parent.requestFocus(); |
| |
| // callback the parent |
| if (cb != null) { |
| cb.receiveDialogCb(this); |
| } |
| } |
| |
| private void setCloseBtn(Container con) { |
| Component[] coms = con.getComponents(); |
| for (int i = 0; i < coms.length; i++) { |
| if (coms[i].getName() != null && "closeBtn".equals(coms[i].getName())) { |
| if (coms[i] instanceof XButton) { |
| this.closeBtn = (XButton) coms[i]; |
| JButton b = (JButton) coms[i]; |
| b.addActionListener(new ActionListener() { |
| public void actionPerformed(ActionEvent event) { |
| dialog.setEnabled(false); |
| close(); |
| } |
| }); |
| } else { |
| Debug.logWarning("Found component with name 'closeBtn' but was not an instance of JButton", module); |
| } |
| } else if (coms[i] instanceof Container) { |
| setCloseBtn((Container) coms[i]); |
| } else { |
| coms[i].requestFocus(); |
| } |
| } |
| } |
| |
| private void pack() { |
| Dimension pageSize = page.getSize(); |
| if (pageSize.getHeight() > 0 || pageSize.getWidth() > 0) { |
| dialog.setSize(page.getSize()); |
| } else { |
| Container contentPane = dialog.getContentPane(); |
| Point size = this.getMaxCoordinates(contentPane); |
| this.setSize(size.x + 2 * padding + 2, size.y + 2 * padding + 4); |
| } |
| } |
| |
| private void checkSize() { |
| Dimension wSize = dialog.getSize(); |
| |
| Container contentPane = dialog.getContentPane(); |
| Point size = this.getMaxCoordinates(contentPane); |
| size.x += 2 * padding + 2; |
| size.y += 2 * padding + 4 + 2; |
| if (size.x != wSize.width || size.y != wSize.height) { |
| this.pack(); |
| } |
| } |
| |
| private void setSize(int width, int height) { |
| dialog.getContentPane().setBounds(padding, padding, width - (padding * 2), height - (padding * 2)); |
| dialog.setSize(width, height + 2); |
| } |
| |
| private Point getMaxCoordinates(Container cont) { |
| Point pt = cont.getLocation(); |
| |
| int maxX = pt.x; |
| int maxY = pt.y; |
| int numChildren = cont.getComponentCount(); |
| |
| for (int i = 0; i < numChildren; i++) { |
| Component comp = cont.getComponent(i); |
| Dimension size = comp.getSize(); |
| Point p = comp.getLocation(); |
| maxX = Math.max(pt.x + p.x + size.width, maxX); |
| maxY = Math.max(pt.y + p.y + size.height, maxY); |
| if (comp instanceof Container) { |
| Point childDim = this.getMaxCoordinates((Container) comp); |
| maxX = Math.max(childDim.x, maxX); |
| maxY = Math.max(childDim.y, maxY); |
| } |
| } |
| |
| return new Point(maxX, maxY); |
| } |
| |
| public void posDialogSetVisible(boolean visible) { |
| posDialogVisible = visible; |
| SwingUtilities.invokeLater( |
| new Runnable() { |
| public void run() { |
| dialog.setVisible(posDialogVisible); |
| } |
| } |
| ); |
| } |
| |
| } |