/*
* Geotoolkit - An Open Source Java GIS Toolkit
* http://www.geotoolkit.org
*
* (C) 2007 - 2008, Open Source Geospatial Foundation (OSGeo)
* (C) 2008 - 2009, Johann Sorel
*
* This library 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;
* version 2.1 of the License.
*
* This library 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.
*/
package org.geotoolkit.gui.swing.propertyedit;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.ComponentOrientation;
import java.awt.Dimension;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingUtilities;
import org.geotoolkit.gui.swing.util.JImagePane;
import org.jdesktop.swingx.JXTaskPane;
import org.jdesktop.swingx.JXTaskPaneContainer;
/**
* Multiproperty panel.
*
* @author Johann Sorel (Geomatys)
* @author Quentin Boileau (Geomatys)
* @module
*/
public abstract class MultiPropertyPanel extends JPanel implements PropertyPane, PropertyChangeListener {
private final Map<String,List<Object>> panels = new LinkedHashMap<>();
private final JXTaskPaneContainer guiMenus = new JXTaskPaneContainer();
private final Map<String,JXTaskPane> guiGroups = new HashMap<>();
private final JImagePane guiPreview = new JImagePane();
private final JXTaskPane preview = new JXTaskPane();
private PropertyPane active = null;
private Object currentTarget = null;
/**
* Creates new form MultiPropertyPanel
*/
public MultiPropertyPanel() {
super();
initComponents();
preview.getContentPane().setLayout(new BorderLayout());
preview.add(BorderLayout.CENTER,guiPreview);
guiMenus.setBorder(BorderFactory.createEmptyBorder(6, 6, 6, 6));
guiTypesPane.setBorder(BorderFactory.createLineBorder(Color.GRAY, 1));
guiTypesPane.add(guiMenus, BorderLayout.CENTER);
typeScroll.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
}
public void addPropertyPanel(final String groupName, final PropertyPane panel) {
List<Object> lst = panels.get(groupName);
if(lst==null){
lst = new ArrayList<>();
panels.put(groupName, lst);
}
lst.add(panel);
}
public void addAction(final String groupName, final Action action) {
List<Object> lst = panels.get(groupName);
if(lst==null){
lst = new ArrayList<>();
panels.put(groupName, lst);
}
lst.add(action);
}
public boolean setSelectedPropertyPanel(final PropertyPane panel) {
if(active!=null){
if (active instanceof Component) {
((Component)active).removePropertyChangeListener(this);
}
remove(active.getComponent());
active = null;
revalidate();
repaint();
}
if (panel != null) {
if (active instanceof Component) {
((Component)active).addPropertyChangeListener(this);
}
active = panel;
active.setTarget(currentTarget);
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
final JComponent panComp = (JComponent) panel.getComponent();
add(BorderLayout.CENTER,panComp);
revalidate();
repaint();
}
});
final Image img = panel.getPreview();
guiPreview.setVisible(img!=null);
guiPreview.setImage(img);
if(img != null){
guiPreview.setPreferredSize(new Dimension(100, 140));
guiPreview.revalidate();
guiPreview.repaint();
preview.setEnabled(true);
preview.setCollapsed(false);
}else{
guiPreview.setPreferredSize(new Dimension(1, 1));
preview.setEnabled(false);
preview.setCollapsed(true);
}
return true;
}
return false;
}
/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
typeScroll = new JScrollPane();
guiTypesPane = new JPanel();
setLayout(new BorderLayout());
typeScroll.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
typeScroll.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
typeScroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
guiTypesPane.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
guiTypesPane.setLayout(new BorderLayout());
typeScroll.setViewportView(guiTypesPane);
add(typeScroll, BorderLayout.WEST);
}// </editor-fold>//GEN-END:initComponents
@Override
public void setTarget(final Object target) {
this.currentTarget = target;
//select only panels which handle this target
for(JXTaskPane tp : guiGroups.values()){
guiMenus.remove(tp);
}
guiMenus.remove(preview);
guiGroups.clear();
PropertyPane selected = null;
for (Entry<String,List<Object>> entry : panels.entrySet()) {
final String groupName = entry.getKey();
final List<Object> panels = entry.getValue();
for(final Object candidate : panels){
JXTaskPane task = guiGroups.get(groupName);
if(task==null){
task = new JXTaskPane();
task.setTitle(groupName);
task.setIcon(null);
task.setCollapsed(true);
task.setSpecial(true);
task.setEnabled(false);
guiGroups.put(groupName, task);
guiMenus.add(task);
}
final Action act;
if(candidate instanceof Action){
act = (Action) candidate;
task.setSpecial(false);
task.setCollapsed(false);
task.setEnabled(true);
}else {
final PropertyPane panel = (PropertyPane) candidate;
if(selected==null){
selected = panel;
}
act = new AbstractAction() {
{
putValue(Action.NAME, panel.getTitle());
putValue(Action.SHORT_DESCRIPTION, panel.getToolTip());
putValue(Action.SMALL_ICON, panel.getIcon());
}
public void actionPerformed(ActionEvent e) {
setSelectedPropertyPanel(panel);
}
};
if(panel.canHandle(target)){
act.setEnabled(true);
panel.setTarget(target);
//activate the group task pane
task.setCollapsed(false);
task.setSpecial(false);
task.setEnabled(true);
}else{
act.setEnabled(false);
panel.setTarget(null);
}
}
task.add(act);
}
}
guiMenus.add(preview);
setSelectedPropertyPanel(selected);
}
@Override
public void apply() {
for (List<Object> lst : panels.values()) {
for(Object candidate : lst){
if(!(candidate instanceof PropertyPane)) continue;
final PropertyPane pan = (PropertyPane) candidate;
if (pan.equals(active)) {
pan.apply();
} else {
pan.reset();
}
}
}
}
@Override
public void reset() {
for (List<Object> lst : panels.values()) {
for(Object candidate : lst){
if(!(candidate instanceof PropertyPane)) continue;
final PropertyPane pan = (PropertyPane) candidate;
pan.reset();
}
}
}
@Override
public abstract String getTitle();
@Override
public abstract ImageIcon getIcon();
@Override
public abstract String getToolTip();
@Override
public Component getComponent() {
return this;
}
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (PropertyPane.RELOAD.equals(evt.getPropertyName())) {
reset();
}
}
// Variables declaration - do not modify//GEN-BEGIN:variables
private JPanel guiTypesPane;
private JScrollPane typeScroll;
// End of variables declaration//GEN-END:variables
}