//{HEADER
/**
* This class is part of jnex 'Nexirius Application Framework for Java'
*
* Copyright (C) Nexirius GmbH, CH-4450 Sissach, Switzerland (www.nexirius.ch)
*
* <p>This library is free software; you can redistribute it and/or<br>
* modify it under the terms of the GNU Lesser General Public<br>
* License as published by the Free Software Foundation; either<br>
* version 2.1 of the License, or (at your option) any later version.</p>
*
* <p>This library is distributed in the hope that it will be useful,<br>
* but WITHOUT ANY WARRANTY; without even the implied warranty of<br>
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU<br>
* Lesser General Public License for more details.</p>
*
* <p>You should have received a copy of the GNU Lesser General Public<br>
* License along with this library; if not, write to the Free Software<br>
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA</p>
* </blockquote>
*
* <p>
* Nexirius GmbH, hereby disclaims all copyright interest in<br>
* the library jnex' 'Nexirius Application Framework for Java' written<br>
* by Marcel Baumann.</p>
*/
//}HEADER
package com.nexirius.framework.datacontroller;
import com.nexirius.framework.application.DialogManager;
import com.nexirius.framework.application.ErrorMessageException;
import com.nexirius.framework.datamodel.*;
import com.nexirius.framework.dataviewer.DataViewer;
import com.nexirius.framework.dataviewer.ViewerCreator;
import com.nexirius.framework.dataviewer.ViewerFactory;
import com.nexirius.framework.layout.DefaultLayoutItem;
import com.nexirius.framework.command.Command;
import com.nexirius.util.CopyPairs;
import javax.swing.*;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Iterator;
/**
* This class controls a simple popup window. It uses the DialogManager to create a JDialog window.
* Based on the parameters it creates a modal or nonmodal dialog window.
* <pre>
* PopupController controller = new PopupController(factory);
* <p/>
* controller.setClientModel(exampleModel, true, null, null, null);
* <p/>
* controller.popup(true);
* <p/>
* </pre>
*
* @author Marcel Baumann
*/
public class PopupController extends DataController {
ViewerFactory factory;
PopupModel popupModel = new PopupModel("Popup");
JComponent clientComponent = null;
DataModel orig = null;
DataModel popupDialogModel = null;
DataModelCommandVector clientMethods;
JDialog dialog;
boolean okPressed = false;
String title = null;
protected CopyPairs copyPairs;
private DataViewer clientAreaDataViewer;
public PopupController(ViewerFactory factory) {
this.factory = factory;
}
/**
* Set the model which will be displayed in the client area of the popup window
*
* @param orig the data model instance which will be displayed in the popup window
* @param duplicate If true then the model will be duplicated before it will be displayed
* @param clientMethods All the methods which should be displayed as buttons in the dialog window. If
* this parameter is null, then all the methods which are defined in the DataModel will be displayed
* as buttons on the dialog window.
* @param vc The viewer creator which will be used to translate the data model into a the dialog section
* @param layout The layout which will be used to translate the data model into a the dialog section
*/
public void setClientModel(DataModel orig, boolean duplicate, DataModelCommandVector clientMethods, ViewerCreator vc, DefaultLayoutItem layout)
throws Exception {
this.orig = orig;
popupModel.setShowHelp(false);
popupModel.setShowCloseOnly(!duplicate);
if (duplicate) {
copyPairs = new CopyPairs();
popupDialogModel = orig.duplicate(null, copyPairs);
popupDialogModel.addSoftDataModelListener(this); // activate this controller also for the dialog model
if (clientMethods != null) {
DataModelCommandVector duplicateMethods = new DataModelCommandVector();
for (DataModelCommand command = clientMethods.firstItem(); command != null; command = clientMethods.nextItem()) {
try {
duplicateMethods.addElement(popupDialogModel.getViewableChild(command.getCommandName()));
} catch (Exception ex) {
ex.printStackTrace();
}
}
clientMethods = duplicateMethods;
}
} else {
popupDialogModel = orig;
}
setClientMethods(clientMethods);
if (vc == null) {
clientAreaDataViewer = factory.createViewer(popupDialogModel, true);
} else {
clientAreaDataViewer = factory.createViewer(vc, popupDialogModel);
}
clientAreaDataViewer.setLayout(layout);
setClientComponent(clientAreaDataViewer.getJComponent());
popupDialogModel.fireEditEvent(popupModel, DataModelEvent.START_EDIT, this);
}
public DataViewer getClientAreaDataViewer() {
return clientAreaDataViewer;
}
/**
* The controller which is used to handle the client area of the dialog window.
* Use this method instead setClientModel if you are using the DataController to handle all
* data model method calls.
*
* @param clientController The controller which holds the client model and its data viewer
* @param clientMethods the client model methods which should be displayed at the bottom of the dialog window
*/
public void setClientController(DataController clientController, DataModelCommandVector clientMethods) {
setClientMethods(clientMethods);
clientController.setParentController(this);
setClientComponent(clientController.getDataViewer().getJComponent());
}
/**
* set the window title (will be translated with ClientResource.getLabel
*
* @param title if null (default) then the name of the model will be used instead
*/
public void setTitle(String title) {
this.title = title;
if (dialog != null) {
dialog.setTitle(getTitle());
}
}
/**
* access the current title
*
* @return the title string or the name of the model or ""
*/
public String getTitle() {
String ret = title;
if (ret == null) {
if (orig != null) {
ret = orig.getCaption();
}
if (ret == null) {
ret = "";
}
}
ret = getLabel(ret);
return ret;
}
/**
* Return the translation of a string
*
*/
public String getLabel(String text) {
if (factory != null && text != null) {
text = factory.getClientResource().getLabel(text);
}
if (text == null) {
text = "";
}
return text;
}
/**
* This method creates the dialog window and calls center on the DialogManager.
* Based on the way this window was closed this method returns true or false.
*
* @param modal If true then a modal JDialog will be used
* @return true if ok was pressed to close the window, else false
*/
public boolean popup(boolean modal) {
okPressed = false;
dialog = DialogManager.createJDialog(getTitle(), modal);
if (getClientAreaDataViewer() != null && getClientAreaDataViewer().getViewerName() != null) {
dialog.setName(getClientAreaDataViewer().getViewerName());
}
dialog.addWindowListener(new MyWindowListener());
dialog.getContentPane().setLayout(new GridLayout(1, 1));
JComponent comp = getDialogComponent();
if (comp != null) {
dialog.getContentPane().add(comp);
}
dialog.pack();
DialogManager.popup(dialog);
return okPressed;
}
public JComponent getDialogComponent() {
JPanel mainPanel = new JPanel(new BorderLayout());
JComponent clientComponent = getClientComponent();
Dimension d = clientComponent.getPreferredSize();
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
// automatically generate a scrolled dialog window if the client component is too large
if (!(clientComponent instanceof JScrollPane) && d.height + 100 > screenSize.height || d.width + 20 > screenSize.width) {
JScrollPane jScrollPane = new JScrollPane(clientComponent);
jScrollPane.getVerticalScrollBar().setUnitIncrement(40);
clientComponent = jScrollPane;
}
mainPanel.add(clientComponent, BorderLayout.CENTER);
try {
JPanel buttonPanel = new JPanel(new GridBagLayout());
Insets insets = new Insets(10, 3, 10, 3);
GridBagConstraints lineConstr = new GridBagConstraints(0, 0, 2, 1, 1.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(2, 0, 0, 0), 0, 0);
GridBagConstraints leftConstr = new GridBagConstraints(0, 1, 1, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, insets, 0, 0);
GridBagConstraints rightConstr = new GridBagConstraints(1, 1, 1, 1, 1.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE, insets, 0, 0);
buttonPanel.add(new JSeparator(), lineConstr);
buttonPanel.add(createStandardButtonComponent(factory), rightConstr);
try {
String defaultCommandName = null;
if (clientMethods != null) {
for (Iterator iterator = clientMethods.iterator(); iterator.hasNext();) {
Command command = (Command) iterator.next();
if (command.isDefaultButton()) {
defaultCommandName = command.getCommandName();
break;
}
}
}
if (defaultCommandName == null) {
defaultCommandName = popupModel.getDefaultCommand().getCommandName();
}
dialog.getRootPane().setDefaultButton((JButton) getDataViewer().getSubcomponent(defaultCommandName));
} catch (Exception ex) {
ex.printStackTrace();
}
buttonPanel.add(createDialogButtonComponent(factory), leftConstr);
mainPanel.add(buttonPanel, BorderLayout.SOUTH);
} catch (Exception e) {
e.printStackTrace();
}
return mainPanel;
}
public JComponent createStandardButtonComponent(ViewerFactory factory)
throws Exception {
DataViewer popupViewer = factory.createViewer(getPopupModel(), true);
this.setDataViewer(popupViewer);
return popupViewer.getJComponent();
}
public JComponent createDialogButtonComponent(ViewerFactory factory)
throws Exception {
JPanel buttonPanel = new JPanel(new GridBagLayout());
JComponent button = null;
DataModelCommand command;
DataViewer buttonViewer;
DataModelCommandVector commandVector = clientMethods;
GridBagConstraints buttonConstr = new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 2, 0, 2), 0, 0);
if (commandVector == null && popupDialogModel != null) {
commandVector = popupDialogModel.getMethods();
}
if (commandVector != null) {
for (command = commandVector.firstItem(); command != null; command = commandVector.nextItem()) {
buttonViewer = factory.createDefaultEditor(command);
button = buttonViewer.getJComponent();
buttonPanel.add(button, buttonConstr);
++buttonConstr.gridx;
if (command.isDefaultButton()) {
dialog.getRootPane().setDefaultButton((JButton) button);
}
}
}
return buttonPanel;
}
public boolean popdown() {
if (dialog == null) {
return okPressed;
}
dialog.setVisible(false);
dialog.dispose();
dialog = null;
return okPressed;
}
public boolean doHandleMethodCall(String methodName, boolean fromChild, DataModel source) {
if (methodName.equals(PopupModel.OK_COMMAND)) {
if (this.popupDialogModel != null && this.popupDialogModel != this.orig) {
try {
if (popupDialogModel.isValid()) {
popupDialogModel.fireEditEvent(popupModel, DataModelEvent.FINISH_EDIT, this);
orig.assignDuplicate(popupDialogModel, copyPairs);
okPressed = true;
popdown();
return true;
} else {
return true;
}
} catch (Exception e) {
if (e instanceof ErrorMessageException) {
throw (ErrorMessageException)e;
} else {
throw new ErrorMessageException("Error: " + e.getMessage(), e, null);
}
}
}
okPressed = true;
popdown();
return false;
} else if (methodName.equals(PopupModel.CANCEL_COMMAND) || methodName.equals(PopupModel.CLOSE_COMMAND)) {
okPressed = false;
popdown();
return true;
}
return false;
}
class MyWindowListener extends WindowAdapter {
public void windowClosing(WindowEvent event) {
popdown();
}
}
public DataModelCommandVector getClientMethods() {
return clientMethods;
}
public void setClientMethods(DataModelCommandVector vector) {
clientMethods = vector;
}
public ViewerFactory getFactory() {
return factory;
}
public void setFactory(ViewerFactory factory) {
this.factory = factory;
}
public PopupModel getPopupModel() {
return popupModel;
}
public void setPopupModel(PopupModel model) {
popupModel = model;
}
public void setClientComponent(JComponent clientComponent) {
this.clientComponent = clientComponent;
}
public JComponent getClientComponent() {
return clientComponent;
}
}