JPanel scrollablePanel = new JPanel();
JScrollPane scrollPane = new JScrollPane(scrollablePanel);
scrollPane.setBorder(BorderFactory.createEmptyBorder());
add(scrollPane, BorderLayout.CENTER);
GridBagLayout gbLayout = new GridBagLayout();
scrollablePanel.setLayout(gbLayout);
setVisible(false);
m_NumEditable = 0;
m_Target = targ;
try {
BeanInfo bi = Introspector.getBeanInfo(m_Target.getClass());
m_Properties = bi.getPropertyDescriptors();
m_Methods = bi.getMethodDescriptors();
} catch (IntrospectionException ex) {
System.err.println("PropertySheet: Couldn't introspect");
return;
}
JTextArea jt = new JTextArea();
m_HelpText = null;
// Look for a globalInfo method that returns a string
// describing the target
for (int i = 0;i < m_Methods.length; i++) {
String name = m_Methods[i].getDisplayName();
Method meth = m_Methods[i].getMethod();
if (name.equals("globalInfo")) {
if (meth.getReturnType().equals(String.class)) {
try {
Object args[] = { };
String globalInfo = (String)(meth.invoke(m_Target, args));
String summary = globalInfo;
int ci = globalInfo.indexOf('.');
if (ci != -1) {
summary = globalInfo.substring(0, ci + 1);
}
final String className = targ.getClass().getName();
m_HelpText = new StringBuffer("NAME\n");
m_HelpText.append(className).append("\n\n");
m_HelpText.append("SYNOPSIS\n").append(globalInfo).append("\n\n");
m_HelpBut = new JButton("More");
m_HelpBut.setToolTipText("More information about "
+ className);
m_HelpBut.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent a) {
openHelpFrame();
m_HelpBut.setEnabled(false);
}
});
if (m_Target instanceof CapabilitiesHandler) {
m_CapabilitiesBut = new JButton("Capabilities");
m_CapabilitiesBut.setToolTipText("The capabilities of "
+ className);
m_CapabilitiesBut.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent a) {
openCapabilitiesHelpDialog();
m_CapabilitiesBut.setEnabled(false);
}
});
}
else {
m_CapabilitiesBut = null;
}
jt.setColumns(30);
jt.setFont(new Font("SansSerif", Font.PLAIN,12));
jt.setEditable(false);
jt.setLineWrap(true);
jt.setWrapStyleWord(true);
jt.setText(summary);
jt.setBackground(getBackground());
JPanel jp = new JPanel();
jp.setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createTitledBorder("About"),
BorderFactory.createEmptyBorder(5, 5, 5, 5)
));
jp.setLayout(new BorderLayout());
jp.add(jt, BorderLayout.CENTER);
JPanel p2 = new JPanel();
p2.setLayout(new BorderLayout());
p2.add(m_HelpBut, BorderLayout.NORTH);
if (m_CapabilitiesBut != null) {
JPanel p3 = new JPanel();
p3.setLayout(new BorderLayout());
p3.add(m_CapabilitiesBut, BorderLayout.NORTH);
p2.add(p3, BorderLayout.CENTER);
}
jp.add(p2, BorderLayout.EAST);
GridBagConstraints gbConstraints = new GridBagConstraints();
// gbConstraints.anchor = GridBagConstraints.EAST;
gbConstraints.fill = GridBagConstraints.BOTH;
// gbConstraints.gridy = 0; gbConstraints.gridx = 0;
gbConstraints.gridwidth = 2;
gbConstraints.insets = new Insets(0,5,0,5);
gbLayout.setConstraints(jp, gbConstraints);
m_aboutPanel = jp;
scrollablePanel.add(m_aboutPanel);
componentOffset = 1;
break;
} catch (Exception ex) {
}
}
}
}
m_Editors = new PropertyEditor[m_Properties.length];
m_Values = new Object[m_Properties.length];
m_Views = new JComponent[m_Properties.length];
m_Labels = new JLabel[m_Properties.length];
m_TipTexts = new String[m_Properties.length];
boolean firstTip = true;
for (int i = 0; i < m_Properties.length; i++) {
// Don't display hidden or expert properties.
if (m_Properties[i].isHidden() || m_Properties[i].isExpert()) {
continue;
}
String name = m_Properties[i].getDisplayName();
Class type = m_Properties[i].getPropertyType();
Method getter = m_Properties[i].getReadMethod();
Method setter = m_Properties[i].getWriteMethod();
// Only display read/write properties.
if (getter == null || setter == null) {
continue;
}
JComponent view = null;
try {
Object args[] = { };
Object value = getter.invoke(m_Target, args);
m_Values[i] = value;
PropertyEditor editor = null;
Class pec = m_Properties[i].getPropertyEditorClass();
if (pec != null) {
try {
editor = (PropertyEditor)pec.newInstance();
} catch (Exception ex) {
// Drop through.
}
}
if (editor == null) {
editor = PropertyEditorManager.findEditor(type);
}
m_Editors[i] = editor;
// If we can't edit this component, skip it.
if (editor == null) {
// If it's a user-defined property we give a warning.
String getterClass = m_Properties[i].getReadMethod()
.getDeclaringClass().getName();
/*
if (getterClass.indexOf("java.") != 0) {
System.err.println("Warning: Can't find public property editor"
+ " for property \"" + name + "\" (class \""
+ type.getName() + "\"). Skipping.");
}
*/
continue;
}
if (editor instanceof GenericObjectEditor) {
((GenericObjectEditor) editor).setClassType(type);
}
if (editor instanceof EnvironmentHandler) {
((EnvironmentHandler)editor).setEnvironment(m_env);
}
// Don't try to set null values:
if (value == null) {
// If it's a user-defined property we give a warning.
String getterClass = m_Properties[i].getReadMethod()
.getDeclaringClass().getName();
/*
if (getterClass.indexOf("java.") != 0) {
System.err.println("Warning: Property \"" + name
+ "\" has null initial value. Skipping.");
}
*/
continue;
}
editor.setValue(value);
// now look for a TipText method for this property
String tipName = name + "TipText";
for (int j = 0; j < m_Methods.length; j++) {
String mname = m_Methods[j].getDisplayName();
Method meth = m_Methods[j].getMethod();
if (mname.equals(tipName)) {
if (meth.getReturnType().equals(String.class)) {
try {
String tempTip = (String)(meth.invoke(m_Target, args));
int ci = tempTip.indexOf('.');
if (ci < 0) {
m_TipTexts[i] = tempTip;
} else {
m_TipTexts[i] = tempTip.substring(0, ci);
}
if (m_HelpText != null) {
if (firstTip) {
m_HelpText.append("OPTIONS\n");
firstTip = false;
}
m_HelpText.append(name).append(" -- ");
m_HelpText.append(tempTip).append("\n\n");
//jt.setText(m_HelpText.toString());
}
} catch (Exception ex) {
}
break;
}
}
}
// Now figure out how to display it...
if (editor.isPaintable() && editor.supportsCustomEditor()) {
view = new PropertyPanel(editor);
} else if (editor.supportsCustomEditor() && (editor.getCustomEditor() instanceof JComponent)) {
view = (JComponent) editor.getCustomEditor();
} else if (editor.getTags() != null) {
view = new PropertyValueSelector(editor);
} else if (editor.getAsText() != null) {
view = new PropertyText(editor);
} else {
System.err.println("Warning: Property \"" + name
+ "\" has non-displayabale editor. Skipping.");
continue;
}
editor.addPropertyChangeListener(this);
} catch (InvocationTargetException ex) {
System.err.println("Skipping property " + name
+ " ; exception on target: "
+ ex.getTargetException());
ex.getTargetException().printStackTrace();
continue;
} catch (Exception ex) {
System.err.println("Skipping property " + name
+ " ; exception: " + ex);
ex.printStackTrace();
continue;
}
m_Labels[i] = new JLabel(name, SwingConstants.RIGHT);
m_Labels[i].setBorder(BorderFactory.createEmptyBorder(10, 10, 0, 5));
m_Views[i] = view;
GridBagConstraints gbConstraints = new GridBagConstraints();
gbConstraints.anchor = GridBagConstraints.EAST;
gbConstraints.fill = GridBagConstraints.HORIZONTAL;
gbConstraints.gridy = i+componentOffset; gbConstraints.gridx = 0;
gbLayout.setConstraints(m_Labels[i], gbConstraints);
scrollablePanel.add(m_Labels[i]);
JPanel newPanel = new JPanel();
if (m_TipTexts[i] != null) {
m_Views[i].setToolTipText(m_TipTexts[i]);
}
newPanel.setBorder(BorderFactory.createEmptyBorder(10, 5, 0, 10));
newPanel.setLayout(new BorderLayout());
newPanel.add(m_Views[i], BorderLayout.CENTER);
gbConstraints = new GridBagConstraints();
gbConstraints.anchor = GridBagConstraints.WEST;
gbConstraints.fill = GridBagConstraints.BOTH;
gbConstraints.gridy = i+componentOffset; gbConstraints.gridx = 1;
gbConstraints.weightx = 100;
gbLayout.setConstraints(newPanel, gbConstraints);
scrollablePanel.add(newPanel);
m_NumEditable ++;
}
if (m_NumEditable == 0) {
JLabel empty = new JLabel("No editable properties",
SwingConstants.CENTER);
Dimension d = empty.getPreferredSize();
empty.setPreferredSize(new Dimension(d.width * 2, d.height * 2));
empty.setBorder(BorderFactory.createEmptyBorder(10, 5, 0, 10));
GridBagConstraints gbConstraints = new GridBagConstraints();
gbConstraints.anchor = GridBagConstraints.CENTER;
gbConstraints.fill = GridBagConstraints.HORIZONTAL;
gbConstraints.gridy = componentOffset; gbConstraints.gridx = 0;
gbLayout.setConstraints(empty, gbConstraints);
scrollablePanel.add(empty);
}
validate();