⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 htmlpane.java

📁 Semantic Web Ontology Editor
💻 JAVA
📖 第 1 页 / 共 4 页
字号:

	public class FormActionEvent extends ActionEvent
	{	private final String 	 method;
		private final String 	 action;
		private final String	 name;
		private final Properties data = new Properties();

		// modified
		private FormActionEvent( String method, String action, String name, String data){
		    super( HTMLPane.this, 0, "submit" );
			this.method	= method;
			this.action	= action;
			this.name = name;
			try
			{
				data = UrlUtil.decodeUrlEncoding(data) + "\n" + dataFromContributors();
				this.data.load( new ByteArrayInputStream( data.getBytes()) );
			}
			catch( IOException e )
			{ //assert false : "\"Impossible\" IOException";
			}
		}
		/**
		 * @param method	method= attribute to Form tag.
		 * @param action	action= attribute to Form tag.
		 * @param data		Data provided by standard HTML element. Data
		 * 					provided by custom tags is appended to this set.
		 */
		private FormActionEvent( String method, String action, String data )
		{	super( HTMLPane.this, 0, "submit" );
			this.method	= method;
			this.action	= action;
			this.name = null;
			try
			{
				data = UrlUtil.decodeUrlEncoding(data) + "\n" + dataFromContributors();
				this.data.load( new ByteArrayInputStream( data.getBytes()) );
			}
			catch( IOException e )
			{ //assert false : "\"Impossible\" IOException";
			}
		}

		/** Return the method= attribute of the <form> tag */
		public String	  method()	{ return method; }

		/** Return the action= attribute of the <form> tag */
		public String	  action()	{ return action; }

		public String	  name()	{ return name; }
		/** Return the a set of properties representing the name=value
		 *  pairs that would be sent to the server on form submission.
		 */
		public Properties data()	{ return data; }

		/** Convenience method, works the same as
		 *  <code>(HTMLPane)( event.getSource() )</code>
		 */
		public HTMLPane source(){ return (HTMLPane)getSource(); }
	}
	//@form-action-event-end

	//-----------------------------------------------------------------
	public final void addActionListener( ActionListener listener )
	{	actionListeners = AWTEventMulticaster.add(actionListeners, listener);
	}

	public final void removeActionListener( ActionListener listener )
	{	actionListeners = AWTEventMulticaster.remove(actionListeners, listener);
	}

	private final void handleSubmit(final String method, final String action,
														  final String data )
	{	actionListeners.actionPerformed(
							new FormActionEvent
							(	method,
								action,
								UrlUtil.decodeUrlEncoding(data)
									+ "\n"
									+ dataFromContributors()
							)
						);
	}

	// modified
	private final void handleSubmit(final String method, final String action, 
	        						final String name, final String data )
	{	actionListeners.actionPerformed(
	        new FormActionEvent(method, action, name,
	                			UrlUtil.decodeUrlEncoding(data)
	                			+ "\n"
	                			+ dataFromContributors())
		);
	}
	
	/*package*/ final void handleInputActionTag( final String name )
	{	actionListeners.actionPerformed(new FormActionEvent( "", "", "" ));
	}

	/*** ****************************************************************
	 *   Add support for a custom tag.
	 *	 Custom tags may contain arbitrary attributes (which are passed to your
	 *	 handler in a {@link Properties} object). Elements specified
	 *	 by a custom tag may contain plain-text contents;
	 *	 any nested elements are discarded. The end-tag element is
	 *	 <u>required</u> in the input, since your handler isn't called
	 *	 until the end-tag element is found.
	 *	 <p>
	 *	 Only one handler can be registered for a given tag.
	 *	 If you register more than one, then the most recent registration wins.
	 *	 All tag handlers must be installed before the page is loaded
	 *	 by {@link #setText}, {@link #setPage}, or equivalent.
	 *	 <p>
	 *	 The handler can choose to return a JComponent, which will appear on
	 *	 the rendered page in place of the tag. By default, the component
	 *	 sits on the text baseline. Use {@link JComponent#setAlignmentY}
	 *	 to control the placement relative to the text baseline. A value of
	 *	 0.75 will place 75% of the Component above the baseline, for example.
	 *	 (a value of .85 is about right for a JLabel in the default font.)
	 *	 Here's a custom tag
	 *	 <code>&lt;holub:label text=&quot;<i>TEXT</i>&quot;&gt;</code>
	 *	 that is replaced by a JLabel that holds the <i>TEXT</i> string:
	 *	 <PRE>
     *  pane.addTag
     *  (   "myTag",
     *      new TagHandler()
     *      {   public JComponent
     *          handleTag(HTMLPane source, Properties attributes)
     *          {  JComponent view = new JLabel(attributes.getProperty("text"));
     *             view.setAlignmentY(0.85F);
     *             return view;
     *          }
     *      }
     *  );
     *  </PRE>
	 *	Tag handlers are shared by <u>all</u> instances of HtmlFrame.
	 *	<p>
	 *	Note that <b>tags are not case sensitive</b>, so regardless
	 *	of how the tag appears in the input (or in the tag argument),
	 *	it's treated as if it's all lower-case characters.
	 *
	 *	 @param tag the tag name (without any "angle" brackets).
	 *				Must be all-upper-case or all-lower-case
	 *	 		letters or underscores (no colons, no mixed case).
	 *			Normal HTML tags cannot be redefined.
	 *	 		Because of the way that the {@link JEditorPane} base
	 *	 		class works,
	 *	 		you can't use use "p-implied" or "content" as a custom-tag
	 *	 		name and you can't use "endtag=" as an attribute.
	 *			If assertions are enabled, attempts to register a
	 *			standard tag generate <code>AssertionError</code>s, but if
	 *			assertions are not  enabled, the request is logged,
	 *			but is otherwise ignored (and will form a minor memory leak.)
	 *
	 *	 @param handler The handler to call when the tag is encountered.
	 *	 @see TagHandler
	 */

	public final void addTag(String tag, TagHandler handler)
	{	tag = tag.toLowerCase();
		//assert !isStandardHTMLtag(tag) :
		//		"Illegal attempt to redefine standard HTML tag <"+tag+">";
		//log.info( "Adding custom tag <" + tag + ">" );
		tagHandlers.put( tag, handler );
	}

	/** Remove the handler for a given tag. Once this call is made,
	 *	 the tag will be ignored if it's encountered in a newly-loaded
	 *	 page. (A warning is logged if an unexpected tag is
	 *	 encountered, but this situation is not considered to be a
	 *	 run-time error.)
	 */

	public final void removeTag( String tag )
	{	tagHandlers.remove( tag );
	}


	/** Notify the JComponents associated with the custom tags that
	 *	 the user has hit the reset button.
	 */

	protected void doReset()
	{	for( Iterator i = contributors.iterator(); i.hasNext(); )
			((TagBehavior) i.next() ).reset();
	}

	/** Collect form data from the JComponents associated with the
	 *	 custom tags and append it to the data set passed to the
	 *	 form handlers. This method has been made protected so that
	 *	 overrides can do some sort of processing or filtering
	 *	 on the data if they need to.
	 *	 @return a set of newline-delimited key=value pairs contained
	 *	 in a single String.
	 */

	protected String dataFromContributors()
	{
		StringBuffer formData = new StringBuffer();
		for(Iterator i = contributors.iterator(); i.hasNext(); )
		{	formData.append( ((TagBehavior) i.next() ).getFormData() );
			formData.append("\n");
		}
		return formData.toString();
	}

	/** Workhorse function used by the assertion at the top of
	 *	 {@link #addTag}. You can use this method to see
	 *	 if a tag is available before attempting to register it.
	 *	 Note that the tag must be specified using all-lower-case
	 *	 characters.
	 *
	 *	 @return <code>true</code> if the tag argument specifies a standard
	 *	 HTML tag or one of the internal tags "p-implied" or "content."
	 *	 Otherwise, return <code>false</code>.
	 */

	public static final boolean isStandardHTMLtag(String tag)
	{	HTML.Tag[] allTags = HTML.getAllTags();

		if( tag.equals("p-implied") || tag.equals("content") )
			return true;

		for( int i = 0; i < allTags.length; ++i )
			if( allTags[i].toString().toLowerCase().equals(tag) )
				return true;

		return false;
	}

	/******************************************************************* 
	 * Provide input preprocessing.
	 * Use this method to replace the default input filter
	 * {@link FilterFactory#NULL_FACTORY}.
	 *
	 * @see FilterFactory
	 * @see NamespaceFilterFactory
	 */

	public void filterInput( FilterFactory provider )
	{	filterProvider = provider;
	}

	/**
	 *	A convenience method for local testing of a UI that will eventually
	 *	be web based. If you map your home URL to a local directory,
	 *	all links to the home URL are automatically replaced by
	 *	links to the directory. For example, given
	 *	<PRE>
	 *	myPane.addHostMapping( "www.holub.com", "file://c:/src/test" );
	 *	</PRE>
	 *	an HTML "anchor" that looks like this:
	 *	<PRE>
	 *	&lt;a href="http://www.holub.com/dir/foo.html"&gt;
	 *	</PRE>
	 *	is treated as if you had specified:
	 *	<PRE>
	 *	&lt;a href="file://c:/src/test/dir/foo.html"&gt;
	 *	</PRE>
	 *	Multiple mappings are supported. That is, if you call this method
	 *	more than once, then all the mappings you specify apply.
	 *	<p>
	 *	The host mappings are shared by <u>all</u> instances of
	 *	HtmlFrame, including popups created by target=_blank in a
	 *	hyperlink.
	 *
	 *	 @see #removeHostMapping
	 */
	public static final void addHostMapping( String thisHost,
										String mapsToThisLocation )
	{	if( hostMap == null )
			hostMap = new HashMap();

		hostMap.put( thisHost,
						new HostMapping(thisHost, mapsToThisLocation));
	}

	/** Remove a host mapping added by a previous call to
	 *	 {@link #addHostMapping}.
	 *	 @see #addHostMapping
	 */
	public static final void removeHostMapping( String thisHost )
	{	hostMap.remove(thisHost);
	}

	/** Map a url if there's an entry for the host portion in the host map.
	 *	 @param url a URL specified in terms of the "host" location.
	 *	 @return a URL for the mapped location.
	 *	 @see #addHostMapping
	 *	 @see #removeHostMapping
	 */
	public URL map(URL url)
	{	if( hostMap != null )
		{	HostMapping mapping = (HostMapping) hostMap.get(url.getHost());
			if( mapping != null )
				url = mapping.map( url );
		}
		return url;
	}

	/*******************************************************************
	 * This class handles the host-to-local-file mapping mechanics
	 *	 for {@link #addHostMapping}. The {@link #hostMap}
	 *	 table is a java.util.Map of objects of this class.
	 */
	private static final class HostMapping
	{	private final String remote;
		private final String local;
		public HostMapping( String remote, String local )
		{	this.remote = ".*://"   + remote.replaceAll("\\.", "\\.");
			this.local  = local ;
		}
		public URL map( URL page )
		{	try
			{	String s = page.toExternalForm();
				return new URL( s.replaceFirst(remote, local) );
			}
			catch( MalformedURLException e )
			{	log.warning( "Couldn't map " + remote + " to "
								+ local + ": " + e.getMessage() );
			}
			return page;
		}
	}
	//@hyperlink-handler-start
	/************************************************************************
	 *	This Hyperlink handler replaces the contents of the current pane
	 *	with whatever's at the indicated link. This code is copied more or
	 *	less verbatim from the Sun documentation. I've also added simple
	 *	support for the mailto: protocol.
	 */

	private final class HyperlinkHandler implements HyperlinkListener
	{	public void hyperlinkUpdate(HyperlinkEvent event)
		{	try
			{	if( event.getEventType() == HyperlinkEvent.EventType.ACTIVATED )
				{
					HTMLPane source 	 = (HTMLPane)event.getSource();
					String   description = event.getDescription();
					Element  e      	 = event.getSourceElement();

					// Get the attributes of the <a ...> tag that got
					// us here, then extract the target= attribute. If
					// we find target=_blank, then display the page
					// in a popup window. I'm assuming that the
					// href references an html file, because it wouldn't
					// make much sense to use target=_blank if it didn't.

 					AttributeSet tagAttributes = (AttributeSet)
							(e.getAttributes().getAttribute(HTML.Tag.A));

					String target = null;
					if( tagAttributes != null )
						target = (String) tagAttributes.getAttribute(
													HTML.Attribute.TARGET);

					if( target != null &&  target.equals("_blank")  )
					{	popupBrowser( event.getURL() );
						return;
					}

					// Handle http: and file: links. If the description
					// doesn't contain a protocol (there's no ':'),
					// then assume a "relative" link:

					if(		description.startsWith("http:")
						||	description.startsWith("file:")
						||	description.indexOf(":") == -1
					  )
					{
						JEditorPane pane = (JEditorPane) event.getSource();

						if(event instanceof HTMLFrameHyperlinkEvent)
						{  ((HTMLDocument)(source.getDocument())).
								 processHTMLFrameHyperlinkEvent(
										 	   (HTMLFrameHyperlinkEvent)event);
						}
						else if( !redirect(event.getURL()) )
						{  unknownRedirect(event.getDescription());
						}
					}
					else if( description.startsWith("mailto") )
					{	if( isWindows() )
						   Runtime.getRuntime().exec(
											"cmd.exe /c start " + description);
						else
						   unknownRedirect(event.getDescription());
					}
					else
					{	unknownRedirect( event.getDescription() );
					}
				}
			}
			catch( Exception e )
			{	log.warning
				( "Unexpected exception caught while processing hyperlink: "
					+ e.toString() + "\n"
					+ Log.stackTraceAsString( e )
				);
			}
		}

		/** Used for anchor tags that include target=_blank attributes. Pop up
		 *	 a new instance of an HTMLPanel in a subwindow, displaying the page
		 *	 whose URL is specified in the "description" argument.
		 */
		private final void popupBrowser( URL target )
												throws MalformedURLException
		{ 	JFrame	 popupFrame	= new JFrame();
			HTMLPane popup			= new HTMLPane();
			popupFrame.getContentPane().  add( new JScrollPane(popup) );

			popup.redirect(target);
			Dimension size = popup.getPreferredSize();
			Point location = getLocationOnScreen();
			popupFrame.setBounds(  location.x + 10,
									location.y + 10,
									size.width,
									size.height );
			popupFrame.show();
		}

		/** Mailto support is OS specific, so we need to know the OS.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -