package org.droiddraw.gui;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.IOException;
import java.util.Hashtable;
import java.util.Vector;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import org.droiddraw.AndroidEditor;
import org.droiddraw.Main;
import org.droiddraw.property.BooleanProperty;
import org.droiddraw.property.ColorProperty;
import org.droiddraw.property.ImageProperty;
import org.droiddraw.property.IntProperty;
import org.droiddraw.property.Property;
import org.droiddraw.property.SelectProperty;
import org.droiddraw.property.StringProperty;
import org.droiddraw.util.FileCopier;
import org.droiddraw.widget.Layout;
import org.droiddraw.widget.Widget;
public class PropertiesPanel
extends JPanel
implements ActionListener, PropertyChangeListener, KeyListener
{
private static final long serialVersionUID = 1L;
Vector<Property> properties;
Hashtable<Property, JComponent> components;
Hashtable<ColorProperty, Color> colorTable;
Viewer viewer;
Widget w;
JPanel items;
Dimension d;
boolean applet;
public PropertiesPanel(boolean applet) {
this(new Vector<Property>(), null, applet);
}
public PropertiesPanel(Vector<Property> properties, Widget w, boolean applet) {
this.components = new Hashtable<Property, JComponent>();
this.colorTable = new Hashtable<ColorProperty, Color>();
this.w =w;
this.applet = applet;
setProperties(properties, w);
this.d = new Dimension(200,400);
}
public void setApplet(boolean applet) {
this.applet = applet;
}
public void setProperties(Vector<Property> properties, Widget w) {
this.properties = properties;
this.removeAll();
this.w = w;
if (w == null)
return;
w.setPropertyChangeListener(this);
items = new JPanel();
items.setLayout(new GridLayout(0,2));
//items.setBorder(BorderFactory.createTitledBorder("Properties"));
components.clear();
if (properties.size() > 0) {
items.add(new JLabel("Properties for: "));
items.add(new JLabel(w.getTagName()));
}
java.awt.FlowLayout fl = new FlowLayout();
fl.setAlignment(FlowLayout.RIGHT);
for (Property prop: properties) {
if (prop.getEditable()) {
if (prop instanceof BooleanProperty) {
items.add(new JPanel());
JCheckBox jcb = new JCheckBox(prop.getEnglishName());
jcb.setSelected(((BooleanProperty)prop).getBooleanValue());
components.put(prop, jcb);
items.add(jcb);
}
else if (prop instanceof IntProperty) {
items.add(new JLabel(prop.getEnglishName()));
JTextField jf = new JTextField(prop.getValue()!=null?prop.getValue().toString():"", 5);
JPanel jp = new JPanel();
jp.setLayout(fl);
jp.add(jf);
components.put(prop, jf);
items.add(jp);
}
else if (prop instanceof ImageProperty) {
items.add(new JLabel(prop.getEnglishName()));
final JTextField jf = new JTextField(prop.getValue()!=null?prop.getValue().toString():"", 10);
JPanel jp = new JPanel();
jp.setLayout(fl);
jp.add(jf);
if (!applet) {
JButton jb = new JButton("Browse");
jb.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (AndroidEditor.instance().getDrawableDirectory() == null) {
JOptionPane.showMessageDialog(PropertiesPanel.this, "You must select a drawables directory.\n If you select an image which is not in this directory,\n it will be copied into it.", "Select Drawable Dir.", JOptionPane.INFORMATION_MESSAGE);
File dir = Main.doOpenDir();
if (dir != null) {
AndroidEditor.instance().setDrawableDirectory(dir);
}
}
File dir = AndroidEditor.instance().getDrawableDirectory();
if (dir != null) {
File img = Main.doOpen(dir);
if (img != null) {
if (!img.getParentFile().equals(dir)) {
try {
FileCopier.copy(img, dir, true);
}
catch (IOException ex) {
AndroidEditor.instance().error(ex);
}
}
String name = img.getName();
int ix = name.indexOf(".");
if (ix != -1) {
name = name.substring(0, ix);
}
jf.setText("@drawable/"+name);
jf.requestFocus();
}
}
}
});
jp.add(jb);
}
components.put(prop, jf);
items.add(jp);
}
else if (prop instanceof StringProperty) {
items.add(new JLabel(prop.getEnglishName()));
JComponent jc;
if (prop instanceof SelectProperty) {
JComboBox jcb = new JComboBox(((SelectProperty)prop).getOptions());
jcb.setSelectedIndex(((SelectProperty)prop).getSelectedIndex());
jc = jcb;
}
else if (prop instanceof ColorProperty) {
jc = new ColorPanel(((ColorProperty)prop).getColorValue());
}
else {
if (prop.getAtttributeName().equals("android:layout_width") ||
prop.getAtttributeName().equals("android:layout_height"))
{
Vector<String> v = new Vector<String>();
v.add("");
v.add("fill_parent");
v.add("wrap_content");
//JAutoComboBox jat = new JAutoComboBox(v);
JAutoTextField jat = new JAutoTextField(v);
jat.setStrict(false);
jat.setColumns(10);
if (prop.getValue() != null) {
jat.setText(prop.getValue().toString());
}
jc = jat;
}
else {
jc = new JTextField(prop.getValue()!=null?prop.getValue().toString():"", 10);
}
}
prop.addPropertyChangeListener(new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent evt) {
Property p = (Property)evt.getSource();
JComponent jc = components.get(p);
if (p instanceof BooleanProperty) {
((JCheckBox)jc).setSelected(((Boolean)evt.getNewValue()).booleanValue());
}
else if (p instanceof ColorProperty) {
// TODO
}
else if (p instanceof SelectProperty) {
// TODO
}
else if (p instanceof StringProperty) {
if (jc != null){
((JTextField)jc).setText(evt.getNewValue().toString());
}
}
}
});
components.put(prop, jc);
JPanel p = new JPanel();
p.setLayout(fl);
p.add(jc);
items.add(p);
}
}
}
this.setLayout(new BorderLayout());
JPanel p = new JPanel();
p.add(items);
this.add(new JScrollPane(p), BorderLayout.CENTER);
if (properties.size() > 0) {
JButton apply = new JButton("Apply");
apply.addActionListener(this);
p = new JPanel();
p.add(apply);
this.add(p, BorderLayout.SOUTH);
}
this.repaint();
this.invalidate();
}
public void setViewer(Viewer v) {
this.viewer = v;
}
public void actionPerformed(ActionEvent arg0) {
apply();
}
protected void apply() {
for (Property prop : properties) {
if (prop.getEditable()) {
if (prop instanceof BooleanProperty) {
JCheckBox jcb = (JCheckBox)components.get(prop);
((BooleanProperty)prop).setBooleanValue(jcb.isSelected());
}
else if (prop instanceof IntProperty) {
JTextField jf = (JTextField)components.get(prop);
try {
((IntProperty)prop).setIntValue(Integer.parseInt(jf.getText()));
} catch (NumberFormatException ex) {
AndroidEditor.instance().error(ex);
}
}
else if (prop instanceof StringProperty) {
if (prop instanceof SelectProperty) {
JComboBox jcb = (JComboBox)components.get(prop);
if (jcb == null) {
AndroidEditor.instance().error("Couldn't find select for: "+prop.getAtttributeName());
}
else
((SelectProperty)prop).setSelectedIndex(jcb.getSelectedIndex());
}
else if (prop instanceof ColorProperty) {
ColorPanel cp = (ColorPanel)components.get(prop);
//((ColorProperty)prop).setColorValue(cp.getColor());
((ColorProperty)prop).setStringValue(cp.getString());
}
else {
JTextField jtf = (JTextField)components.get(prop);
if (jtf == null)
AndroidEditor.instance().error("Couldn't find text for: "+prop.getAtttributeName());
else if(prop.getAtttributeName().equals("android:layout_width") ||
prop.getAtttributeName().equals("android:layout_height")){
if(!jtf.getText().endsWith("px") && !jtf.getText().equals("wrap_content") && !jtf.getText().equals("fill_parent")){
AndroidEditor.instance().error("Incorrect Syntax for: " + prop.getEnglishName() + "\n\"px\" is required after a width or height entry");
}
else
((StringProperty)prop).setStringValue(jtf.getText());
}
else
((StringProperty)prop).setStringValue(jtf.getText());
}
}
}
}
w.apply();
if (w instanceof Layout) {
((Layout)w).repositionAllWidgets();
w.apply();
}
if (w.getParent() != null)
w.getParent().positionWidget(w);
if (viewer != null)
viewer.repaint();
}
@SuppressWarnings("unchecked")
public void propertyChange(PropertyChangeEvent evt) {
if (w.equals(evt.getSource())) {
setProperties((Vector<Property>)evt.getNewValue(), w);
}
}
public void keyPressed(KeyEvent e) {}
public void keyReleased(KeyEvent e) {}
public void keyTyped(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
apply();
}
}
}