/*
* Copyright 2003-2007 Tufts University Licensed under the
* Educational Community License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License. You may
* obtain a copy of the License at
*
* http://www.osedu.org/licenses/ECL-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an "AS IS"
* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
package tufts.vue;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.text.JTextComponent;
import javax.swing.border.*;
import tufts.vue.gui.*;
// TODO FIX: the text input fields should save value on focus loss
/**
* @version $Revision: 1.1 $ / $Date: 2008-06-19 03:46:58 $ / $Author: sfraize $
*/
class LWCInfoPanel extends javax.swing.JPanel
implements VueConstants,
//LWSelection.Listener,
LWComponent.Listener,
ActionListener,
FocusListener
{
//private JTextField labelField = new JTextField(15);
//private JTextComponent labelField = new JTextPane();
private JTextComponent labelField = new VueTextPane();
//private JLabel resourceField = new JLabel();
//private JTextComponent resourceField = new tufts.vue.gui.VueTextField();
//private JTextArea resourceField = new JTextArea();
//private JTextComponent resourceField = new JTextPane();
private JTextComponent resourceField = new VueTextPane();
private JLabel sizeField = new JLabel();
private JPanel fieldPane = new JPanel();
private JPanel resourceMetadataPanel = new JPanel();
private JPanel metadataPane = new JPanel();
private PropertiesEditor propertiesEditor = null;
private Object[] labelTextPairs = {
"Label", labelField,
"Resource", resourceField,
"-Size", sizeField,
};
private LWComponent lwc;
public LWCInfoPanel()
{
super(new BorderLayout());
setOpaque(false);
if (!GUI.isMacAqua()) {
Border textPaneBorder = BorderFactory.createEtchedBorder();
//Border textPaneBorder = BorderFactory.createLineBorder(Color.lightGray);
labelField.setBorder(textPaneBorder);
resourceField.setBorder(textPaneBorder);
}
labelField.setEditable(false);
resourceField.setEditable(false);
resourceField.setOpaque(false);
resourceField.setBorder(null);
//setBorder(BorderFactory.createEmptyBorder(6,6,6,6));
GridBagLayout gridBag = new GridBagLayout();
GridBagConstraints c = new GridBagConstraints();
fieldPane.setLayout(gridBag);
fieldPane.setOpaque(false);
addLabelTextRows(labelTextPairs, gridBag, fieldPane);
// settting metadata
setUpMetadataPane();
metadataPane.setOpaque(false);
add(fieldPane, BorderLayout.NORTH);
add(metadataPane,BorderLayout.CENTER);
//VUE.ModelSelection.addListener(this);
VUE.addActiveListener(LWComponent.class, this);
}
private void setUpMetadataPane() {
metadataPane.setLayout(new BorderLayout());
metadataPane.setBorder(BorderFactory.createEmptyBorder(10,0,0,0));
// todo: bug in properties editor: will never display edit elements unless create editable initially
propertiesEditor = new PropertiesEditor(false);
metadataPane.add(propertiesEditor,BorderLayout.CENTER);
validate();
}
private void addLabelTextRows(Object[] labelTextPairs, GridBagLayout gridbag, Container container)
{
GridBagConstraints c = new GridBagConstraints();
c.anchor = GridBagConstraints.EAST;
int num = labelTextPairs.length;
boolean lastWasLabelAbove = false;
Border lastBorder = null;
for (int i = 0; i < num; i += 2) {
String txt = (String) labelTextPairs[i];
boolean readOnly = false;
boolean labelAbove = false;
if (txt.charAt(0) == '-') {
txt = txt.substring(1);
readOnly = true;
} else if (txt.charAt(0) == '+') {
labelAbove = true;
txt = txt.substring(1);
}
txt += ": ";
//-------------------------------------------------------
// Add the label field
//-------------------------------------------------------
int topPad = lastWasLabelAbove ? 3 : 1;
if (labelAbove) {
c.insets = new Insets(topPad, 0, 0, 0);
c.gridwidth = GridBagConstraints.REMAINDER; // last in row
c.anchor = GridBagConstraints.WEST;
} else {
c.insets = new Insets(topPad, 0, 1, 0);
c.gridwidth = GridBagConstraints.RELATIVE; // next-to-last in row
c.anchor = GridBagConstraints.EAST;
// this makes labels stay at top left of multi-line fields, tho it throws off
// baseline alignment for normal cases. What we REALLY want is a baseline
// alignment against the first line of text in the field.
// c.anchor = GridBagConstraints.NORTHEAST;
}
c.fill = GridBagConstraints.NONE; // the label never grows
c.weightx = 0.0; // reset
JLabel label = new JLabel(txt);
gridbag.setConstraints(label, c);
container.add(label);
label.setFont(FONT_NARROW);
//-------------------------------------------------------
// Add the text value field
//-------------------------------------------------------
c.gridwidth = GridBagConstraints.REMAINDER; // last in row
c.fill = GridBagConstraints.HORIZONTAL;
if (labelAbove)
c.insets = new Insets(0, 0, 0, 0);
else
c.insets = new Insets(0, 0, 1, 0);
c.weightx = 1.0;
JComponent field = (JComponent) labelTextPairs[i+1];
//field.setFont(VueConstants.SmallFont);
if (field instanceof JTextField) {
//((JTextField)field).setHorizontalAlignment(JTextField.LEFT);
((JTextField)field).addActionListener(this);
((JTextField)field).addFocusListener(this);
}
//field.setFont(FONT_NARROW);
gridbag.setConstraints(field, c);
container.add(field);
if (lastBorder != null && field instanceof JTextPane) {
field.setBorder(lastBorder);
}
if (readOnly) {
Border b = field.getBorder();
//System.out.println("LWCInfoPanel: got border " + b);
//lastBorder = b;
if (b != null) {
final Insets borderInsets = b.getBorderInsets(field);
System.out.println("LWCInfoPanel: got border insets " + borderInsets + " for " + field);
field.putClientProperty(VueTextField.ActiveBorderKey, b);
Border emptyBorder = new EmptyBorder(borderInsets);
field.putClientProperty(VueTextField.InactiveBorderKey, emptyBorder);
field.setBorder(emptyBorder);
}
//field.setBorder(new EmptyBorder(1,1,1,1));
if (field instanceof JTextComponent) {
JTextComponent tc = (JTextComponent) field;
tc.setEditable(false);
tc.setFocusable(false);
}
if (VueUtil.isMacPlatform()) {
//field.setBackground(SystemColor.control);
field.setOpaque(false);
}
}
lastWasLabelAbove = labelAbove;
}
/**
* JLabel field = new JLabel("Metadata");
* c.gridwidth = GridBagConstraints.REMAINDER; //end row
* c.fill = GridBagConstraints.HORIZONTAL;
* c.anchor = GridBagConstraints.WEST;
* gridbag.setConstraints(field, c);
* container.add(field);
*/
}
public void LWCChanged(LWCEvent e) {
if (this.lwc != e.getSource())
return;
if (e.key == LWKey.Deleting) {
this.lwc = null;
setAllEnabled(false);
} else if (e.getSource() != this)
loadItem(this.lwc);
}
// public void selectionChanged(LWSelection selection) {
// if (selection.isEmpty() || selection.size() > 1)
// setAllEnabled(false);
// else
// loadItem(selection.first());
// }
public void activeChanged(ActiveEvent e, LWComponent c) {
if (c == null)
setAllEnabled(false);
else
loadItem(c);
}
private void loadText(JTextComponent c, String text) {
String hasText = c.getText();
// This prevents flashing where fields of
// length greater the the visible area do
// a flash-scroll when setting the text, even
// if it's the same as what's there.
if (hasText != text && !hasText.equals(text))
c.setText(text);
}
private void loadText(JLabel c, String text) {
String hasText = c.getText();
// This prevents flashing where fields of
// length greater the the visible area do
// a flash-scroll when setting the text, even
// if it's the same as what's there.
if (hasText != text && !hasText.equals(text))
c.setText(text);
}
private void setAllEnabled(boolean tv) {
int pairs = labelTextPairs.length;
for (int i = 0; i < pairs; i += 2) {
JComponent field = (JComponent) labelTextPairs[i+1];
field.setEnabled(tv);
}
resourceMetadataPanel.setEnabled(tv);
metadataPane.setEnabled(tv);
propertiesEditor.setEnabled(tv);
}
private void loadItem(LWComponent lwc) {
if (this.lwc != lwc) {
if (this.lwc != null)
this.lwc.removeLWCListener(this);
this.lwc = lwc;
if (this.lwc != null) {
this.lwc.addLWCListener(this, LWKey.Label, LWKey.Resource, LWKey.Deleting);
setAllEnabled(true);
} else
setAllEnabled(false);
}
//System.out.println(this + " loadItem " + lwc);
LWComponent c = this.lwc;
if (c == null)
return;
setAllEnabled(true);
//System.out.println(this + " loading " + c);
final Resource r = c.getResource();
if (r != null)
loadText(resourceField, r.getSpec());
else
loadText(resourceField, "");
loadText(labelField, c.getLabel());
String ss = VueUtil.abbrevBytes(r.getByteSize());
sizeField.setText(ss);
//loading the metadata if it exists
if (c.getResource() != null) {
PropertyMap properties = c.getResource().getProperties();
if (properties != null) {
if (c.getResource().getClientType() == Resource.ASSET_FEDORA)
propertiesEditor.setProperties(properties, false);
else
propertiesEditor.setProperties(properties, true);
}
} else {
propertiesEditor.clear();
}
}
public void actionPerformed(ActionEvent e) {
if (this.lwc == null)
return;
String text = e.getActionCommand();
Object src = e.getSource();
LWComponent c = this.lwc;
updateLWComponent(text,src,c);
}
public void focusGained(FocusEvent e) {
}
public void focusLost(FocusEvent e) {
if (this.lwc == null)
return;
String text = ((JTextField)e.getSource()).getText();
Object src = e.getSource();
LWComponent c = this.lwc;
updateLWComponent(text,src,c);
}
public void updateLWComponent(String text,Object src,LWComponent c) {
try {
boolean set = true;
if (src == labelField)
c.setLabel(text);
else if (src == resourceField)
c.setResource(text);
else
set = false;
if (set)
VUE.getUndoManager().mark();
else
return;
} catch (Exception ex) {
System.err.println(ex);
System.err.println("LWCInfoPanel: error setting property value ["+text+"] on " + src);
}
}
public String toString() {
return "LWCInfoPanel@" + Integer.toHexString(hashCode());
}
public static void main(String args[]) {
VUE.init(args);
LWCInfoPanel p = new LWCInfoPanel();
LWComponent node = new LWNode("Test Node");
node.setNotes("I am a note.");
node.setResource("file:///System/Library/Frameworks/JavaVM.framework/Versions/1.4.2/Home");
Resource r = node.getResource();
for (int i = 1; i < 6; i++)
r.setProperty("field_" + i, "value_" + i);
if (args.length > 1) {
//ToolWindow w = VUE.createToolWindow("LWCInfoPanel", p);
DockWindow w = new DockWindow("LWCInfoPanel", p);
w.setVisible(true);
} else
tufts.Util.displayComponent(p);
VUE.getSelection().setTo(node); // setLWComponent does diddly -- need this
// Must have at least ONE active frame for our focus manager to work
new Frame("An Active Frame").setVisible(true);
/*
p.setAllEnabled(true);
p.labelField.setEditable(true);
p.labelField.setEnabled(true);
p.resourceField.setEditable(true);
p.resourceField.setEnabled(true);
*/
}
}