/** * The constructor for AttributeDisplay requires information about default file directories and * urls. These are passed in via a Properties object, that should contain values for * 'dir.templates', 'dir.htmldocs', and 'dir.local'. * * @param owner the parent frame, used for gui sanity and L&F propogation * @param resourceLoader the resource loader used to load HTML templates from zip/jar files */ public AttributeDisplay(JFrame owner, CBResourceLoader resourceLoader) { super(); // myProperties = props; if (JXConfig.getProperty("plugins.package") != null) { setPackagePrefix(JXConfig.getProperty("plugins.package")); log.fine("SETTING PLUGIN PREFIX TO: " + PACKAGEPREFIX); } else log.fine("PLUGIN PREFIX UNCHANGED: " + PACKAGEPREFIX); this.resourceLoader = resourceLoader; this.owner = owner; initHTMLEditor(); initTableEditor(); addEditor(templateDisplay); /** * This change listener is *intended* to listen for user initiated tab changes, rather than * programmatic changes to the editor tabs (which are expected to look after themselves) */ addChangeListener( new ChangeListener() { public void stateChanged(ChangeEvent e) { if (ignoreChangeEvents) // sometimes when we're messing around we can fire heaps of return; // change events - and there's no point paying attention to 'em. int index = getSelectedIndex(); if (index >= 0 && activeEditors.size() > index && activeEditors.get(index) != null) { setCurrentEditor((PluggableEditor) activeEditors.get(index)); } else // should never happen (ROTFL) { log.warning( "internal error - unable to find editor # " + index + " in Attribute Display"); } } }); }
/** Kicks off the entry modify/update & checks for manditory attributes. */ public void doSubmit() { if (dataSource == null) { CBUtility.error("No dataSource available to write changes to in Table Attribute Editor"); return; } myEditor.stopCellEditing(); // If schema checking is on, make sure that all mandatory attributes are filled in. if ("false".equalsIgnoreCase(JXConfig.getProperty("option.ignoreSchemaOnSubmission")) && (tableData.checkMandatoryAttributesSet() == false)) { CBUtility.error( TableAttributeEditor.this, CBIntText.get("All Mandatory Attributes must have values!"), null); return; } writeTableData(); }
/** * Constructor initialises the table and a popup tool, as well as initialising the required GUI * elements. It adds action listeners for the three main buttons, which include basic user input * validation checking. */ public TableAttributeEditor(JFrame MyOwner) { // As usual, it is insanely hard to get the swing components to display // and work properly. If JTable is not displayed in a scroll pane no headers are // displayed, and you have to do it manually. (If you *do* display it // in a scrollbar, in this instance, it screws up sizing) // The broken header mis-feature is only mentioned in the tutorial, // not in the api doco - go figure. super(); owner = MyOwner; // final JPanel mainPanel = (JPanel)this; tableData = new AttributeTableModel(); attributeTable = new JTable(tableData); // attributeTable.setRowHeight(20); // This may be needed, depends on how fussy people get about // the bottom of letters like 'y' getting cut off when the cell is selected - bug 3013. popupTableTool = new SmartPopupTableTool(attributeTable, tableData, (JXplorerBrowser) owner); // Set the renderer for the attribute type... final AttributeTypeCellRenderer typeRenderer = new AttributeTypeCellRenderer(); attributeTable.setDefaultRenderer(AttributeNameAndType.class, typeRenderer); // Set the renderer for the attribute value... final AttributeValueCellRenderer valueRenderer = new AttributeValueCellRenderer(); attributeTable.setDefaultRenderer(AttributeValue.class, valueRenderer); // Set the editor for the attribute value... myEditor = new AttributeValueCellEditor(owner); attributeTable.setDefaultEditor(AttributeValue.class, myEditor); attributeTable.getTableHeader().setReorderingAllowed(false); currentDN = null; JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.CENTER)); buttonPanel.add( submit = new CBButton( CBIntText.get("Submit"), CBIntText.get("Submit your changes to the Directory."))); buttonPanel.add( reset = new CBButton( CBIntText.get("Reset"), CBIntText.get("Reset this entry i.e. cancels any changes."))); buttonPanel.add( changeClass = new CBButton( CBIntText.get("Change Classes"), CBIntText.get("Change the Object Class of this entry."))); buttonPanel.add( opAttrs = new CBButton( CBIntText.get("Properties"), CBIntText.get("View the Operational Attributes of this entry."))); // I don't really understand why we have to do this... // but without it these buttons over ride the default // button (Search Bar's search button), if they have // been clicked and the user hits the enter key? opAttrs.setDefaultCapable(false); submit.setDefaultCapable(false); reset.setDefaultCapable(false); changeClass.setDefaultCapable(false); setLayout(new BorderLayout(10, 10)); tableScroller = new JScrollPane(); attributeTable.setBackground(Color.white); tableScroller.setPreferredSize(new Dimension(300, 285)); tableScroller.setViewportView(attributeTable); add(tableScroller, BorderLayout.CENTER); add(buttonPanel, BorderLayout.SOUTH); if ("true".equals(JXConfig.getProperty("lock.read.only"))) title = CBIntText.get("Table Viewer"); else title = CBIntText.get("Table Editor"); setVisible(true); // triggers adding operational attributes of the current entry. opAttrs.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { displayOperationalAttributes(); } }); reset.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { myEditor.stopCellEditing(); // tableData.reset(); displayEntry(originalEntry, dataSource, false); } }); submit.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { doSubmit(); } }); // This allows the user to change the objectclass attribute. // This is pretty tricky, because it changes what attributes are available. changeClass.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { changeClass(); } }); attributeTable.addMouseListener( new MouseAdapter() { public void mousePressed(MouseEvent e) { if (!doPopupStuff(e)) super.mousePressed(e); } public void mouseReleased(MouseEvent e) { if (!doPopupStuff(e)) super.mouseReleased(e); } // TODO need to have a way to call this from a keystroke... public boolean doPopupStuff(MouseEvent e) { if (e.isPopupTrigger() == false) return false; int row = attributeTable.rowAtPoint(new Point(e.getX(), e.getY())); attributeTable.clearSelection(); attributeTable.addRowSelectionInterval(row, row); attributeTable.repaint(); popupTableTool.registerCurrentRow( (AttributeNameAndType) attributeTable.getValueAt(row, 0), (AttributeValue) attributeTable.getValueAt(row, 1), row, tableData.getRDN()); // active path also set by valueChanged popupTableTool.show(attributeTable, e.getX(), e.getY()); popupTableTool.registerCellEditor(myEditor); // TE: for bug fix 3107. return true; } }); }
/** * Clear out all the old editors, and get new editors corresponding to the new object classes. * * @param entry the entry to be displayed by all the editors * @param ds the datasource the editors may use for more info * @param ocs the object classes (in order) to find editors for. */ protected void setEditors(DXEntry entry, DataBrokerQueryInterface ds, Vector ocs) { try { clearPluggableEditors(); // clear all extra editors // search for unique structural editors... if ("false".equalsIgnoreCase(JXConfig.getProperty("plugins.ignoreUniqueness"))) { if (ocs == null) // TE: may happen if virtual entry. return; int size = ocs.size(); for (int i = 0; i < size; i++) { Object objectClass = ocs.get(i); if (objectClass != null) { PluggableEditor ed = getEditor(objectClass.toString()); if (ed != null && ed.isUnique() == true) // found a unique editor { // so clear old ones, addUniqueEditor(ed); // and use the unique one refreshEditors(entry, ds); // to display the data setCurrentEditor(ed); return; // ... and exit. } } } } else log.warning("skipping uniqueness test for pluggable editors"); boolean newEdSet = false; // search for non-unique structural editors for (int i = 0; i < ocs.size(); i++) { Object objectClass = ocs.get(i); if (objectClass != null) { PluggableEditor ed = getEditor(objectClass.toString()); if (ed != null) { addEditor(ed); // Force the displayed editor to be the first pluggable one... if (newEdSet == false) { setCurrentEditor(ed); newEdSet = true; } } } } // search for non-structural editors try { Attribute allOCs = entry.getAllObjectClasses(); if (allOCs != null) { Enumeration vals = allOCs.getAll(); while (vals.hasMoreElements()) { Object oc = vals.nextElement(); if (oc != null) { String ocName = oc.toString(); if (ocs.contains(ocName) == false) // don't bother with struct objectclasses dealt with above { PluggableEditor ed = getEditor(ocName); if (ed != null) { addEditor(ed); if (ed.isUnique()) // a special service to users... log.warning( "WARNING: Illegal unique editor defined for oc: " + ocName + " not allowed - (oc not in primary structural inheritance chain)"); } } } } } } catch (NamingException e) { log.log( Level.WARNING, "WARNING: non-fatal exception getting object classes for plugin editors. ", e); } addEditor(templateDisplay); // and always add old faithfulls... // XXX if (entry.getStatus() != DXEntry.NEW) // well, almost always... addEditor(tableDisplay); } catch (Exception e) { log.warning("Unexpected Exception in AttributeDisplay\n" + e); e.printStackTrace(); } }