/* ========================
* JSynoptic : a free Synoptic editor
* ========================
*
* Project Info: http://jsynoptic.sourceforge.net/index.html
*
* This program is free software; you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Foundation;
* either version 2.1 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
*
* (C) Copyright 2001-2005, by :
* Corporate:
* EADS Astrium SAS
* EADS CRC
* Individual:
* Claude Cazenave
*
* $Id: JDialogObjectInfo.java,v 1.1 2006/11/06 14:46:03 booba_skaya Exp $
*
*/
package simtools.ui;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.logging.Logger;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.JToolBar;
import javax.swing.KeyStroke;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;
/**
* Class JDialogObjectInfo
* This dialog permits to display informations about objects.
* It also permits to navigates easily in the fields of the objects, if their are accepted by the dialogInfo.
* You just have to implement the method: getAcceptedClass, that return the array of accepted class.
* And constructContent that fill the infos arraylist with the fields of the currently displayed object.
*/
public abstract class JDialogObjectInfo extends JDialog implements MouseListener {
/**(<b>long</b>) serialVersionUID.*/
private static final long serialVersionUID = 1787367305607254759L;
// a logger for debug purpose
static Logger logger = simtools.util.LogConfigurator.getLogger(JDialogObjectInfo.class.getName());
/**(<b>Object</b>) displayedObject: The current displayed object.*/
private Object displayedObject;
/**(<b>JTable</b>) jTableInfos: The table that displays the infos.*/
private JTable jTableInfos;
/**(<b>ArrayList</b>) infos.*/
protected ArrayList infos;
/**(<b>MenuResourceBundle</b>) resources: The resources.*/
private MenuResourceBundle resources;
/**(<b>JToolBar</b>) jToolBar: The JToolBar.*/
private JToolBar jToolBar;
/**(<b>ArrayList</b>) history: The list of displayed objects.*/
private ArrayList history;
/**(<b>int</b>) indexInHistory: The current displayed index in history.*/
private int indexInHistory;
/**(<b>JButton</b>) jButtonPrevious: The previous button.*/
private JButton jButtonPrevious;
/**(<b>String</b>) PREVIOUS_ACTION: The Key to previous Action.*/
private static final String PREVIOUS_ACTION = "previousAction";
/**(<b>String</b>) NEXT_ACTION: The key to next action.*/
private static final String NEXT_ACTION = "nextAction";
/**(<b>int</b>) DEFAULT_DIALOG_WIDTH: the default width of the dialog.*/
private static final int DEFAULT_DIALOG_WIDTH = 500;
/**(<b>String</b>) DIALOG_WIDTH: the dialog width property.*/
private static final String DIALOG_WIDTH = "jDialogObjectInfoWidth";
/**(<b>int</b>) DEFAULT_DIALOG_HEIGHT: the default dialog height.*/
private static final int DEFAULT_DIALOG_HEIGHT = 300;
/**(<b>String</b>) DIALOG_HEIGHT: the dialog width property.*/
private static final String DIALOG_HEIGHT = "jDialogObjectInfoHeight";
/**(<b>String</b>) DIALOG_COLUMN0: the dialog column0 property.*/
private static final String DIALOG_COLUMN0 = "jDialogObjectInfoColumn0PreferredWith";
/**(<b>String</b>) DIALOG_COLUMN0: the dialog column1 property.*/
private static final String DIALOG_COLUMN1 = "jDialogObjectInfoColumn1PreferredWith";
/**(<b>HashMap</b>) actions: the actions.*/
private HashMap actions;
/**(<b>JButton</b>) jButtonNext: The button next.*/
private JButton jButtonNext;
/**
* Contructor JDialogObjectInfo
* <br><b>Summary:</b><br>
* The constructor of the class JDialogObjectInfo.
* @param resources The menuResource bundle.
*/
public JDialogObjectInfo(MenuResourceBundle resources) {
super();
this.resources = resources;
if (this.resources == null) {
this.resources = new MenuResourceBundle() {
protected Object[][] getContents() {
return new Object[][] {
{ "objectInfoColumn0", "Name" },
{ "objectInfoColumn1", "Value" },
{ "previousActionAction", "<" },
{ "previousActionTip", "Go to previous displayed object." },
{ "nextActionAction", ">" },
{ "nextActionTip", "Go to next displayed object." }, };
}
};
}
initActions();
getContentPane().setLayout(new BorderLayout());
getContentPane().add(new JScrollPane(getJTableInfos()), BorderLayout.CENTER);
getContentPane().add(getJToolBar(), BorderLayout.NORTH);
setSize(300, 300);
history = new ArrayList();
indexInHistory = -1;
}
/**
* Method getAcceptedClass
* <br><b>Summary:</b><br>
* Return the array of class that can be displayed by this dialogObjectInfo.
* @return <b>(Class[])</b> The array of class that can be displayed by this dialogObjectInfo.
*/
protected abstract Class[] getAcceptedClass();
/**
* Method initActions
* <br><b>Summary:</b><br>
* Init the actions.
*/
private void initActions() {
actions = new HashMap();
actions.put(NEXT_ACTION, new NextAction());
actions.put(PREVIOUS_ACTION, new PreviousAction());
}
/**
* Method getJToolBar
* <br><b>Summary:</b><br>
* This method construct the JToolBar.
* @return JToolBar The JToolBar.
*/
private JToolBar getJToolBar() {
if (jToolBar == null) {
jToolBar = new JToolBar();
jToolBar.add(getJButtonPrevious());
jToolBar.add(getJButtonNext());
}
return jToolBar;
}
/**
* Method getJButtonNext
* <br><b>Summary:</b><br>
* return the next button
* @return <b>(JButton)</b> The next button.
*/
private JButton getJButtonNext() {
if (jButtonNext == null) {
jButtonNext = new JButton((AbstractAction) actions.get(NEXT_ACTION));
}
return jButtonNext;
}
/**
* Method getJButtonPrevious
* <br><b>Summary:</b><br>
* Return the previous button.
* @return <b>(JButton)</b> The previous button.
*/
private JButton getJButtonPrevious() {
if (jButtonPrevious == null) {
jButtonPrevious = new JButton((AbstractAction) actions.get(PREVIOUS_ACTION));
}
return jButtonPrevious;
}
/**
* Method getJTableInfos
* <br><b>Summary:</b><br>
* This method return the JTable that displays the infos.
* @return <b>(JTable)</b> The JTableInfos.
*/
private JTable getJTableInfos() {
if (jTableInfos == null) {
jTableInfos = new JTable() {
/* (non-Javadoc)
* @see javax.swing.JTable#getCellRenderer(int, int)
*/
public TableCellRenderer getCellRenderer(int row, int column) {
//The result
TableCellRenderer result = null;
if (column == TableModelObjectInfo.NAME_COLUMN) {
result = super.getCellRenderer(row, column);
} else {
result = new TableCellRendererObjectInfo();
}
//return the result
return result;
}
};
infos = new ArrayList();
//Set the table Model
jTableInfos.setModel(new TableModelObjectInfo(infos, resources));
//Add this as mouseListener
jTableInfos.addMouseListener(this);
}
//return the table
return jTableInfos;
}
/**
* Method setDisplayedObject
* <br><b>Summary:</b><br>
* This method permits to display a new object.
* Remove old content, if any.
* @param object The new object to be displayed.
*/
public void setDisplayedObject(Object object) {
//remove all object after current index not to disturb during navigation.
history = new ArrayList(history.subList(0, indexInHistory + 1));
//add the requested object to history, but only if not already the last one (not to make doublon).
int lastIndex = history.lastIndexOf(object);
int historySize = history.size();
if (lastIndex == -1 || lastIndex != historySize - 1) {
history.add(object);
}
//go to last of history(the newly added object).
setDisplayedIndex(history.size() - 1);
}
/**
* Method setDisplayedIndex
* <br><b>Summary:</b><br>
* Display the object at the given index in history.
* @param i the index of the object to be displayed in the history.
*/
private void setDisplayedIndex(int i) {
//Retrieve the object to be displayed in history.
Object object = history.get(i);
//erase previous one.
if (displayedObject != null) {
//If there was a displayed object, remove old content.
infos.clear();
}
//set the new displayed object
displayedObject = object;
indexInHistory = i;
//And construct the new content.
constructContent();
//refresh table.
((DefaultTableModel) getJTableInfos().getModel()).fireTableDataChanged();
//refresh the actions.
refreshActions();
}
/**
* Method refreshActions
* <br><b>Summary:</b><br>
* refresh the actions availability.
*/
private void refreshActions() {
//update next and previous actions, depending on the current position in history.
//previous is available only if index if positive.
if (indexInHistory > 0) {
((AbstractAction) actions.get(PREVIOUS_ACTION)).setEnabled(true);
} else {
((AbstractAction) actions.get(PREVIOUS_ACTION)).setEnabled(false);
}
//next is available, if we have not reach end of history.
if (indexInHistory < (history.size() - 1)) {
((AbstractAction) actions.get(NEXT_ACTION)).setEnabled(true);
} else {
((AbstractAction) actions.get(NEXT_ACTION)).setEnabled(false);
}
}
/**
* Method constructContent
* <br><b>Summary:</b><br>
* This method construct the content of the dialog.
* Must construct the infos in function of the current displayedObject object.
*/
protected abstract void constructContent();
/**
* Class Info
* A simple class to display info.
*/
public class Info {
/**(<b>String</b>) name: the name of the info.*/
public String name;
/**(<b>Object</b>) value: The value of the info.*/
public Object value;
/**
* Contructor Info
* <br><b>Summary:</b><br>
* The constructor of the class Info.
* @param name The name of the info.
* @param value The value of the info.
*/
public Info(String name, Object value) {
this.name = name;
this.value = value;
}
}
/**
* Class TableCellRendererObjectInfo
* A table cell renderer for the Object info dialog.
*/
private class TableCellRendererObjectInfo extends JTextArea implements TableCellRenderer {
/* (non-Javadoc)
* @see javax.swing.table.DefaultTableCellRenderer#getTableCellRendererComponent(javax.swing.JTable, java.lang.Object, boolean, boolean, int, int)
*/
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
boolean hasFocus, int row, int column) {
//If value is an instance of the accepted class, paint it in blue.
boolean accepted = false;
for (int i = 0; i < getAcceptedClass().length && !accepted; i++) {
if (value != null && getAcceptedClass()[i].isAssignableFrom(value.getClass())) {
accepted = true;
//The value's object can be displayed by the dialog.
setForeground(Color.blue);
}
}
if (value != null) {
setText(value.toString());
}
setLineWrap(true);
setWrapStyleWord(true);
int height_wanted = (int) getPreferredSize().getHeight();
if (height_wanted != table.getRowHeight(row))
table.setRowHeight(row, height_wanted);
return this;
}
}
public void mouseClicked(MouseEvent e) {
//control dblClick
if ((e.getModifiers() == MouseEvent.BUTTON1_MASK) && (e.getClickCount() == 2)) {
//In case of a double click, open the clicked info, if possible.
//retrieve the object clicked.
int selectedRow = jTableInfos.getSelectedRow();
if (selectedRow != -1) {
Object selectedObject = jTableInfos.getValueAt(selectedRow, TableModelObjectInfo.VALUE_COLUMN);
if (selectedObject != null) {
setDisplayedObject(selectedObject);
}
}
}
}
public void mouseEntered(MouseEvent e) {
//nothing to do.
}
public void mouseExited(MouseEvent e) {
//nothing to do.
}
public void mousePressed(MouseEvent e) {
//nothing to do.
}
public void mouseReleased(MouseEvent e) {
//nothing to do.
}
/**
* Class NextAction
* The action to go to next.
*/
class NextAction extends AbstractAction {
public NextAction() {
initAction(resources, this, NEXT_ACTION);
}
public void actionPerformed(ActionEvent e) {
nextAction();
}
}
/**
* Method nextAction
* <br><b>Summary:</b><br>
* Go to next object properties.
* @return <b>(void)</b> A void.
*/
public void nextAction() {
//go to next in history.
setDisplayedIndex(indexInHistory + 1);
}
/**
* Class PreviousAction
* The action to go to previous.
*/
class PreviousAction extends AbstractAction {
public PreviousAction() {
initAction(resources, this, PREVIOUS_ACTION);
}
public void actionPerformed(ActionEvent e) {
previousAction();
}
}
/**
* Method previousAction
* <br><b>Summary:</b><br>
* Go to previous object properties.
* @return <b>(void)</b> A void.
*/
public void previousAction() {
//go to previous in history.
setDisplayedIndex(indexInHistory - 1);
}
/**
* Method initAction
* <br><b>Summary:</b><br>
* Initialise an action using its label.
* @param res The resource bundle to be used.
* @param action The action to be initialised.
* @param resLabel The action tag to retrieve in bundle.
*/
private static void initAction(MenuResourceBundle res, Action action, String resLabel) {
action.putValue(Action.NAME, res.getStringValue(resLabel + "Action"));
ImageIcon i = res.getIcon(resLabel + "Image");
if (i == null) {
i = res.getIcon("nullImage");
}
action.putValue(Action.SMALL_ICON, i);
KeyStroke k = res.getKeyStroke(resLabel + "Shortcut");
if (k != null) {
action.putValue(Action.ACCELERATOR_KEY, k);
}
String tip = res.getStringValue(resLabel + "Tip");
action.putValue(Action.SHORT_DESCRIPTION, tip);
}
/**
* Method getDisplayedObject
* <br><b>Summary:</b><br>
* @return the displayedObject
*/
protected Object getDisplayedObject() {
return displayedObject;
}
/**
* Method addInfo
* <br><b>Summary:</b><br>
* This method permits to add an info on the current displayed object.
* If this info's type can be displayed by the dialog, it will be displayed in blue.
* @param name The name of the info.
* @param info The info.
*/
public void addInfo(String name, Object info) {
infos.add(new Info(name, info));
}
/**
* Method setUserProperties
* <br><b>Summary:</b><br>
* This method permits to initialize the dialog properties.
* @param up The userProperties to be used to set the dialog.
*/
public void setUserProperties(UserProperties up) {
int width = up.getInt(DIALOG_WIDTH, DEFAULT_DIALOG_WIDTH);
int height = up.getInt(DIALOG_HEIGHT, DEFAULT_DIALOG_HEIGHT);
setSize(width, height);
if (jTableInfos != null) {
jTableInfos.getColumnModel().getColumn(0).setPreferredWidth(up.getInt(DIALOG_COLUMN0, width / 3));
jTableInfos.getColumnModel().getColumn(1).setPreferredWidth(up.getInt(DIALOG_COLUMN1, width * 2 / 3));
}
}
/**
* Method getUserProperties
* <br><b>Summary:</b><br>
* use this to retrieve in the given userProperties the current dialog properties.
* @param up The user properties to store the current dialog properties.
*/
public void getUserProperties(UserProperties up) {
Dimension d = getSize();
if (d.width == 0 || d.height == 0) {
d.width = up.getInt(DIALOG_WIDTH, DEFAULT_DIALOG_WIDTH);
d.height = up.getInt(DIALOG_HEIGHT, DEFAULT_DIALOG_HEIGHT);
}
up.setInt(DIALOG_WIDTH, d.width);
up.setInt(DIALOG_HEIGHT, d.height);
if (jTableInfos != null) {
up.setInt(DIALOG_COLUMN0, jTableInfos.getColumnModel().getColumn(0).getWidth());
up.setInt(DIALOG_COLUMN1, jTableInfos.getColumnModel().getColumn(1).getWidth());
}
}
}