001/* 002 * Gridarta MMORPG map editor for Crossfire, Daimonin and similar games. 003 * Copyright (C) 2000-2011 The Gridarta Developers. 004 * 005 * This program is free software; you can redistribute it and/or modify 006 * it under the terms of the GNU General Public License as published by 007 * the Free Software Foundation; either version 2 of the License, or 008 * (at your option) any later version. 009 * 010 * This program is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 013 * GNU General Public License for more details. 014 * 015 * You should have received a copy of the GNU General Public License along 016 * with this program; if not, write to the Free Software Foundation, Inc., 017 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 018 */ 019 020package net.sf.gridarta.gui.dialog.plugin.parameter; 021 022import java.awt.Color; 023import java.awt.Component; 024import java.awt.Container; 025import java.awt.Dimension; 026import java.awt.FlowLayout; 027import java.awt.GridBagConstraints; 028import java.awt.GridBagLayout; 029import java.awt.event.ActionEvent; 030import java.awt.event.ActionListener; 031import java.awt.event.MouseEvent; 032import java.awt.event.MouseListener; 033import javax.swing.AbstractButton; 034import javax.swing.ComboBoxEditor; 035import javax.swing.JButton; 036import javax.swing.JLabel; 037import javax.swing.JPanel; 038import javax.swing.JPopupMenu; 039import javax.swing.JTextField; 040import javax.swing.border.LineBorder; 041import javax.swing.event.DocumentEvent; 042import javax.swing.event.DocumentListener; 043import javax.swing.text.JTextComponent; 044import net.sf.gridarta.gui.panel.gameobjectattributes.GameObjectAttributesModel; 045import net.sf.gridarta.gui.panel.objectchooser.ObjectChooser; 046import net.sf.gridarta.model.archetype.Archetype; 047import net.sf.gridarta.model.baseobject.BaseObject; 048import net.sf.gridarta.model.face.FaceObjectProviders; 049import net.sf.gridarta.model.gameobject.GameObject; 050import net.sf.gridarta.model.maparchobject.MapArchObject; 051import net.sf.gridarta.utils.CommonConstants; 052import org.jetbrains.annotations.NotNull; 053import org.jetbrains.annotations.Nullable; 054 055public class ArchComboBoxEditor<G extends GameObject<G, A, R>, A extends MapArchObject<A>, R extends Archetype<G, A, R>> implements ComboBoxEditor { 056 057 private final ArchComboBox<G, A, R> archComboBox; 058 059 private final ArchComboBoxModel<G, A, R> archComboBoxModel; 060 061 private final ObjectChooser<G, A, R> objectChooser; 062 063 private final GameObjectAttributesModel<G, A, R> gameObjectAttributesModel; 064 065 private Container editorPanel; 066 067 private JLabel icon; 068 069 private JTextComponent editor; 070 071 private JPopupMenu popup; 072 073 private volatile boolean locked; 074 075 /** 076 * The {@link FaceObjectProviders} for looking up faces. 077 */ 078 @NotNull 079 private final FaceObjectProviders faceObjectProviders; 080 081 /** 082 * Creates a new instance. 083 * @param faceObjectProviders the face object providers for looking up 084 * faces 085 */ 086 public ArchComboBoxEditor(final ArchComboBox<G, A, R> archComboBox, final ArchComboBoxModel<G, A, R> archComboBoxModel, final ObjectChooser<G, A, R> objectChooser, final GameObjectAttributesModel<G, A, R> gameObjectAttributesModel, @NotNull final FaceObjectProviders faceObjectProviders) { 087 this.archComboBox = archComboBox; 088 this.archComboBoxModel = archComboBoxModel; 089 this.objectChooser = objectChooser; 090 this.gameObjectAttributesModel = gameObjectAttributesModel; 091 this.faceObjectProviders = faceObjectProviders; 092 } 093 094 public void lockEditor() { 095 locked = true; 096 } 097 098 public void unlockEditor() { 099 locked = false; 100 } 101 102 private synchronized void buildPanel() { 103 if (editorPanel == null) { 104 editorPanel = new JPanel(new GridBagLayout()); 105 final GridBagConstraints gbc = new GridBagConstraints(); 106 gbc.gridx = 0; 107 gbc.gridy = 0; 108 gbc.weightx = 1.0; 109 gbc.gridwidth = 4; 110 gbc.fill = GridBagConstraints.HORIZONTAL; 111 editor = new JTextField(); 112 editorPanel.add(editor, gbc); 113 gbc.gridy = 1; 114 gbc.gridwidth = 1; 115 gbc.weightx = 0.0; 116 gbc.gridx = 1; 117 final AbstractButton fromSelect = new JButton("From tile selection"); 118 fromSelect.addActionListener(new ActionListener() { 119 120 @Override 121 public void actionPerformed(final ActionEvent e) { 122 final BaseObject<G, A, R, ?> gameObject = objectChooser.getSelection(); 123 if (gameObject != null) { 124 final Archetype<G, A, R> ao = archComboBoxModel.getNearestMatch(gameObject.getArchetype().getArchetypeName()); 125 archComboBox.setSelectedItem(ao); 126 setItem(ao); 127 } 128 } 129 }); 130 editorPanel.add(fromSelect, gbc); 131 final AbstractButton fromActive = new JButton("From map selection"); 132 fromActive.addActionListener(new ActionListener() { 133 134 @Override 135 public void actionPerformed(final ActionEvent e) { 136 final BaseObject<G, A, R, ?> gameObject = gameObjectAttributesModel.getSelectedGameObject(); 137 if (gameObject != null) { 138 final Archetype<G, A, R> ao = archComboBoxModel.getNearestMatch(gameObject.getArchetype().getArchetypeName()); 139 archComboBox.setSelectedItem(ao); 140 setItem(ao); 141 } 142 } 143 }); 144 gbc.gridx = 2; 145 editorPanel.add(fromActive, gbc); 146 editor.addMouseListener(new MouseListener() { 147 148 @Override 149 public void mouseClicked(final MouseEvent e) { 150 } 151 152 @Override 153 public void mouseEntered(final MouseEvent e) { 154 //popup.setLocation(p.x, p.y+archComboBoxEditor.getHeight()+5); 155 popup.setPreferredSize(null); 156 final Dimension d = popup.getPreferredSize(); 157 final Dimension p = editorPanel.getSize(); 158 if (d.width < p.width) { 159 d.width = p.width; 160 } 161 if (d.height < p.height) { 162 d.height = p.height; 163 } 164 popup.setPreferredSize(d); 165 popup.show(editorPanel, 0, editorPanel.getHeight() + 5); 166 } 167 168 @Override 169 public void mouseExited(final MouseEvent e) { 170 popup.setVisible(false); 171 } 172 173 @Override 174 public void mousePressed(final MouseEvent e) { 175 } 176 177 @Override 178 public void mouseReleased(final MouseEvent e) { 179 } 180 }); 181 editor.setEditable(true); 182 editor.getDocument().addDocumentListener(new DocumentListener() { 183 184 @Override 185 public void changedUpdate(final DocumentEvent e) { 186 archComboBox.editorEntryChange(); 187 } 188 189 @Override 190 public void insertUpdate(final DocumentEvent e) { 191 archComboBox.editorEntryChange(); 192 } 193 194 @Override 195 public void removeUpdate(final DocumentEvent e) { 196 archComboBox.editorEntryChange(); 197 } 198 }); 199 icon = new JLabel(); 200 popup = new JPopupMenu(); 201 popup.setLayout(new FlowLayout()); 202 popup.setBackground(CommonConstants.BG_COLOR); 203 popup.setBorder(new LineBorder(Color.black)); 204 popup.add(icon); 205 popup.setFocusable(false); 206 archComboBox.setBackground(CommonConstants.BG_COLOR); 207 } 208 } 209 210 @Override 211 public void selectAll() { 212 // TODO Auto-generated method stub 213 214 } 215 216 @Override 217 public Component getEditorComponent() { 218 if (editorPanel == null) { 219 buildPanel(); 220 } 221 return editorPanel; 222 } 223 224 @Override 225 public void addActionListener(final ActionListener l) { 226 // TODO Auto-generated method stub 227 228 } 229 230 @Override 231 public void removeActionListener(final ActionListener l) { 232 // TODO Auto-generated method stub 233 234 } 235 236 @Nullable 237 @Override 238 public Object getItem() { 239 // TODO Auto-generated method stub 240 return null; 241 } 242 243 @Override 244 public void setItem(final Object anObject) { 245 final BaseObject<?, ?, ?, ?> arch = (BaseObject<?, ?, ?, ?>) anObject; 246 if (anObject == null) { 247 icon.setIcon(null); 248 icon.setText("No item selected"); 249 } else { 250 icon.setIcon(faceObjectProviders.getFace(arch)); 251 } 252 253 if (arch == null) { 254 icon.setText(""); 255 if (!locked) { 256 editor.setText(""); 257 } 258 } else { 259 if (!locked) { 260 editor.setText(arch.getArchetype().getArchetypeName()); 261 } 262 icon.setText(arch.getArchetype().getArchetypeName()); 263 } 264 } 265 266 public JTextComponent getEditor() { 267 return editor; 268 } 269 270}