📄 htmlpane.java
字号:
*/
private final boolean isWindows()
{ return( System.getProperty("os.name").toLowerCase().
indexOf("windows") != -1);
}
}
/*******************************************************************
* Handles hyperlinks for the http:// or file:// protocols.
* Not all files are loaded, and a name-based algorithm
* is used to determine what gets loaded and what doesn't
* get loaded.
* All requests that are not handled here (i.e. for a protocol
* other than http: or file:, or for a file with an extension
* not on the list, below) are routed to
* {@link #unknownRedirect(String)}
* for processing.
* Overload the current method to change the way that the
* http: and file: protocols are processed.
* Overload {@link #unknownRedirect(String)} to add support
* for other protocols.
* <p>
* Any host mappings specified to
* {@link #addHostMapping} are processed first.
* Then, those URLs that end in
* one of the following extensions are handled.
* <table border=0 cellspacing=0 cellpadding=0>
* <tr><td><code>.shtml</code></td><td> HTML file </td></tr>
* <tr><td><code>.html </code></td><td> HTML file </td></tr>
* <tr><td><code>.htm </code></td><td> HTML file </td></tr>
* <tr><td><code>.pl </code></td><td> Perl script </td></tr>
* <tr><td><code>.jsp </code></td><td> Java Server Page </td></tr>
* <tr><td><code>.asp </code></td><td> Active Server Page </td></tr>
* <tr><td><code>.php </code></td><td> PHP script </td></tr>
* <tr><td><code>.py </code></td><td> Python Script </td></tr>
* </table>
* <p>
* All URL's whose paths do not have a '.' in the string that follows the
* rightmost slash (including directory specifications, which should be
* terminated by a slash) are assumed to reference an implicit index.html
* file. Similarly, a URL that specifies a host or directory, but no file
* (e.g. "http://www.holub.com" or "http://www.holub.com/directory/),
* is loaded.
* <p>
* N.B.: A relative file that doesn't have an extension (such as
* <code><a href=filename></code> is not recognized as
* an HTML file, so is not processed.
* <p>
* You can override this method if you need to change this default
* behavior, This method is called from the Swing Event Thread, so
* it's safe for your override to use
* {@link JEditorPane#setPage(URL)}
*
* @param page the target page. Must be a file: or http: URL.
* @return true if the page was handled. If you return false,
* {@link #unknownRedirect(String)} is given a chance
* to process it.
*/
public boolean redirect( URL page )
{ //assert( page.getProtocol().equals("http")
// || page.getProtocol().equals("file") );
try
{ String file = page.getFile();
if( !(file.length()==0 || htmlExtensions.matcher(file).matches()) )
return false;
setPage( page ); // local version of setPage handles host mapping
}
catch (Throwable t)
{ String message = "HTMLPane couldn't open hyperlink: "
+ t.getMessage();
log.warning( message );
JOptionPane.showMessageDialog(
HTMLPane.this,
message,
"401 Error",
JOptionPane.WARNING_MESSAGE );
}
return true;
}
/** A regular expression that identifies all file extensions
* recognized by {@link #redirect(URL)}
* as an HTML file. The same expression also recognizes
* directories (that end in a slash) and all file names
* that don't have an extension.
*/
private static final Pattern htmlExtensions =
Pattern.compile( "(.*\\.(html|htm|pl|jsp|asp|php|py|shtml)([?#].*)?$)"
+ "|(.*/[^\\./]+([?#].*)?$)"
+ "|(.*/([?#].*)?$)",
Pattern.CASE_INSENSITIVE );
/** Handles all hyperlink protocols that aren't recognized by
* {@link #redirect redirect(...)}.
* Is also called if a mailto: protocol is specified and
* we're not running under Windows. This implementation just logs
* a warning to "com.holub.ui" and pops up a warning-style dialog box
* indicating that the protocol isn't supported. You can override
* this method to support protocols other than file:// and http://
*/
public void unknownRedirect( String request )
{ log.warning("HTMLPane: Protocol or file type not supported ("
+ request + ")" );
JOptionPane.showMessageDialog
( HTMLPane.this,
"Protocol or file type not supported (" + request + ")",
"Link Error",
JOptionPane.WARNING_MESSAGE
);
}
//@hyperlink-handler-end
/*******************************************************************
* Overrides {@link JEditorPane#setText(String)}
* to do general housekeeping.
* @see #setPage(URL)
* @see #setPage(String)
*/
public final void setText(String text)
{ handlePageShutdown();
super.setText(text);
}
/** Overrides {@link JEditorPane#setPage(URL)} to
* map hosts, and do general housekeeping.
* @see #setText(String)
* @see #setPage(String)
*/
public final void setPage(URL url) throws IOException
{ handlePageShutdown();
super.setPage( map(url) );
}
/** This version of setPage is disabled in an HTMLPane. You can
* use setPage(new URL(...)); if all you have is a string.
* @see #setText(String)
* @see #setPage(URL)
* @throws UnsupportedOperationException always
*/
public final void setPage(String location)
{ throw new UnsupportedOperationException(
"setPage(String) not supported by HTMLPane" );
}
/** Read is disabled in an HTMLPane.
* @throws UnsupportedOperationException always
*/
public void read(InputStream in, Object desc) throws IOException
{ throw new UnsupportedOperationException(
"read() not supported by HTMLPane" );
}
/** A version of {@link JEditorPane#setPage(URL)}
* that can be called safely from somewhere other than a Swing
* event handler. Note that your form handlers <i>are</i>
* being called from an event handler.
*/
public void setPageAsynchronously(final URL page) throws IOException
{ SwingUtilities.invokeLater
( new Runnable()
{ public void run()
{ try
{ setPage(page);
}
catch(IOException e)
{ log.warning("HTMLPane: setPage() failed on Event Thread");
}
}
}
);
}
//@end
/*******************************************************************
* A test class. Creates pages using test/main.html and
* test/submit.html. This test is, unfortunately, highly interactive.
*/
private static class Test
{
static
{
try
{ UIManager.setLookAndFeel(
UIManager.getSystemLookAndFeelClassName() );
}
catch( Exception e )
{ e.printStackTrace();
System.exit(-1);
}
}
public static void main( String[] args )
{
try
{ // Use the Windows look and feel.
URL mainPage;
mainPage =new URL( args.length >= 1
? args[0]
: "file:/c:/src/com/holub/ui/HTML/test/main.html" );
Log.toScreen("com.holub.ui");
final HTMLPane pane = new HTMLPane();
pane.addActionListener
( new ActionListener()
{ public void actionPerformed( ActionEvent event )
{
FormActionEvent act = (FormActionEvent)event;
act.data().list(System.out);
String value = act.data().getProperty( "value" );
if( value != null && value.equals("Cancel") )
{ System.out.println("CANCEL");
}
else
{ System.out.println("\n"+ act.getActionCommand() );
System.out.println("\t"+"method=" + act.method() );
System.out.println("\t"+"action=" + act.action() );
act.data().list( System.out );
System.out.println("");
try
{ act.source().setPage
( new URL(
"file:/c:/src/com/holub/ui/HTML/test/submit.html")
);
}
catch( Exception e )
{ e.printStackTrace();
}
System.out.println("");
}
}
}
);
pane.addHostMapping( "www.test.com",
"file:/c:/src/com/holub/ui/test" );
// should fail with an assertion because of null handler
try { pane.addTag( "B", null ); } catch(AssertionError e){}
pane.addTag
( "size",
new TagHandler()
{ public JComponent
handleTag(HTMLPane source, Properties attributes)
{ source.setPreferredSize
( new Dimension
( Integer.parseInt(attributes.getProperty("width")),
Integer.parseInt(attributes.getProperty("height"))
)
);
return null;
}
}
);
// Converts tags of the form <abcd:efg> into <abcd_efg>
// The algorithm looks for a <, followed by non-white
// characters other than >, followed by a :, and replaces
// the : with an _.
pane.filterInput( new NamespaceFilterFactory() );
pane.addTag // handle <holub:JLabel> tags
( "holub_JLabel",
new TagHandler()
{ public JComponent
handleTag(HTMLPane source,Properties a)
{ JComponent view = new JLabel(a.getProperty("text"));
view.setAlignmentY(0.85F);
return view;
}
}
);
class ContributingText extends JTextField implements TagBehavior
{ private final String value;
private final String name;
public ContributingText(String name, String value)
{ super(value);
this.name =name;
this.value =value;
}
public void reset()
{
setText( value );
invalidate();
}
public void destroy()
{ System.out.println("Destroying <textInput> control");
}
public String getFormData ()
{ return name + "=" + getText();
};
public Dimension getPreferredSize()
{ return new Dimension(150,20);
}
public Dimension getMinimumSize()
{ return getPreferredSize();
}
public Dimension getMaximumSize()
{ return getPreferredSize();
}
}
pane.addTag
( "textInput",
new TagHandler()
{ public JComponent
handleTag(HTMLPane source,Properties attributes)
{ return new ContributingText
( attributes.getProperty("name"),
attributes.getProperty("value") );
}
}
);
pane.addTag
( "test",
new TagHandler()
{ public JComponent
handleTag(HTMLPane source,Properties attr)
{ System.out.println
( "\n<"
+ attr.getProperty(HTMLPane.TAG_NAME)
+">"
);
attr.list( System.out );
return null;
}
}
);
JFrame frame = new JFrame();
frame.addWindowListener
( new WindowAdapter()
{ public void windowClosing( WindowEvent e )
{ System.exit(255);
}
}
);
frame.getContentPane().add( new JScrollPane(pane) );
try
{ pane.setPage( mainPage );
}
catch(Exception e)
{ System.err.println( "Can't open " + mainPage + "\n" );
e.printStackTrace();
}
frame.setSize( pane.getPreferredSize() );
frame.pack();
frame.show();
/*
createSmallFrame
( new Runnable()
{ public void run()
{ createSmallFrame(null);
}
}
);
*/
}
catch( Throwable e )
{ e.printStackTrace();
}
}
}
// Create a small frame. When it shuts down (is submitted)
// it executes r.run() [before disposing the current window]
//
private static void createSmallFrame( final Runnable r )
{
try
{
final JFrame frame = new JFrame();
final HTMLPane pane = new HTMLPane();
pane.addActionListener
( new ActionListener()
{ public void actionPerformed(ActionEvent e)
{
if( r != null )
r.run();
frame.setVisible(false);
frame.dispose();
}
}
);
pane.setPage(
new URL("file:/c:/src/com/holub/ui/HTML/test/second.html"));
frame.getContentPane().add( pane );
frame.pack();
frame.show();
}
catch(Exception e)
{ e.printStackTrace();
}
}
}
//@end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -