> does ne1 hav any clue as to how to go about building a browser using
> java..im lost
As with any software project, start with the requirements. Until you know
exactly what you want to achieve, you can't really plan to achieve it.
Are you talking about a fully-featured web-browser for veiwing any page on
the public Internet with full JavaScript and CSS support? That's a huge
task (look how long it took the Mozilla Foundation with hundreds of
volunteers). If it's just for viewing specific pages that you have some
control over, then things start to become more manageable since you can
restrict yourself to well-formed XHTML and not worry about having to parse
the tag soup. Even so, just the layout engine for that is a big project.
Dan.
--
Daniel Dyer
http://www.uncommons.org
Here's one:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.html.*;
public class Browser {
private JTextField addressField;
private JEditorPane editorPane;
private void initComponents() {
addressField = new JTextField(50);
editorPane = new JEditorPane();
editorPane.setEditable( false );
addressField.addActionListener( new ActionListener() {
public void actionPerformed( ActionEvent e ) {
setPage( addressField.getText().trim() );
}
});
editorPane.addHyperlinkListener( new HyperlinkListener() {
public void hyperlinkUpdate( HyperlinkEvent e ) {
if ( e.getEventType() ==
HyperlinkEvent.EventType.ACTIVATED ) {
if ( e instanceof HTMLFrameHyperlinkEvent ) {
HTMLFrameHyperlinkEvent evt =
(HTMLFrameHyperlinkEvent)e;
HTMLDocument doc =
(HTMLDocument)editorPane.getDocument();
doc.processHTMLFrameHyperlinkEvent( evt );
} else {
setPage( e.getURL().toString() );
}
}
}
});
}
public void setPage( String page ) {
try {
editorPane.setPage( page );
addressField.setText( page );
} catch ( Exception ex ) {
JOptionPane.showMessageDialog( null, ex.getMessage() );
}
}
private JComponent createAddressPanel() {
JLabel addressLabel = new JLabel("Address" );
addressLabel.setDisplayedMnemonic( KeyEvent.VK_A );
addressLabel.setLabelFor( addressField );
Box addressPanel = new Box( BoxLayout.X_AXIS );
addressPanel.add( addressLabel );
addressPanel.add( Box.createHorizontalStrut(5) );
addressPanel.add( addressField );
return addressPanel;
}
private void createAndShowGUI() {
initComponents();
JPanel contentPanel = new JPanel( new BorderLayout() );
JComponent addressPanel = createAddressPanel();
addressPanel.setBorder( BorderFactory.createEmptyBorder(5,5,5,5) );
contentPanel.add( addressPanel, BorderLayout.NORTH );
contentPanel.add( new JScrollPane(editorPane) );
JFrame frame = new JFrame("Browser");
frame.setDefaultCloseOperation( JFrame.DISPOSE_ON_CLOSE );
frame.setContentPane( contentPanel );
frame.pack();
frame.setVisible(true);
}
public static final void main( String args[] ) {
EventQueue.invokeLater( new Runnable() {
public void run() {
new Browser().createAndShowGUI();
}
});
}
}
Bye
Michael
See the book "Just Java" 5th edition by Peter van der Linden. It has code
for a small browser. IIRC it is around 200 lines.
// __
public class Browser00{
private JTextField addressField;
private JTextPane JTxtPn;
// __
private void initComponents(){
addressField = new JTextField(50);
JTxtPn = new JTextPane();
// __
String aCntntEnc;
aCntntEnc = "text/html; charset=utf-8";
aCntntEnc = "text/html; charset=GB2312";
JTxtPn.setContentType(aCntntEnc);
JTxtPn.setEditable( false );
// __
addressField.addActionListener( new ActionListener(){
public void actionPerformed( ActionEvent e ){
setPage( addressField.getText().trim() );
}
});
// __
JTxtPn.addHyperlinkListener( new HyperlinkListener(){
public void hyperlinkUpdate( HyperlinkEvent e ){
if ( e.getEventType() == HyperlinkEvent.EventType.ACTIVATED ){
if ( e instanceof HTMLFrameHyperlinkEvent ){
HTMLFrameHyperlinkEvent evt = (HTMLFrameHyperlinkEvent)e;
HTMLDocument doc = (HTMLDocument)JTxtPn.getDocument();
doc.processHTMLFrameHyperlinkEvent( evt );
}
else{ setPage( e.getURL().toString() ); }
}
}
});
}
// __
public void setPage( String page ){
try{
System.out.println("// - - - - - - - - - - - - - - - - - - ");
System.out.println("// __ page: " + page);
System.out.println("// __ Before JTxtPn.setPage(): " +
JTxtPn.getEditorKit().getContentType());
JTxtPn.setPage( page );
System.out.println("// __ After JTxtPn.setPage(): " +
JTxtPn.getEditorKit().getContentType());
addressField.setText( page );
}catch ( Exception ex ){ JOptionPane.showMessageDialog( null,
ex.getMessage()); }
}
// __
private JComponent createAddressPanel(){
JLabel addressLabel = new JLabel("Address" );
addressLabel.setDisplayedMnemonic( KeyEvent.VK_A );
addressLabel.setLabelFor( addressField );
Box addressPanel = new Box( BoxLayout.X_AXIS );
addressPanel.add( addressLabel );
addressPanel.add( Box.createHorizontalStrut(5) );
addressPanel.add( addressField );
return addressPanel;
}
// __
private void createAndShowGUI(){
initComponents();
JPanel contentPanel = new JPanel( new BorderLayout() );
JComponent addressPanel = createAddressPanel();
addressPanel.setBorder( BorderFactory.createEmptyBorder(5,5,5,5) );
contentPanel.add( addressPanel, BorderLayout.NORTH );
contentPanel.add( new JScrollPane(JTxtPn), BorderLayout.CENTER );
JFrame frame = new JFrame("Browser00");
frame.setDefaultCloseOperation( JFrame.DISPOSE_ON_CLOSE );
frame.setContentPane( contentPanel );
frame.pack();
frame.setVisible(true);
}
// __
public static final void main( String args[] ){
EventQueue.invokeLater( new Runnable(){
public void run(){ new Browser00().createAndShowGUI(); }
});
}
}
It *can* display such pages. You don't have to specify the encoding.
E. g. point your "browser" to
You'll see a page containing greek glyphs. If not, either your fonts
don't support it or it might be a bug in your java version :)
> .
> also I don't quite understand what is meant in the specification with:
If you e.g. use setContentType("text/plain") this method will set the
right EdiorKit (not HTMLEditorKit).
<api>
There are multiple ways to get a character set mapping to happen with
JEditorPane.
1. One way is to specify the character set as a parameter of the
MIME type. This will be established by a call to the setContentType
method. If the content is loaded by the setPage method the content type
will have been set according to the specification of the URL. It the
file is loaded directly, the content type would be expected to have been
set prior to loading.
2. Another way the character set can be specified is in the document
itself. This requires reading the document prior to determining the
character set that is desired. To handle this, it is expected that the
EditorKit.read operation throw a ChangedCharSetException which will be
caught. The read is then restarted with a new Reader that uses the
character set specified in the ChangedCharSetException (which is an
IOException).
</api>
> .
> How can you display non-ASCII characters using a basic java-based
> browser like this one?
It is encoding-aware already.
> .
> // - - - - - - - - - - - THE CODE
Please follow the conventions and don't capitalize variable names (it's
jTxtPn not JTxtPn).
Bye
Michael
I think sun had a java browser called "Hot Java" it's now obsolete but
the source code is available for research. you can go there and
download it.
Bassel
C:\cmllpz_dir\dev\java\JBrowser\HotJava\hjb115-generic\HotJava1.1.5\bin>echo
off
.
" CLASSPATH:" ~\HotJava\hjb115-generic\HotJava1.1.5\lib\classes;.
" HOTJAVA_HOME:" ~\HotJava\hjb115-generic\HotJava1.1.5
" JAVA_HOME:" ~\j2sdk1.4.2_12
.
[Starting HotJava]
[Initializing globals]
java.util.MissingResourceException: Can't find bundle for base name
hjResourceBundle, locale en_US
at
java.util.ResourceBundle.throwMissingResourceException(ResourceBundle.java:838)
at
java.util.ResourceBundle.getBundleImpl(ResourceBundle.java:807)
at java.util.ResourceBundle.getBundle(ResourceBundle.java:551)
at sunw.hotjava.misc.Globals.initProperties(Globals.java:312)
at sunw.hotjava.Main.main(Main.java:79)
java.lang.Exception: Failed to load localized properties:
java.util.MissingResourceException: Can't find bundle for base name
hjResourceBundle, locale en_US
at sunw.hotjava.misc.Globals.initProperties(Globals.java:316)
at sunw.hotjava.Main.main(Main.java:79)
error: Failed to load localized properties:
java.util.MissingResourceException: Can't find bundle for base name
hjResourceBundle, locale en_US
// __
.
otf
If you've problems with reading Chinese characters from a stream, the
character encoding used for reading is wrong.
If you've problems rendering Chinese characters, the used font doesn't
include these.
E.g. the following
import javax.swing.*;
public class Unicode {
public static final void main( String args[] ) {
JFrame frame = new JFrame("Unicode");
frame.setDefaultCloseOperation( JFrame.DISPOSE_ON_CLOSE );
frame.getContentPane().add( new JLabel("\u4e10 \u2704") );
frame.pack();
frame.setVisible( true );
}
}
can be used to display a chinese symbol [1] and a dingbat symbol [2]
(scissors).
Since the fonts I use don't include chinese characters (but dingbat
symbols) I get a small rectangle followed by the scissors.
[1] http://www.unicode.org/charts/PDF/U4E00.pdf
[2] http://www.unicode.org/charts/PDF/U2700.pdf
Bye
Michael
Code2000 - 51,239 characters (61,864 glyphs) in version 1.16
Includes many characters that are difficult to find elsewhere, making
it a useful font to assign to the user-defined encoding or character
set in your Web browser, and well worth the $5 registration. Produced
by James Kass.
Family: Serif
Styles: Regular
Availability: shareware $5 payable via paypal to
jame...@code2000.net
http://www.code2000.net/code2000_page.htm
.
// __
and with this piece of code (again reworking/repurposing yours ;-))
you can load TTFs from a local file (without tinkering with
font.properties) and see both the chinese chars and the scissors
.
// __
import java.awt.*;
import javax.swing.*;
import java.io.*;
// __
public class UnicodeFrm06{
private static Font dynFnt32Pt = null;
// __
public static void main( String args[] ){
// __ with Cyberbit TTF fonts you see then the Chinese chars but not
the scissors
String aTTF_Fl = "/lib/fonts/Cyberbit.ttf";
// __ with CODE2000 TTF fonts you see both
aTTF_Fl = "/lib/fonts/CODE2000.TTF";
// __
String aJvHmProp = System.getProperty("java.home");
File Fl = new File(aJvHmProp, aTTF_Fl);
String aFlPath = Fl.getAbsolutePath();
// __
float fSz = 32f;
dynFnt32Pt = setCtxtFonts(aFlPath, fSz);
if(dynFnt32Pt != null){
JFrame frame = new JFrame("UnicodeFrm06");
frame.setDefaultCloseOperation( JFrame.DISPOSE_ON_CLOSE );
JLabel Ji18nLbl = new JLabel("\u4e10 \u2704");
Ji18nLbl.setBackground(Color.white);
Ji18nLbl.setFont(dynFnt32Pt);
Ji18nLbl.setToolTipText(" TTFs from: " + aFlPath);
frame.getContentPane().add(Ji18nLbl);
frame.getContentPane().setBackground(Color.white);
frame.pack();
frame.setVisible(true);
}
else{ System.err.println("// __ Fonts could not be set from file: |"
+ aFlPath + "|"); }
}
// __ loading fonts from a data feed programatically
private static Font setCtxtFonts(String aFlPath, float fSz){
Font Fnt = null;
try{
FileInputStream FIS = new FileInputStream((new File(aFlPath)));
Font dynFnt = Font.createFont(Font.TRUETYPE_FONT, FIS);
Fnt = dynFnt.deriveFont(fSz);
FIS.close();
}catch(FileNotFoundException FlNF){ FlNF.printStackTrace(); }
catch(FontFormatException FFX){ FFX.printStackTrace(); }
catch(IOException IOX){ IOX.printStackTrace(); }
// __
return(Fnt);
}
}