diff --git a/flying-saucer-examples/src/main/java/org/xhtmlrenderer/demo/docbook/ShowDocBookPage.java b/flying-saucer-examples/src/main/java/org/xhtmlrenderer/demo/docbook/ShowDocBookPage.java deleted file mode 100644 index 938f1f83e..000000000 --- a/flying-saucer-examples/src/main/java/org/xhtmlrenderer/demo/docbook/ShowDocBookPage.java +++ /dev/null @@ -1,120 +0,0 @@ -package org.xhtmlrenderer.demo.docbook; - -import org.xhtmlrenderer.layout.SharedContext; -import org.xhtmlrenderer.simple.FSScrollPane; -import org.xhtmlrenderer.simple.XHTMLPanel; -import org.xhtmlrenderer.swing.Java2DTextRenderer; -import org.xhtmlrenderer.swing.NaiveUserAgent; -import org.xhtmlrenderer.util.XRLog; - -import javax.swing.*; -import java.awt.*; -import java.awt.event.ActionEvent; -import java.io.InputStream; -import java.net.URL; - -public class ShowDocBookPage { - public JFrame frame; - - private static class ResourceLoadingUserAgent extends NaiveUserAgent { - @Override - protected InputStream resolveAndOpenStream(String uri) { - InputStream result = super.resolveAndOpenStream(uri); - if (result == null && uri != null && uri.startsWith("file:")) { - return ShowDocBookPage.class.getResourceAsStream(uri.substring("file:".length())); - } else { - return result; - } - } - } - - public static void main(final String[] args) { - SwingUtilities.invokeLater(() -> { - String uri = "/docbook/xml/plugin-implement.xml"; - if (args.length > 0) uri = args[0]; - - new ShowDocBookPage().run(uri); - }); - } - - private static void usage(int i, String reason) { - String s = "org.xhtmlrenderer.demo.docbook.ShowDocbookPage" + - "\n" + - "Simple example to render a single DocBook XML page, " + - "using only CSS, in a Swing JFrame/JPanel " + - "using Flying Saucer." + - "\n\n" + - "Usage: \n" + - " java org.xhtmlrenderer.demo.docbook.ShowDocbookPage [uri]" + - "\n\n" + - "Error: " + reason; - System.out.println(s); - System.exit(i); - } - - private void run(final String uri) { - frame = new JFrame("Show Sample DocBook XML Rendered with Pure CSS"); - frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - - final XHTMLPanel panel = new XHTMLPanel(); - panel.getSharedContext().setUserAgentCallback(new ResourceLoadingUserAgent()); - setAntiAlias(panel); - - FSScrollPane fsp = new FSScrollPane(panel); - frame.getContentPane().add(fsp, BorderLayout.CENTER); - - frame.pack(); - frame.setSize(1024, 768); - frame.setVisible(true); - - SwingUtilities.invokeLater(() -> { - URL url = ShowDocBookPage.class.getResource(uri); - String urls = url.toExternalForm(); - XRLog.general("Loading URI: " + urls); - panel.setDocument(urls); - - showAboutDialog(); - }); - } - - private void setAntiAlias(XHTMLPanel introPanel) { - SharedContext sharedContext = introPanel.getSharedContext(); - sharedContext.setTextRenderer(new Java2DTextRenderer()); - } - - private void showAboutDialog() { - final JDialog aboutDlg = new JDialog(frame); - aboutDlg.setSize(new Dimension(500, 450)); - - XHTMLPanel panel = new XHTMLPanel(); - setAntiAlias(panel); - panel.setOpaque(false); - - URL url = ShowDocBookPage.class.getResource("/docbook/xhtml/intro.xhtml"); - panel.setDocument(url.toExternalForm()); - - JPanel outer = new JPanel(new BorderLayout()); - outer.add(panel, BorderLayout.CENTER); - final JButton btn = new JButton(new AbstractAction("OK") { - @Override - public void actionPerformed(ActionEvent e) { - aboutDlg.dispose(); - } - }); - JPanel control = new JPanel(new FlowLayout(FlowLayout.RIGHT)); - control.add(btn); - outer.add(control, BorderLayout.SOUTH); - - aboutDlg.getContentPane().setLayout(new BorderLayout()); - aboutDlg.getContentPane().add(outer, BorderLayout.CENTER); - - aboutDlg.setTitle("About the Browser Demo"); - - int xx = (frame.getWidth() - aboutDlg.getWidth()) / 2; - int yy = (frame.getHeight() - aboutDlg.getHeight()) / 2; - aboutDlg.setLocation(xx, yy); - aboutDlg.setModal(true); - SwingUtilities.invokeLater(() -> aboutDlg.setVisible(true)); - SwingUtilities.invokeLater(() -> btn.requestFocusInWindow()); - } -} \ No newline at end of file diff --git a/flying-saucer-examples/src/main/java/org/xhtmlrenderer/demo/docbook/package-info.java b/flying-saucer-examples/src/main/java/org/xhtmlrenderer/demo/docbook/package-info.java deleted file mode 100644 index 476803aa9..000000000 --- a/flying-saucer-examples/src/main/java/org/xhtmlrenderer/demo/docbook/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -@NullMarked -package org.xhtmlrenderer.demo.docbook; - -import org.jspecify.annotations.NullMarked; \ No newline at end of file diff --git a/flying-saucer-examples/src/main/resources/docbook/xml/plugin-implement.xml b/flying-saucer-examples/src/main/resources/docbook/xml/plugin-implement.xml deleted file mode 100644 index cb2db6f18..000000000 --- a/flying-saucer-examples/src/main/resources/docbook/xml/plugin-implement.xml +++ /dev/null @@ -1,1185 +0,0 @@ - - - - - - - - - - - - -Implementing a Simple Plugin - - - There are many applications for the leading operating systems that - provide a scratch-pad or sticky note - facility for the desktop display. A similar type of facility operating - within the jEdit display would be a convenience. The use of dockable - windows would allow the notepad to be displayed or hidden with a single - mouse click or keypress (if a keyboard shortcut were defined). The - contents of the notepad could be saved at program exit (or, if earlier, - deactivation of the plugin) and retrieved at program startup or plugin - activation. - - - - We will keep the capabilities of this plugin modest, but a few - other features would be worthwhile. The user should be able to write - the contents of the notepad to storage on demand. It should also be - possible to choose the name and location of the file that will be - used to hold the notepad text. This would allow the user to load - other files into the notepad display. The path of the notepad file - should be displayed in the plugin window, but will give the user the - option to hide the file name. Finally, there should be an action - by which a single click or keypress would cause the contents of the - notepad to be written to the new text buffer for further processing. - - - - The full source code for QuickNotepad is contained in jEdit's - source code distribution. We will provide excerpts in this discussion - where it is helpful to illustrate specific points. You are invited - to obtain the source code for further study or to use as a starting point - for your own plugin. - - - -<indexterm> - <primary>Plugin API</primary> - <secondary>loading at startup</secondary> -</indexterm> -How Plugins are Loaded - - - We will - discuss the implementation of the QuickNotepad - plugin, along with the jEdit APIs - it makes use of. But first, we describe how plugins are loaded. - - - - As part of its startup routine, jEdit's main - method calls various methods to load and initialize plugins. - - - - Additionally, plugins using the new jEdit 4.2 plugin API can be - loaded and unloaded at any time. This is a great help when - developing your own plugins -- there is no need to restart the - editor after making changes (see ). - - - - Note that plugins using the older jEdit 4.1 API are still only loaded on editor startup, and unloaded on editor exit. The jEdit 4.1 API is deprecated and will not be described in this guide. - - - - Plugins are loaded from files with the .jar - filename extension located in the jars - subdirectories of the jEdit installation and user settings directories - (see ). - - - - For each JAR archive file it finds, jEdit scans its entries and - performs the following tasks: - - - - - Adds to a collection maintained by jEdit a new object of - type - PluginJAR. This is a data structure - holding the name of the JAR archive file, a reference to the - - JARClassLoader, and a collection - of plugins found in the archive file. - - - Loads any properties defined in files ending with - the extension .props that are contained - in the archive. See . - - - Reads action definitions from any file named - actions.xml in the archive (the file need - not be at the top level). See . - - - Parses and loads the contents of any file named - dockables.xml in the archive (the file need - not be at the top level). This file contains BeanShell code for - creating docking or floating windows that will contain the visible - components of the plugin. Not all plugins define dockable - windows, - but those that do need a dockables.xml file. - See . - - - Checks for a class name with a name ending with - Plugin.class. - - - Such a class is known as a plugin core class and must - extend jEdit's abstract - - EditPlugin - class. The initialization routine checks the plugin's - properties to see if it is subject to any dependencies. For example, a - plugin may require that the version of the Java runtime environment or - of jEdit itself be equal to or above some threshold version. A plugin - can also require the presence of another plugin. - - - If any dependency is - not satisfied, the loader marks the plugin as broken and - logs an error message. - - - - - - After scanning the plugin JAR file and loading any resources, - a new instance - of the plugin core class is created and added to the collection - maintained by the appropriate - PluginJAR. - jEdit then calls the - start() method of the plugin core class. - The start() method can perform initialization of the - object's data members. - Because this method is defined as an empty no-op in the - - EditPlugin abstract class, a plugin need not - provide an implementation if no unique initialization is required. - - - - -Updating 4.1 plugins - - - Note that while jEdit 4.1 plugins were only loaded on startup, jEdit 4.2 plugins can be loaded at any time. As a result, the start() method needs to cope with being called at any time, and stop() needs to fully clean up after the plugin. See the API documentation for the - EditPlugin class for details. - - - - - -The QuickNotepadPlugin Class - - - The major issues encountered when writing a plugin core class arise - from the developer's decisions on what features the plugin will make - available. These issues have implications for other plugin elements - as well. - - - - - Will the plugin provide for actions that the user can trigger using - jEdit's menu items, toolbar buttons and keyboard shortcuts? - - - Will the plugin have its own visible interface? - - - Will the plugin have settings that the user can configure? - - - Will the plugin - respond to any messages reflecting changes in the host - application's state? - - - - - - Recall that the plugin core class must extend - - EditPlugin. - In QuickNotepad's plugin core class, there are no special - initialization or shutdown chores to perform, so we will not need - a start() or stop() method. - - - - The resulting plugin core class is lightweight and straightforward to implement: - - - - -public class QuickNotepadPlugin extends EditPlugin { - public static final String NAME = "quicknotepad"; - public static final String MENU = "quicknotepad.menu"; - public static final String PROPERTY_PREFIX - = "plugin.QuickNotepadPlugin."; - public static final String OPTION_PREFIX - = "options.quicknotepad."; - - - - First we define a few static - String data members to enforce consistent syntax - for the name of properties we will use throughout the plugin. - - - - - - - - public void createMenuItems(Vector menuItems) { - menuItems.addElement(GUIUtilities.loadMenu(MENU)); - } - - - This implementation of - the - EditPlugin.createMenuItems() method - is very typical. - It uses a jEdit utility function to create the menu, taking the list - of actions from the quicknotepad property, and - the label from quotenotepad.label. - - - - If the plugin only had a single menu item (for example, an item - activating a dockable window), we would call - - GUIUtilities.loadMenuItem() instead of - - GUIUtilities.loadMenu(). - - - - - - -public void createOptionPanes(OptionsDialog od) { - od.addOptionPane(new QuickNotepadOptionPane()); - } - - -} - - - This implementation of - the - EditPlugin.createOptionPanes() method - adds a new instance of QuickNotepadOptionPane - to the given instance of the Global Options - dialog box. - - - - - - - - -The EditBus - - - Plugins register - EBComponent instances with the - - EditBus to receive messages reflecting - changes in jEdit's state. - - - - The message - classes derived from - EBMessage cover the opening - and closing of the application, changes in the status of buffers and views, - changes in user settings, as well as changes in - the state of other program features. A full list of messages can be found in the - org.gjt.sp.jedit.msg - package. - - - - - EBComponents are added and removed with the - - EditBus.addToBus() and - - EditBus.removeFromBus() - methods. - - - - Typically, the - EBComponent.handleMessage() method - is implemented with one or more if blocks that test - whether the message is an instance of a derived message class in - which the component has an interest. - - -if(msg instanceof BufferUpdate) { - // a buffer's state has changed! -} -else if(msg instanceof ViewUpdate) { - // a view's state has changed! -} -// ... and so on - - - If a plugin core class will respond to EditBus - messages, it can be derived from - - EBPlugin, in which case no explicit - addToBus() call is necessary. - Otherwise, - - EditPlugin will suffice as a - plugin base class. Note that QuickNotepad uses the latter. - - - - -The Property File - - - jEdit maintains a list of properties, which are - name/value pairs used to store human-readable strings, user settings, - and various other forms of meta-data. During startup, jEdit loads the - default set of properties, followed by plugin properties stored in - plugin JAR files, finally followed by user properties. - - - - Some properties are used by the plugin API itself. Others are - accessed by the plugin using methods in the - - jEdit - class. - - - - Property files contained in plugin JARs must end with the filename - extension .props, and have a very simple syntax, - which the following example illustrates: - - -# Lines starting with '#' are ignored. -name=value -another.name=another value -long.property=Long property value, split over \ - several lines -escape.property=Newlines and tabs can be inserted \ - using the \t and \n escapes -backslash.property=A backslash can be inserted by writing \\. - - - - Now we look at the QuickNotepad.props file - which contains properties for the QuickNotepad plugin. - The first type of property data is information about the plugin itself; - these are the only properties that must be specified in order for the - plugin to load: - - -# general plugin information -plugin.QuickNotepadPlugin.activate=defer -plugin.QuickNotepadPlugin.name=QuickNotepad -plugin.QuickNotepadPlugin.author=John Gellene -plugin.QuickNotepadPlugin.version=4.1 -plugin.QuickNotepadPlugin.docs=QuickNotepad.html -plugin.QuickNotepadPlugin.depend.0=jedit 04.02.10.00 - - These properties are described in detail in the documentation for the - - EditPlugin class - and do not require further - discussion here. - - - - Next in the file comes a property that sets the title of the - plugin's dockable window. Dockable windows are discussed in detail - in . - - -# dockable window name -quicknotepad.title=QuickNotepad - - - Next, we see menu item labels for the plugin's actions. - Actions are discussed in detail - in . - - -# action labels -quicknotepad.label=QuickNotepad -quicknotepad.choose-file.label=Choose notepad file -quicknotepad.save-file.label=Save notepad file -quicknotepad.copy-to-buffer.label=Copy notepad to buffer - - - Next, the plugin's menu is defined. See - . - - -# application menu items -quicknotepad.menu.label=QuickNotepad -quicknotepad.menu=quicknotepad - quicknotepad.choose-file \ - quicknotepad.save-file quicknotepad.copy-to-buffer - - - We have created a small toolbar as a component of QuickNotepad, so - file names for the button icons follow: - - -# plugin toolbar buttons -quicknotepad.choose-file.icon=Open.png -quicknotepad.save-file.icon=Save.png -quicknotepad.copy-to-buffer.icon=Edit.png - - - The menu item labels corresponding to these icons will also serve as tooltip - text. - - - - Finally, the properties file set forth the labels and settings - used by the option pane: - - -# Option pane labels -options.quicknotepad.label=QuickNotepad -options.quicknotepad.file=File: -options.quicknotepad.choose-file=Choose -options.quicknotepad.choose-file.title=Choose a notepad file -options.quicknotepad.choose-font=Font: -options.quicknotepad.show-filepath.title=Display notepad file path - -# Initial default font settings -options.quicknotepad.show-filepath=true -options.quicknotepad.font=Monospaced -options.quicknotepad.fontstyle=0 -options.quicknotepad.fontsize=14 - -# Setting not defined but supplied for completeness -options.quicknotepad.filepath= - - - -Updating 4.1 plugins - - - jEdit 4.2 plugins are distinguished from jEdit 4.1 plugins by the presence of the plugin.name.activate property. If this property is set, the plugin is treated like a jEdit 4.2 plugin. Usually, this property should be set to defer. See the API documentation for the - EditPlugin class for details. - - - - - -The Action Catalog - - - Actions define procedures that can be bound to a menu - item, a toolbar button or a keyboard shortcut. Actions are short - scripts written in BeanShell, jEdit's macro scripting - language. These scripts either direct the action themselves, - delegate to a method in one of the plugin's classes that - encapsulates the action, or do a little of both. The scripts are - usually short; elaborate action protocols are usually contained in - compiled code, rather than an interpreted macro script, to speed - execution. - - - - Actions are defined by creating an XML file entitled - actions.xml and placing it in the plugin JAR - file. - - - - The actions.xml - file from the QuickNotepad plugin looks - as follows: - - - - - - wm.addDockableWindow(QuickNotepadPlugin.NAME); - wm.getDockableWindow(QuickNotepadPlugin.NAME).chooseFile(); - - - - - - wm.addDockableWindow(QuickNotepadPlugin.NAME); - wm.getDockableWindow(QuickNotepadPlugin.NAME).saveFile(); - - - - - - wm.addDockableWindow(QuickNotepadPlugin.NAME); - wm.getDockableWindow(QuickNotepadPlugin.NAME).copyToBuffer(); - - -]]> - - - This file defines three actions. They use the current view's - - DockableWindowManager object and the method - getDockable() to find the QuickNotepad plugin - window and call the desired method. - - - - When an action is invoked, the BeanShell scripts address - the plugin through static methods, or if instance data is needed, the - current - View, its - - DockableWindowManager, and the plugin - object return by the getDockable() method. - - - - If you are unfamiliar with BeanShell code, you may nevertheless notice - that the code statements bear a strong resemblance to Java code, with - one exception: the - variable view is never assigned any value. - - - - For complete answers to this and other BeanShell - mysteries, see ; two - observations will suffice here. First, the variable - view is predefined by jEdit's implementation of - BeanShell to refer to the current View object. - Second, the - BeanShell scripting language is based upon Java syntax, but allows - variables to be typed at run time, so explicit types for variables - need not be declared. - - - - A formal description of each element of the - actions.xml file can be found in the - documentation of the - - ActionSet class. - - - - -The Dockable Window Catalog - - - The jEdit plugin API uses BeanShell to create the top-level visible container - of a plugin's interface. The BeanShell code is contained in a file named - dockables.xml. It usually is quite short, providing only - a single BeanShell expression used to create a visible plugin window. - - - - The following example from the QuickNotepad plugin illustrates the - requirements of the data file: - - - - - - - - - new QuickNotepad(view, position); - -]]> - - - -In this example, the <DOCKABLE> element has -a single attribute, the dockable window's identifier. This attribute is -used to key a property where the window title is stored; see -. - - - - - -The contents of the <DOCKABLE> element itself is a -BeanShell expression that constructs a new QuickNotepad -object. The view and position are -predefined by the plugin API as the view in which the plugin window will reside, -and the docking position of the plugin. - - - - - A formal description of each element of the - dockables.xml file can be found in the - documentation of the - - DockableWindowManager class. - - - - -The QuickNotepad Class - - - Here is where most of the features of the plugin will be implemented. - To work with the dockable window API, the top level window will be a - JPanel. The visible components reflect a - simple layout. Inside the top-level panel we will place a scroll pane with - a text area. Above the scroll pane we will place a panel containing a small - tool bar and a label displaying the path of the current notepad file. - - - - We have identified three user actions that need - implementation here: chooseFile(), - saveFile(), and - copyToBuffer(). As noted earlier, we also want the - text area to change its appearance in immediate response to a change in - user options settings. In order to do that, the window class must - respond to a PropertiesChanged message from - the EditBus. - - - - - - Unlike the EBPlugin class, the - EBComponent interface does not deal with the - component's actual subscribing and unsubscribing to the EditBus. To - accomplish this, we use a pair of methods inherited from the - Java platform's JComponent class - that are called when the window is made visible, and when it is hidden. - These two methods, - addNotify() and - removeNotify(), are overridden to add and remove - the visible window from the list of EditBus subscribers. - - - - We will provide for two minor features when the notepad is - displayed in the floating window. First, when a floating plugin window - is created, we will give the notepad text area input focus. Second, - when the notepad if floating and has input focus, we will have the - Escape key dismiss the notepad window. An - AncestorListener and a - KeyListener will implement these details. - - - - Here is the listing for the data members, the constructor, and the - implementation of the EBComponent interface: - - - -public class QuickNotepad extends JPanel - implements EBComponent -{ - private String filename; - private String defaultFilename; - private View view; - private boolean floating; - - private QuickNotepadTextArea textArea; - private QuickNotepadToolPanel toolPanel; - - // - // Constructor - // - - public QuickNotepad(View view, String position) - { - super(new BorderLayout()); - - this.view = view; - this.floating = position.equals( - DockableWindowManager.FLOATING); - - this.filename = jEdit.getProperty( - QuickNotepadPlugin.OPTION_PREFIX - + "filepath"); - if(this.filename == null || this.filename.length() == 0) - { - this.filename = new String(jEdit.getSettingsDirectory() - + File.separator + "qn.txt"); - jEdit.setProperty(QuickNotepadPlugin.OPTION_PREFIX - + "filepath",this.filename); - } - this.defaultFilename = new String(this.filename); - - this.toolPanel = new QuickNotepadToolPanel(this); - add(BorderLayout.NORTH, this.toolPanel); - - if(floating) - this.setPreferredSize(new Dimension(500, 250)); - - textArea = new QuickNotepadTextArea(); - textArea.setFont(QuickNotepadOptionPane.makeFont()); - textArea.addKeyListener(new KeyHandler()); - textArea.addAncestorListener(new AncestorHandler()); - JScrollPane pane = new JScrollPane(textArea); - add(BorderLayout.CENTER, pane); - - readFile(); - } - - // - // Attribute methods - // - - // for toolBar display - public String getFilename() - { - return filename; - } - - // - // EBComponent implementation - // - - public void handleMessage(EBMessage message) - { - if (message instanceof PropertiesChanged) - { - propertiesChanged(); - } - } - - - private void propertiesChanged() - { - String propertyFilename = jEdit.getProperty( - QuickNotepadPlugin.OPTION_PREFIX + "filepath"); - if(!defaultFilename.equals(propertyFilename)) - { - saveFile(); - toolPanel.propertiesChanged(); - defaultFilename = propertyFilename.clone(); - filename = defaultFilename.clone(); - readFile(); - } - Font newFont = QuickNotepadOptionPane.makeFont(); - if(!newFont.equals(textArea.getFont())) - { - textArea.setFont(newFont); - textArea.invalidate(); - } - } - - // These JComponent methods provide the appropriate points - // to subscribe and unsubscribe this object to the EditBus - - public void addNotify() - { - super.addNotify(); - EditBus.addToBus(this); - } - - - public void removeNotify() - { - saveFile(); - super.removeNotify(); - EditBus.removeFromBus(this); - } - - ... - -} - - - This listing refers to a QuickNotebookTextArea - object. It is currently implemented as a JTextArea with - word wrap and tab sizes hard-coded. Placing the object in a separate - class will simply future modifications. - - - - -The QuickNotepadToolBar Class - - - There is nothing remarkable about the toolbar panel that is placed - inside the QuickNotepad object. The constructor - shows the continued use of items from the plugin's properties file. - - -public class QuickNotepadToolPanel extends JPanel -{ - private QuickNotepad pad; - private JLabel label; - - public QuickNotepadToolPanel(QuickNotepad qnpad) - { - pad = qnpad; - JToolBar toolBar = new JToolBar(); - toolBar.setFloatable(false); - - toolBar.add(makeCustomButton("quicknotepad.choose-file", - new ActionListener() { - public void actionPerformed(ActionEvent evt) { - QuickNotepadToolPanel.this.pad.chooseFile(); - } - })); - toolBar.add(makeCustomButton("quicknotepad.save-file", - new ActionListener() { - public void actionPerformed(ActionEvent evt) { - QuickNotepadToolPanel.this.pad.saveFile(); - } - })); - toolBar.add(makeCustomButton("quicknotepad.copy-to-buffer", - new ActionListener() { - public void actionPerformed(ActionEvent evt) { - QuickNotepadToolPanel.this.pad.copyToBuffer(); - } - })); - label = new JLabel(pad.getFilename(), - SwingConstants.RIGHT); - label.setForeground(Color.black); - label.setVisible(jEdit.getProperty( - QuickNotepadPlugin.OPTION_PREFIX - + "show-filepath").equals("true")); - this.setLayout(new BorderLayout(10, 0)); - this.add(BorderLayout.WEST, toolBar); - this.add(BorderLayout.CENTER, label); - this.setBorder(BorderFactory.createEmptyBorder(0, 0, 3, 10)); - } - - ... - -} - - - The method makeCustomButton() provides uniform - attributes for the three toolbar buttons corresponding to three of the - plugin's use actions. The menu titles for the user actions serve double - duty as tooltip text for the buttons. There is also a - propertiesChanged() method for the toolbar that - sets the text and visibility of the label containing the notepad file path. - - - - -The QuickNotepadOptionPane Class - - - Using the default implementation provided by - AbstractOptionPane reduces the preparation of an - option pane to two principal tasks: writing a - _init() method to layout and initialize the pane, - and writing a _save() method to commit any settings - changed by user input. If a button on the option pane should trigger - another dialog, such as a JFileChooser or jEdit's - own enhanced VFSFileChooserDialog, the option - pane will also have to implement the - ActionListener interface to display additional - components. - - - - The QuickNotepad plugin has only three options to set: the path name of - the file that will store the notepad text, the visibility of the - path name on the tool bar, and the notepad's display font. - Using the shortcut methods of the plugin API, the implementation of - _init() looks like this: - - -public class QuickNotepadOptionPane extends AbstractOptionPane - implements ActionListener -{ - private JTextField pathName; - private JButton pickPath; - private FontSelector font; - - ... - - public void _init() - { - showPath = new JCheckBox(jEdit.getProperty( - QuickNotepadPlugin.OPTION_PREFIX - + "show-filepath.title"), - jEdit.getProperty( - QuickNotepadPlugin.OPTION_PREFIX + "show-filepath") - .equals("true")); - addComponent(showPath); - - pathName = new JTextField(jEdit.getProperty( - QuickNotepadPlugin.OPTION_PREFIX - + "filepath")); - JButton pickPath = new JButton(jEdit.getProperty( - QuickNotepadPlugin.OPTION_PREFIX - + "choose-file")); - pickPath.addActionListener(this); - - JPanel pathPanel = new JPanel(new BorderLayout(0, 0)); - pathPanel.add(pathName, BorderLayout.CENTER); - pathPanel.add(pickPath, BorderLayout.EAST); - - addComponent(jEdit.getProperty( - QuickNotepadPlugin.OPTION_PREFIX + "file"), - pathPanel); - - font = new FontSelector(makeFont()); - addComponent(jEdit.getProperty( - QuickNotepadPlugin.OPTION_PREFIX + "choose-font"), - font); - } - - ... - -} - - - Here we adopt the vertical arrangement offered by use of the - addComponent() method with one embellishment. - We want the first row of the option pane to contain - a text field with the current notepad file path and a button that will - trigger a file chooser dialog when pressed. To place both of them on - the same line (along with an identifying label for the file option), - we create a JPanel to contain both components and - pass the configured panel to addComponent(). - - - - The _init() method uses properties from the plugin's - property file to provide the names of label for the components placed - in the option pane. It also uses a property whose name begins with - PROPERTY_PREFIX as a persistent data item - the - path of the current notepad file. The elements of the notepad's font - are also extracted from properties using a static method of the option - pane class. - - - - The _save() method extracts data from the user - input components and - assigns them to the plugin's properties. The implementation is - straightforward: - - -public void _save() -{ - jEdit.setProperty(QuickNotepadPlugin.OPTION_PREFIX - + "filepath", pathName.getText()); - Font _font = font.getFont(); - - jEdit.setProperty(QuickNotepadPlugin.OPTION_PREFIX - + "font", _font.getFamily()); - jEdit.setProperty(QuickNotepadPlugin.OPTION_PREFIX - + "fontsize", String.valueOf(_font.getSize())); - jEdit.setProperty(QuickNotepadPlugin.OPTION_PREFIX - + "fontstyle", String.valueOf(_font.getStyle())); - jEdit.setProperty(QuickNotepadPlugin.OPTION_PREFIX - + "show-filepath", String.valueOf(showPath.isSelected())); -} - - - The class has only two other methods, one to display a file chooser - dialog in response to user action, and the other - to construct a Font object from the plugin's font - properties. They do not require discussion here. - - - - -Plugin Documentation - - - While not required by the plugin API, a help file is an essential - element of any plugin written for public release. A single web page is - often all that is required. There are no specific requirements on - layout, but because of the design of jEdit's help viewer, the use of - frames should be avoided. Topics that would be useful include - the following: - - - - - - a description of the purpose of the plugin; - - - - - an explanation of the type of input the user can supply through its - visible interface (such as mouse action or text entry in controls); - - - - - a listing of available user actions that can be taken when the - plugin does not have input focus; - - - - - a summary of configuration options; - - - - - information on development of the plugin (such as a change log, - a list of to do items, and contact information for - the plugin's author); and - - - - - licensing information, including acknowledgments for any library - software used by the plugin. - - - - - - The location of the plugin's help file is stored in the - plugin.QuickNotepad.docs - property; see . - - - - -Compiling the Plugin - - - We have already outlined the contents of the user action catalog, the - properties file and the documentation file in our earlier discussion. - The final step is to compile the source file and build the archive file - that will hold the class files and the plugin's other resources. - - - - Publicly released plugins include with their source a makefile - in XML format for the - Ant utility. The format for this file - requires few changes from plugin to plugin. Here is the version of - build.xml used by QuickNotepad and many other - plugins: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -]]> - - - For a full discussion of the Ant file format and - command syntax, you should consult the Ant - documentation site. Modifying this makefile for a different - plugin will likely only require three changes: - - - - - the name of the plugin; - - - the choice of compiler (made by inserting and deleting the comment character - '#'); and - - - the classpath variables for jedit.jar - any plugins this one depends on. - - - - - -Reloading the Plugin - - - Once you have compiled your plugin using the 4.2 API you will need to reload - it to test it. Follow these steps to reload your plugin without restarting jEdit: - - - - - From the Plugins menu open the Plugin Manager. - - - On the Manage tab uncheck Hide libraries. This will - allow you to see plugins that are not loaded. - - - Find the plugin on the Manage tab and uncheck it. This will unload the plugin. - You will get a warning if this plugin does not support dynamic reloading. - If you get that warning you will need to restart jEdit to reload the plugin - until the plugin is converted over to the 4.2 API. - - - Recheck the plugin to reload it. - - - - - - The jEdit web site contains a macro and an Ant task that can be used as an alternative - method for dynamically reloading plugins. - - - - - - If you have reached this point in the text, you are probably serious - about writing a plugin for jEdit. Good luck with your efforts, and - thank you for contributing to the jEdit project. - - - - - diff --git a/src/packaging/docbook/docbook_demo.jnlp b/src/packaging/docbook/docbook_demo.jnlp deleted file mode 100644 index 24f912509..000000000 --- a/src/packaging/docbook/docbook_demo.jnlp +++ /dev/null @@ -1,22 +0,0 @@ - - - - DocBook XML/CSS Demo - Flying Saucer - - - Flying Saucer DocBook XML/CSS Demo - A demonstration of the Flying Saucer XHTML - renderer with a page containing DocBook XML, rendered using pure CSS. - FS DocBook Demo - - - - - - - - - - -