Logo Search packages:      
Sourcecode: josm version File versions  Download package

RelationEditor.java

package org.openstreetmap.josm.gui.dialogs;

import static org.openstreetmap.josm.tools.I18n.tr;
import static org.xnap.commons.i18n.I18n.marktr;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.Map.Entry;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.DefaultTableModel;

import org.openstreetmap.josm.Main;
import org.openstreetmap.josm.command.AddCommand;
import org.openstreetmap.josm.command.ChangeCommand;
import org.openstreetmap.josm.data.osm.OsmPrimitive;
import org.openstreetmap.josm.data.osm.Relation;
import org.openstreetmap.josm.data.osm.RelationMember;
import org.openstreetmap.josm.gui.OsmPrimitivRenderer;
import org.openstreetmap.josm.tools.GBC;
import org.openstreetmap.josm.tools.ImageProvider;

/**
 * This dialog is for editing relations.
 * 
 * In the basic form, it provides two tables, one with the relation tags
 * and one with the relation members. (Relation tags can be edited through 
 * the normal properties dialog as well, if you manage to get a relation 
 * selected!)
 * 
 * @author Frederik Ramm <frederik@remote.org>
 *
 */
00052 public class RelationEditor extends JFrame {

      /**
       * The relation that this editor is working on, and the clone made for
       * editing.
       */
00058       private final Relation relation;
      private final Relation clone;
      
      /**
       * The property data.
       */
00064       private final DefaultTableModel propertyData = new DefaultTableModel() {
            @Override public boolean isCellEditable(int row, int column) {
                  return true;
            }
            @Override public Class<?> getColumnClass(int columnIndex) {
                  return String.class;
            }
      };

      /**
       * The membership data.
       */
00076       private final DefaultTableModel memberData = new DefaultTableModel() {
            @Override public boolean isCellEditable(int row, int column) {
                  return column == 0;
            }
            @Override public Class<?> getColumnClass(int columnIndex) {
                  return columnIndex == 1 ? OsmPrimitive.class : String.class;
            }
      };
      
      /**
       * The properties and membership lists.
       */
00088       private final JTable propertyTable = new JTable(propertyData);
      private final JTable memberTable = new JTable(memberData);
      
      /**
       * Creates a new relation editor for the given relation. The relation
       * will be saved if the user selects "ok" in the editor.
       * 
       * If no relation is given, will create an editor for a new relation.
       * 
       * @param relation relation to edit, or null to create a new one.
       */
00099       public RelationEditor(Relation relation)
      {
            super(relation == null ? tr("Create new relation") : 
                  relation.id == 0 ? tr ("Edit new relation") :
                  tr("Edit relation #{0}", relation.id));
            this.relation = relation;
            
            if (relation == null) {
                  // create a new relation
                  this.clone = new Relation();
            } else {
                  // edit an existing relation
                  this.clone = new Relation(relation);      
            }
            
            getContentPane().setLayout(new BorderLayout());
            JTabbedPane tabPane = new JTabbedPane();
            getContentPane().add(tabPane, BorderLayout.CENTER);
            
            // (ab)use JOptionPane to make this look familiar;
            // hook up with JOptionPane's property change event
            // to detect button click
            final JOptionPane okcancel = new JOptionPane("", 
                  JOptionPane.PLAIN_MESSAGE, JOptionPane.OK_CANCEL_OPTION, null);
            getContentPane().add(okcancel, BorderLayout.SOUTH);
            
            okcancel.addPropertyChangeListener(new PropertyChangeListener() {
                  public void propertyChange(PropertyChangeEvent event) {
                        if (event.getPropertyName().equals(JOptionPane.VALUE_PROPERTY) && event.getNewValue() != null) {
                              if ((Integer)event.getNewValue() == JOptionPane.OK_OPTION) {
                                    // clicked ok!
                                    if (RelationEditor.this.relation == null) {
                                          Main.main.undoRedo.add(new AddCommand(clone));
                                    } else if (!RelationEditor.this.relation.realEqual(clone, true)) {
                                          Main.main.undoRedo.add(new ChangeCommand(RelationEditor.this.relation, clone));
                                    }
                              }
                              setVisible(false);
                        }
                  }
            });

            JLabel help = new JLabel("<html><em>"+
                  "This is the basic relation editor which allows you to change the relation's tags " +
                  "as well as the members. In addition to this we should have a smart editor that " +
                  "detects the type of relationship and limits your choices in a sensible way.</em></html>");
            
            getContentPane().add(help, BorderLayout.NORTH);       
            try { setAlwaysOnTop(true); } catch (SecurityException sx) {}
            
            // Basic Editor panel has two blocks; 
            // a tag table at the top and a membership list below.

            // setting up the properties table
            
            propertyData.setColumnIdentifiers(new String[]{tr("Key"),tr("Value")});
            propertyTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
            propertyData.addTableModelListener(new TableModelListener() {
                  public void tableChanged(TableModelEvent tme) {
                        if (tme.getType() == TableModelEvent.UPDATE) {
                              int row = tme.getFirstRow();
                  
                              if (!(tme.getColumn() == 0 && row == propertyData.getRowCount() -1)) {
                                    clone.entrySet().clear();
                                    for (int i = 0; i < propertyData.getRowCount(); i++) {
                                          String key = propertyData.getValueAt(i, 0).toString();
                                          String value = propertyData.getValueAt(i, 1).toString();
                                          if (key.length() > 0 && value.length() > 0) clone.put(key, value);
                                    }
                                    refreshTables();
                              }
                        }
                  }
            });
            propertyTable.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
            
            // setting up the member table
            
          memberData.setColumnIdentifiers(new String[]{tr("Role"),tr("Occupied By")});
            memberTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
            memberTable.getColumnModel().getColumn(1).setCellRenderer(new OsmPrimitivRenderer());
            /*
            memberTable.getColumnModel().getColumn(1).setCellRenderer(new DefaultTableCellRenderer() {
                  public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
                        Component c = super.getTableCellRendererComponent(table, value, isSelected, false, row, column);
                        if (c instanceof JLabel) {
                              ((OsmPrimitive)value).visit(nameVisitor);
                              ((JLabel)c).setText(nameVisitor.name);
                        }
                        return c;
                  }
            });   
            */
            memberData.addTableModelListener(new TableModelListener() {
                  public void tableChanged(TableModelEvent tme) {
                        if (tme.getType() == TableModelEvent.UPDATE && tme.getColumn() == 0) {
                              int row = tme.getFirstRow();
                              clone.members.get(row).role = memberData.getValueAt(row, 0).toString();
                        }
                  }
            });
            memberTable.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);

            
            // combine both tables and wrap them in a scrollPane
            JPanel bothTables = new JPanel();
            bothTables.setLayout(new GridBagLayout());
            bothTables.add(new JLabel(tr("Tags (empty value deletes tag)")), GBC.eol().fill(GBC.HORIZONTAL));
            bothTables.add(new JScrollPane(propertyTable), GBC.eop().fill(GBC.BOTH));
            bothTables.add(new JLabel(tr("Members")), GBC.eol().fill(GBC.HORIZONTAL));
            bothTables.add(new JScrollPane(memberTable), GBC.eol().fill(GBC.BOTH));
            
            JPanel buttonPanel = new JPanel(new GridLayout(1,3));
            
            buttonPanel.add(createButton(marktr("Add Selected"),"addselected", tr("Add all currently selected objects as members"), KeyEvent.VK_A, new ActionListener() {
                  public void actionPerformed(ActionEvent e) {
                        addSelected();
                  }
            }));

            buttonPanel.add(createButton(marktr("Delete"),"delete", tr("Remove the member in the current table row from this relation"), KeyEvent.VK_D, new ActionListener() {
                  public void actionPerformed(ActionEvent e) {
                        int[] rows = memberTable.getSelectedRows();
                        RelationMember mem = new RelationMember();
                        for (int row : rows) {
                              mem.role = memberTable.getValueAt(row, 0).toString();
                              mem.member = (OsmPrimitive) memberTable.getValueAt(row, 1);
                              clone.members.remove(mem);
                        }
                        refreshTables();
                  }
            }));

            buttonPanel.add(createButton(marktr("Select"),"select", tr("Highlight the member from the current table row as JOSM's selection"), KeyEvent.VK_S, new ActionListener() {
                  public void actionPerformed(ActionEvent e) {
                        int[] rows = memberTable.getSelectedRows();
                        ArrayList<OsmPrimitive> sel = new ArrayList<OsmPrimitive>(rows.length);
                        for (int i : rows) { sel.add((OsmPrimitive)memberTable.getValueAt(i, 1)); }
                        Main.ds.setSelected(sel);
                  }
            }));
            bothTables.add(buttonPanel, GBC.eop().fill(GBC.HORIZONTAL));

            tabPane.add(bothTables, "Basic");
            
            refreshTables();
            
            setSize(new Dimension(400, 500));
            setLocationRelativeTo(Main.parent);
      }
      
      private void refreshTables() {
            
            // re-load property data
            
            propertyData.setRowCount(0);
            for (Entry<String, String> e : clone.entrySet()) {
                  propertyData.addRow(new Object[]{e.getKey(), e.getValue()});
            }
            propertyData.addRow(new Object[]{"", ""});
            
            // re-load membership data
            
            memberData.setRowCount(0);
            for (RelationMember em : clone.members) {
                  memberData.addRow(new Object[]{em.role, em.member});
            }
      }
      
      private JButton createButton(String name, String iconName, String tooltip, int mnemonic, ActionListener actionListener) {
            JButton b = new JButton(tr(name), ImageProvider.get("dialogs", iconName));
            b.setActionCommand(name);
            b.addActionListener(actionListener);
            b.setToolTipText(tooltip);
            b.setMnemonic(mnemonic);
            b.putClientProperty("help", "Dialog/Properties/"+name);
            return b;
      }
      
      private void addSelected() {
            for (OsmPrimitive p : Main.ds.getSelected()) {
                  RelationMember em = new RelationMember();
                  em.member = p;
                  em.role = "";
                  clone.members.add(em);
            }
            refreshTables();
      }
}

Generated by  Doxygen 1.6.0   Back to index