//{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.application;
import com.nexirius.framework.datacontroller.PopupController;
import com.nexirius.framework.dataeditor.PopupEditorAdaptor;
import com.nexirius.framework.datamodel.*;
import com.nexirius.framework.dataviewer.DataViewer;
import com.nexirius.framework.dataviewer.LayoutItem;
import com.nexirius.framework.dataviewer.ViewerCreator;
import com.nexirius.framework.dataviewer.ViewerFactory;
import com.nexirius.framework.gadgets.ErrorAdaptor;
import com.nexirius.framework.layout.DefaultLayoutItem;
import com.nexirius.framework.menu.ApplicationMenu;
import com.nexirius.util.locale.LocaleManager;
import com.nexirius.util.locale.LocaleManagerImpl;
import com.nexirius.util.resource.ClientResource;
import com.nexirius.util.XString;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.border.EtchedBorder;
import java.awt.*;
import java.awt.event.*;
import java.text.MessageFormat;
/**
* This class creates an application window (JFrame) and support automatic menu and toolbar generation
* as well as initialisation of client resources and viewer factory and command processor and DialogManager
*/
public abstract class Application implements WindowListener, AskAdaptor, ErrorAdaptor, PopupEditorAdaptor {
private LocaleManager localeManager = null;
protected DataModelCommandVector applicationCommands = null;
private StringModel statusLineModel = new StringModel("", "statusLineModel");
protected String argv[];
protected JFrame mainFrame = null;
protected JPanel mainPanel = null;
protected JComponent toolBar = null;
protected ViewerFactory factory = null;
protected ProgressAdaptorModel progressAdaptorModel = new ProgressAdaptorModel();
public Application(String argv[]) {
this.argv = argv;
}
public abstract String getApplicationName();
public abstract DataModel getApplicationModel();
/**
* starts the application
* calls
* <PRE>
* preInit();
* createApplication();
* init();
* getMainFrame().setVisible(true);
* postInit();
* </PRE>
*/
public void run() {
try {
initialise();
} catch (Exception ex) {
ex.printStackTrace();
}
}
/**
* @return the application title (is used as the the title of the main frame)
*/
public String getApplicationTitle() {
return getApplicationName();
}
/**
* access the client resource implementation (see getApplicationName())
*/
public ClientResource getClientResource() {
return getFactory().getClientResource();
}
/**
* translate a text resource (using the client resource implementation)
*/
public String getText(String text) {
String ret = text;
if (getClientResource() == null) {
return ret;
}
ret = getClientResource().getText(text);
if (ret == null) {
ret = text;
}
return ret;
}
/**
* access the locale manager
*/
public LocaleManager getLocaleManager() {
if (this.localeManager == null) {
this.localeManager = new LocaleManagerImpl();
}
return this.localeManager;
}
/**
* access the current ViewerFactory which is based on the current client resource implementation
*/
public ViewerFactory getFactory() {
if (factory == null) {
try {
factory = ViewerFactory.getDefaultInstance(getApplicationName());
getLocaleManager().addLocaleListener(factory.getClientResource());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
return factory;
}
/**
* access the status line model
* redefine this method to introduce a special DataModel to be used on the bottom of the application
* the default implementation for this is a StringModel
*/
public DataModel getStatusLineModel() {
return statusLineModel;
}
/**
* creates the main frame and initialises the title to whatever is retutned by getApplicationTitle()
*/
protected void createFrame() {
mainFrame = new JFrame(getApplicationTitle());
Icon icon = getClientResource().getIcon("Application");
//DialogManager.toplevelFrame = mainFrame;
DialogManager.setApplicationFrame(mainFrame);
if (icon != null && icon instanceof ImageIcon) {
mainFrame.setIconImage(((ImageIcon) icon).getImage());
}
mainFrame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
mainPanel = new JPanel();
mainPanel.setBorder(new EtchedBorder());
mainFrame.getContentPane().setLayout(new BorderLayout());
mainFrame.getContentPane().add(BorderLayout.CENTER, mainPanel);
}
/**
* updates the currently displayed application title (accesses getApplicationTitle())
*/
public void updateApplicationTitle() {
if (mainFrame != null) {
mainFrame.setTitle(getApplicationTitle());
}
}
/**
* implementation of the PopupEditorAdaptor interface
*/
public boolean popupEdit(DataModel dataModel, boolean reuse) {
return popupEdit(dataModel, null, null, reuse);
}
/**
* implementation of the PopupEditorAdaptor interface
*/
public boolean popupEdit(DataModel dataModel) {
return popupEdit(dataModel, null, null, false);
}
/**
* implementation of the PopupEditorAdaptor interface
*/
public boolean popupEdit(DataModel dataModel, ViewerCreator creator) {
return popupEdit(dataModel, creator, null, false);
}
/**
* implementation of the PopupEditorAdaptor interface
*
* @param dataModel the model which will be translated into a dialog window
* @param creator the creator (or null for default creator) which translates the model into an editor
* @param layout the layout (or null for default or not used by creator)
* @param reuse deprecated
* @deprecated
*/
public boolean popupEdit(DataModel dataModel, ViewerCreator creator, LayoutItem layout, boolean reuse) {
if (reuse) {
new Exception("reuse == true is not supported anymore").printStackTrace();
}
return popupEdit(dataModel, creator, layout);
}
/**
* implementation of the PopupEditorAdaptor interface
*
* @param dataModel the model which will be translated into a dialog window
* @param creator the creator (or null for default creator) which translates the model into an editor
* @param layout the layout (or null for default or not used by creator)
* @param duplicateModel duplicate model (show ok and cancel button if true else only close button)
* @param commands use dataModel.getMethods() or null (no buttons are visible on the lefthand bottom side)
* @return true if ok was pressed on the dialog window
*/
public boolean popupEdit(DataModel dataModel, ViewerCreator creator, LayoutItem layout, boolean duplicateModel, DataModelCommandVector commands) {
PopupController controller = new PopupController(getFactory());
try {
controller.setClientModel(dataModel, duplicateModel, commands, creator, (DefaultLayoutItem) layout);
} catch (Exception e) {
e.printStackTrace();
}
return controller.popup(duplicateModel);
}
/**
* implementation of the PopupEditorAdaptor interface. Creates a window with all methods of
* the model displayed at the left bottom (with Ok and Cancel button)
*
* @param dataModel the model which will be translated into a dialog window
* @param creator the creator (or null for default creator) which translates the model into an editor
* @param layout the layout (or null for default or not used by creator)
*/
public boolean popupEdit(DataModel dataModel, ViewerCreator creator, LayoutItem layout) {
return popupEdit(dataModel, creator, layout, true, dataModel.getMethods());
}
/**
* implementation of the PopupEditorAdaptor interface
* Show dataModel in a popup window with a close button.
*/
public boolean noDuplicatePopupEdit(DataModel dataModel, ViewerCreator creator, LayoutItem layout) {
return popupEdit(dataModel, creator, layout, false, dataModel.getMethods());
}
/**
* access the main window
*/
public Frame getToplevelFrame() {
Component currParent = DialogManager.getToplevelFrame();
Frame theFrame = null;
if (currParent instanceof JDialog) {
theFrame = new Frame();
}
if (theFrame == null) {
return getMainFrame();
}
return theFrame;
}
/**
* implementation of the error adaptor interface
*/
public void error(String message, String title) {
JDialog dialog = DialogManager.createJDialog(title, true);
if (message.indexOf('\n') > 0 && !message.startsWith("<")) {
message = "<HTML><PRE>" + message + "</PRE></HTML>";
}
System.err.println(message);
JLabel label = new JLabel(message);
dialog.addWindowListener(new ErrorWindowListener());
dialog.getContentPane().setLayout(new BorderLayout());
label.setBorder(new EtchedBorder(EtchedBorder.LOWERED));
label.setHorizontalAlignment(JLabel.CENTER);
label.setBorder(new EmptyBorder(40, 40, 40, 40));
if (label.getIcon() == null) {
label.setIcon(getClientResource().getIcon("EXCLAMATION"));
}
dialog.getContentPane().add(BorderLayout.CENTER, label);
JPanel buttonPanel = new JPanel();
JButton buttons[] = new JButton[1];
buttons[0] = getFactory().createJButton("Ok", new OkListener(dialog));
buttons[0].setDefaultCapable(true);
dialog.getRootPane().setDefaultButton(buttons[0]);
getFactory().arrangeButtons(buttons, buttonPanel);
dialog.getContentPane().add(BorderLayout.SOUTH, buttonPanel);
dialog.pack();
DialogManager.showError();
DialogManager.popup(dialog);
}
/**
* implementation of the error adaptor interface
*/
public void error(String message) {
error(getText(message), getText("Error"));
}
/**
* implementation of the error adaptor interface
*/
public void error(String message, Object param[]) {
if (message == null) {
message = "Error";
}
MessageFormat f = new MessageFormat(getText(message));
error(f.format(param), getText("Error"));
}
/**
* implementation of the error adaptor interface
*/
public void warning(String message) {
if (message == null) {
message = "Warning";
}
error(getText(message), getText("Warning"));
}
/**
* implementation of the error adaptor interface
*/
public void warning(String message, Object param[]) {
MessageFormat f = new MessageFormat(getText(message));
error(f.format(param), getText("Warning"));
}
class OkListener implements ActionListener {
JDialog dialog;
public OkListener(JDialog dialog) {
this.dialog = dialog;
}
public void actionPerformed(ActionEvent e) {
//dialog.setVisible(false);
//dialog.hide();
dialog.dispose();
DialogManager.hideError();
}
}
class ErrorWindowListener extends WindowAdapter {
public void windowClosing(WindowEvent e) {
DialogManager.hideError();
}
}
/**
* implementation of the ask adaptor interface
*/
public boolean ask(String question, String answerYes, String answerNo, boolean defaultIsYes) {
return ask(question, answerYes, answerNo, defaultIsYes, false);
}
public boolean ask(String question, String answerYes, String answerNo, boolean defaultIsYes, boolean hasCancel) {
return ask(question, answerYes, answerNo, defaultIsYes, hasCancel, null);
}
/**
* implementation of the ask adaptor interface
*/
public boolean ask(String question, String answerYes, String answerNo, boolean defaultIsYes, boolean hasCancel, Object[] parameters) {
String title = getText("Question");
JDialog dialog = DialogManager.createJDialog(title, true);
if (parameters != null) {
question = MessageFormat.format(getClientResource().getLabel(question), parameters);
}
AskModel model = new AskModel("Question", question, answerYes, answerNo, defaultIsYes);
model.setHasCancel(hasCancel);
model.setAnswerListener(new AskListener(dialog));
try {
DataViewer viewer = getFactory().createDefaultViewer(model);
dialog.getContentPane().setLayout(new BorderLayout());
dialog.getContentPane().add(BorderLayout.CENTER, viewer.getJComponent());
dialog.pack();
viewer.defineDefaultButton(dialog.getRootPane());
DialogManager.popup(dialog);
} catch (Exception ex) {
ex.printStackTrace();
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
if (model.isCancel()) {
throw new RuntimeException("Cancel");
}
return model.isYes();
}
class AskListener implements DataModelListener {
JDialog dialog;
public AskListener(JDialog dialog) {
this.dialog = dialog;
}
public void dataModelChangeValue(DataModelEvent event) {
dialog.setVisible(false);
}
public void dataModelChangeStructure(DataModelEvent event) {
}
public void dataModelGrabFocus(DataModelEvent event) {
}
}
/**
* creates an application menu and the tool bar based on a text file (in the class path) getApplicationName() + ".menu"
*/
public ApplicationMenu getApplicationMenu() throws Exception {
return new ApplicationMenu(getFactory(), getApplicationModel(), applicationCommands, getApplicationName() + ".menu");
}
/**
* creates the application menu and the tool bar and attaches them to the main frame
*/
protected void createMenu()
throws Exception {
getMainFrame().setJMenuBar(getApplicationMenu().getMenuBar());
toolBar = getApplicationMenu().getToolBar();
if (toolBar != null) {
getMainFrame().getContentPane().add(BorderLayout.NORTH, toolBar);
}
}
/**
* creates the status line viewer on the bottom of the main frame based on getStatusLineModel()
*/
protected void createStatusLine()
throws Exception {
if (getStatusLineModel() != null) {
DataViewer sl = getFactory().createDefaultViewer(getStatusLineModel());
getMainFrame().getContentPane().add(BorderLayout.SOUTH, sl.getJComponent());
}
}
/**
* builds the application main frame with
* <PRE>
* applicationCommands = getApplicationModel().getMethods();
* createFrame();
* createMenu();
* createStatusLine();
* </PRE>
*/
private void createApplication()
throws Exception {
applicationCommands = getApplicationModel().getMethods();
createFrame();
createMenu();
createStatusLine();
getMainFrame().addWindowListener(this);
getClientResource().updateListeners();
}
/**
* builds the application main frame and calls init methods in the right order
* <PRE>
* preInit();
* createApplication();
* init();
* getMainFrame().setVisible(true);
* postInit();
* </PRE>
*/
protected void initialise()
throws Exception {
DialogManager.setErrorAdaptor(this);
DialogManager.setAskAdaptor(this);
DialogManager.setPopupEditorAdaptor(this);
DialogManager.setProgressAdaptor(getProgressAdaptor());
preInit();
createApplication();
init();
getMainFrame().setVisible(true);
postInit();
}
/**
* redefine this method to initialize the main model with all its method (methods whitch are part of the menu)
* Menu or toolbar items reference methods by name which are appended (appendMethod()) to the application model (main model)
*/
public void preInit() {
}
/**
* redefine this method to do all the initialize work which has to be done right before the application window is visible
*/
public void init() throws Exception {
}
/**
* redefine this method to do alll the initialisation which should be done right after the application window becomes visible
* (e.g. load most recent file)
*/
public void postInit() {
}
/**
* redefine this method to veto the actual exit
*/
public void exit() {
System.exit(0);
}
/**
* redefine this method to access the status line information�
*/
public void info(String info) {
if (info == null || info.length() == 0) {
statusLineModel.setFlag(ModelFlag.INVISIBLE, true);
}
statusLineModel.setText(info);
}
/**
* this method translates the message and sends it to the info() method
*/
public void tinfo(String info) {
info(getClientResource().getLabel(info));
}
/**
* access the main panel (which is the center of the application window)
*/
public JPanel getMainPanel() {
return mainPanel;
}
/**
* access the main frame
*/
public JFrame getMainFrame() {
return mainFrame;
}
/**
* access the DataModel which holds progress info
*/
public ProgressAdaptor getProgressAdaptor() {
return progressAdaptorModel;
}
// Window Listener
public void windowActivated(WindowEvent e) {
}
public void windowClosed(WindowEvent e) {
}
public void windowClosing(WindowEvent e) {
exit();
}
public void windowDeactivated(WindowEvent e) {
}
public void windowDeiconified(WindowEvent e) {
}
public void windowIconified(WindowEvent e) {
}
public void windowOpened(WindowEvent e) {
}
// Window Listener
}