2 Probleme mit Java-Browser (URL verändern & Layout)
wucher wichtel
- java
0 Slyh0 wucher wichtel0 wucher wichtel0 Slyh
3 Slyh
Hallo!
Wie einige vielleicht schon wissen, versuche ich Java zu lernen :) Das Lernen hat bei JavaScript mit viel Geduld und noch mehr Beispielen ganz gut geklappt. Das Problem bei Java ist, ist dass die Beispiele geringer werden, die man z.B. im Netz findet. Jetzt wollte ich mal einen Browser schreiben. Das ist mit Java nicht besonders schwer. Aber ich will auch ermöglichen, dass die URL der Seite per Textfield verändert werden kann. Aber das klappt leider nicht. Zudem kommt, dass ich massive Probleme mit den Layoutmanagern habe. Mein Browser sollte in etwa so aussehen:
|---------------------|
| |Textfield| |ok| |
|---------------------|
| |
| Browser |
| |
| |
Aber aussehen tut es so:
|---------------------|
| |
| |Textfield| |ok| |
Browser |
--------------------- |
Natürlich wird das komplette Fenster in zwei Teile geteilt (GridLayout), aber wie kann ich das erreichen (Welcher LayoutManager), dass das Textfield mit dem JButton nur genausoviel Platz einnimmt, wie es soll? Wenn man bei anderen Anwendungen die Fenstergröße verändert, dann wird die Tool-Leiste auch nicht größer, sondern nur z.B. das Dokument (Word) oder die Website (Firefox).
Wie kann ich für ein JPanel (Ist das für mein Vorhaben das richtige?), das das TextField und den Button enthält, eine feste Höhe angeben? Von mir aus 100px o.ä.?
Jetzt zu meinem zweiten Problem:
Wie schon klar geworden ist möchte ich ein JTextfield, in das der Anwender eine Adresse angeben kann. Diese Adresse soll dann per Klick auf den OK-Button angezeigt werden. Doch ich habe starke Probleme das Verändern der URL zu erreichen. Wie muss ich es schreiben, dass es klappt?
Hier der Quelltext mit Kommentaren:
package test;
import javax.swing.*;
import javax.swing.event.*;
import java.io.*;
import java.net.*;
import java.awt.event.*;
import java.awt.*;
class Test{
String neueSeite;
}
class Adresse{
static void SetzeURL(Test nS){
nS.neueSeite = adresse.getText();
//Hier meckert Java, weil es adresse nicht kennt. Ich weiß aber nicht, wie ich es schreiben muss, damit Java weiß was ich damit mein?!
}
}
public class JBrowserTextField extends JEditorPane implements HyperlinkListener {
JBrowserTextField( String url )
{
setEditable( false );
addHyperlinkListener( this );
try
{
setPage( new URL(url) );
}
catch ( IOException e ) { e.printStackTrace(); }
}
public void hyperlinkUpdate( HyperlinkEvent event )
{
HyperlinkEvent.EventType typ = event.getEventType();
if ( typ == HyperlinkEvent.EventType.ACTIVATED )
{
try
{
setPage( event.getURL() );
}
catch( IOException e ) {
JOptionPane.showMessageDialog( this,
"Can't follow link to "
+ event.getURL().toExternalForm(),
"Error",
JOptionPane.ERROR_MESSAGE);
}
}
}
public static void main(String[] args){
String startseite = "http://www.selfhtml.org";
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setLayout(new GridLayout(2,0));
JPanel eingabe = new JPanel();
final JTextField adresse = new JTextField(startseite);
final JButton ok = new JButton("OK");
eingabe.add(adresse);
eingabe.add(ok);
f.add(eingabe);
ActionListener al = new ActionListener(){
public void actionPerformed(ActionEvent e){
Adresse neueURL = new Adresse();
JBrowserTextField( neueURL );
//Hier meckert Java wegen dem Fehler weiter oben (siehe erster Kommentar).
//Wie muss ich in diesem ActionListener Java sagen, dass ich die URL verändern will? Stimmt das wenigstens ansatzweise mit JBrowserTextField(neueURL);?
//Wie kann ich den String mit der Adresse überall verfügbar machen? Ich habe das jetzt mit mehreren Klassen "gelöst" (Test & Adresse), weil ich ein Beispiel fand, das mir wenigstens diesen Weg gezeigt hat. Sicher ist das total umständlich oder sogar falsch, aber ich weiß nicht, wie ich es anders machen kann. Habt ihr einen Tipp?
}
};
f.setSize(600,500);
f.add(new JScrollPane(new JBrowserTextField(startseite)));
f.setVisible(true);
}
}
Vielen Dank für eure Hilfe!
ciao, ww
Hallo,
ich kümmere mich jetzt nur mal um dein erstes Problem.
Wie einige vielleicht schon wissen, versuche ich Java zu lernen :) Das Lernen hat bei JavaScript mit viel Geduld und noch mehr Beispielen ganz gut geklappt. Das Problem bei Java ist, ist dass die Beispiele geringer werden, die man z.B. im Netz findet.
Das glaube ich dir nicht...
Geringer als bei JavaScript, vielleicht. Aber man findet wirklich
massenhaft Code und Beispiele.
|---------------------|
| |Textfield| |ok| |
|---------------------|
| |
| Browser |
| |
| |
Aber aussehen tut es so:
|---------------------|
| |
| |Textfield| |ok| |
Browser --------------------- Natürlich wird das komplette Fenster in zwei Teile geteilt (GridLayout),
In zwei _gleich große_ Teile. Deshalb sieht das so aus.
aber wie kann ich das erreichen (Welcher LayoutManager), dass das Textfield mit dem JButton nur genausoviel Platz einnimmt, wie es soll?
Mit mehreren LayoutManagern sollte das möglich sein. Im Grunde würde
ich aber zum GridBagLayout raten. Damit kriegst du das gewünschte
Ergebnis recht schnell hin. Allerdings hat das GridBagLayout eine
recht steile Lernkurve. Dafür ist es aber auch mächtig.
So auf den ersten Blick müßte das Layout aber auch unter Verwendung
des BorderLayouts realisierbar sein, wobei zwei Layouts ineinander
verschachtelt werden müssten.
Im äußeren Layout packst du den Browser-Bereich in den CENTER. In den
NORTH-Bereich setzt du einen Container, z.B. JPanel, in dem sich
wiederum das Textfield und der Button befinden. Das JPanel erhält
auch BorderLayout als LayoutManager. Im JPanel kommt das Textfield
an die CENTER-Position und der Button an die EAST-Position.
(Letzteres hat allerdings den Nachteil, daß der Button dieselbe Höhe
wie das Textfield erhalten wird.)
Aber, wie gesagt, das GridBagLayout ist hier wohl sinnvoller.
Möglicherweise lassen sich auch andere LayoutManager auf die beschriebene
Weise so kombinieren, daß ein besseres Ergebnis herauskommt.
(Ich habe meine Angaben nicht getestet. Es ist durchaus möglich, daß
sie fehlerhaft sind und nicht das gewünschte Ergebnis erzielen.)
Ansonsten kann ich dir noch die JavaDocs und Tutorials zu den Java-
LayoutManager ans Herz legen.
Wie kann ich für ein JPanel (Ist das für mein Vorhaben das richtige?), das das TextField und den Button enthält, eine feste Höhe angeben? Von mir aus 100px o.ä.?
Wenn du LayoutManager verwendest, je nach LayoutManager gar nicht.
Aber das willst du auch nicht. Sonst würdest du ja keine LayoutManager
verwenden...
Gruß
Slyh
Hallo!
ich kümmere mich jetzt nur mal um dein erstes Problem.
Danke!
Das glaube ich dir nicht...
Geringer als bei JavaScript, vielleicht. Aber man findet wirklich
massenhaft Code und Beispiele.
Könntest du mir bitte einen Link posten? Ich habe schon viel geggogelt, bin aber auf keinen grünen Zweig gekommen. Eine solche Seite würde mir sehr helfen.
Aber, wie gesagt, das GridBagLayout ist hier wohl sinnvoller.
Ooh... der ist kompliziert :) Ich werde mich mal einarbeiten.
Ich habe es jetzt erstmal mit BorderLayout hinbekommen. Danke für die Beschreibung. Irgendwie fehlt(e) mir (noch) das Verständnis für soetwas. Wie damals beim Umstieg von Tabellen auf CSS-Layouts ;)
Ansonsten kann ich dir noch die JavaDocs und Tutorials zu den Java-
LayoutManager ans Herz legen.
Werde ich mir auf jeden Fall vornehmen!
Vielen Dank für deine Hilfe. Zumindest das mit dem Layout hätte sich geklärt. Vielen vielen Dank dafür.
ciao, ww
PS: Der jetzige Code sieht so aus:
package test;
import javax.swing.*;
import javax.swing.event.*;
import java.io.*;
import java.net.*;
import java.awt.event.*;
import java.awt.*;
import java.awt.BorderLayout.*;
class Test{
String neueSeite;
}
class Adresse{
static void SetzeURL(Test nS){
nS.neueSeite = adresse.getText();
}
}
public class JBrowserTextField extends JEditorPane implements HyperlinkListener {
JBrowserTextField( String url )
{
setEditable( false );
addHyperlinkListener( this );
try
{
setPage( new URL(url) );
}
catch ( IOException e ) { e.printStackTrace(); }
}
public void hyperlinkUpdate( HyperlinkEvent event )
{
HyperlinkEvent.EventType typ = event.getEventType();
if ( typ == HyperlinkEvent.EventType.ACTIVATED )
{
try
{
setPage( event.getURL() );
}
catch( IOException e ) {
JOptionPane.showMessageDialog( this,
"Can't follow link to "
+ event.getURL().toExternalForm(),
"Error",
JOptionPane.ERROR_MESSAGE);
}
}
}
public static void main(String[] args){
String startseite = "http://www.selfhtml.org";
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setLayout(new BorderLayout());
JPanel eingabe = new JPanel();
eingabe.setLayout(new BorderLayout());
final JTextField adresse = new JTextField(startseite);
final JButton ok = new JButton("OK");
eingabe.add(adresse, BorderLayout.CENTER);
eingabe.add(ok, BorderLayout.EAST);
f.add(eingabe, BorderLayout.NORTH);
ActionListener al = new ActionListener(){
public void actionPerformed(ActionEvent e){
Adresse neueURL = new Adresse();
JBrowserTextField( neueURL );
}
};
f.setSize(600,500);
f.add(new JScrollPane(new JBrowserTextField(startseite)));
f.setVisible(true);
}
}
Java meckert immer noch an den gleichen Stellen wie vorher, was das Verändern der URL betrifft.
Hallo!
Könntest du mir bitte einen Link posten? Ich habe schon viel geggogelt, bin aber auf keinen grünen Zweig gekommen. Eine solche Seite würde mir sehr helfen.
Ich weiß nicht, mit welchen Stichwörtern ich vor einiger Zeit gesucht habe, aber Google spuckt bei "Java Code" und "Java Sourcecode" einiges aus.
ciao, ww
Hallo,
Könntest du mir bitte einen Link posten? Ich habe schon viel geggogelt, bin aber auf keinen grünen Zweig gekommen. Eine solche Seite würde mir sehr helfen.
Naja, eine Seite, die allgemein Code bereitstellt, kenne ich nicht.
Wobei, doch, Google Code Search soll wohl so etwas sein.
Ich bilde mir außerdem ein, irgendwann mal auf eine Seite gestoßen zu
sein, die freien Code (sortiert nach Programmiersprache) zur Verfügung
stellt. Die Adresse weiß ich aber leider nicht mehr.
Ich dachte jedenfalls eher an Code für spezielle Probleme, wie eben
z.B. LayoutManager. Google hilft hier meistens weiter.
Für Code-Schnipsel ist allgemein der Java Almanac sehr zu empfehlen.
Da wird man für viele grundlegende Problemstellungen häufig schon
fündig.
Aber, wie gesagt, das GridBagLayout ist hier wohl sinnvoller.
Ooh... der ist kompliziert :) Ich werde mich mal einarbeiten.
Man gewöhnt sich recht schnell dran, nachdem man ein paar Beispiele
gemacht wird. Vom Prinzip her ist das GridBagLayout gar nicht so arg
weit von HTML-Tabellen weg...
Gruß
Slyh
Hallo,
Jetzt zu meinem zweiten Problem:
Wie schon klar geworden ist möchte ich ein JTextfield, in das der Anwender eine Adresse angeben kann. Diese Adresse soll dann per Klick auf den OK-Button angezeigt werden. Doch ich habe starke Probleme das Verändern der URL zu erreichen. Wie muss ich es schreiben, dass es klappt?
Ich gehe jetzt allgemein mal über deinen Code und sage etwas dazu, ohne
auf dein Problem einzugehen. Um den Code genauer zu verstehen, bin ich
jetzt ehrlich gesagt zu müde. Vielleicht kannst du meine Kommentare
soweit schonmal zur Kenntnis nehmen, ggf. den Code anpassen, nochmal
posten und so Hilfe erhalten.
Hier der Quelltext mit Kommentaren:
[code lang=java]
package test;import javax.swing.*;
import javax.swing.event.*;
import java.io.*;
import java.net.*;
import java.awt.event.*;
import java.awt.*;
Verwendest du eine IDE? Das solltest du ggf. langsam mal. Die kann dir
bei vielen Dingen schon weiterhelfen. Wie man von Hand kompiliert, hast
du vermutlich jetzt ja gelernt.
class Test{
String neueSeite;
}
Was macht das da?
class Adresse{
static void SetzeURL(Test nS){
Du solltest Methodennamen auf jeden Fall mit kleinem Anfangsbuchstaben
schreiben. Das ist eine Konvention in Java. Wenn ich auf Code stoße,
der großgeschrieben ist, denke ich sofort an eine Klasse und bin
verwirrt, wenn es doch keine ist. Den meisten anderen Entwicklern
wird das auch so gehen.
"nS" ist außerdem kein wirklich sprechender Name...
Wieso hat "nS" nicht gleich den Typ "String"? Ich nehme stark an, daß
du eine URL übergibst?! Du brauchst dafür keine eigene Klasse "Test"
bauen. Verwende als Datentyp einfach String.
nS.neueSeite = adresse.getText();
//Hier meckert Java, weil es adresse nicht kennt. Ich weiß aber nicht, wie ich es schreiben muss, damit Java weiß was ich damit mein?!
Wo kommt "adresse" her? Das sieht aus wie eine Instanzvariable von der
Klasse "Adresse". Ich sehe dort aber keine Instanzvariable die so
heißt. Was willst du hier tun?
}
}public class JBrowserTextField extends JEditorPane implements HyperlinkListener {
JBrowserTextField( String url )
{
setEditable( false );
addHyperlinkListener( this );try
{
setPage( new URL(url) );
}
catch ( IOException e ) { e.printStackTrace(); }
}
public void hyperlinkUpdate( HyperlinkEvent event )
{
HyperlinkEvent.EventType typ = event.getEventType();if ( typ == HyperlinkEvent.EventType.ACTIVATED )
{
try
{
setPage( event.getURL() );
}
catch( IOException e ) {
JOptionPane.showMessageDialog( this,
"Can't follow link to "
+ event.getURL().toExternalForm(),
"Error",
JOptionPane.ERROR_MESSAGE);
}
}
}
Den obenstehenden Code habe ich mir jetzt nicht näher angeschaut.
public static void main(String[] args){
String startseite = "http://www.selfhtml.org";JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setLayout(new GridLayout(2,0));JPanel eingabe = new JPanel();
Der Name "eingabe" ist irgendwie nicht so toll. :)
final JTextField adresse = new JTextField(startseite);
final JButton ok = new JButton("OK");eingabe.add(adresse);
eingabe.add(ok);
f.add(eingabe);ActionListener al = new ActionListener(){
Du machst mit "a1" (schlechter Name) gar nichts. Du solltest ihn noch
als ActionListener für den Button setzen...
public void actionPerformed(ActionEvent e){
Adresse neueURL = new Adresse();
JBrowserTextField( neueURL );
//Hier meckert Java wegen dem Fehler weiter oben (siehe erster Kommentar).
Das ist auch kein Wunder, weil das kein gültiger Code ist. (Außer ich
übersehe etwas.) Ich weiß auch nicht genau, was du da machen willst.
Es ist auch nicht "ansatzweise" richtig, nein. :)
Allgemein solltest du dir überlegen, ob das Befüllen des JFrame wirklich
in main() passieren sollte. Möglicherweise wäre ein Konstruktor oder
eine init()-Methode sinnvoller hierfür geeignet.
Dann solltest du dir ohnehin überlegen, ob es nicht klüger wäre, eine
Applikationsklasse (z.B. "MyBrowser") zu erstellen, die von JFrame
ableitet. So wird das oftmals in Java gelöst.
public class MyBrowser extends JFrame
In main() machst du im Prinzip nur noch folgendes:
MyBrowser myBrowser = new MyBrowser();
myBrowser.setSize(600, 500);
myBrowser.setVisible(true);
Das Code, der das Frame mit den Komponenten befüllt, würde sich dann
ab sofort im Konstruktor von MyBrowser befinden.
Die aktuelle Adresse könntest du in einer Instanzvariable(!) "adresse"
von MyBrowser speichern. Somit kannst du aus jeder Methode von MyBrower
auf die aktuelle Adresse zugreifen.
Im Konstruktor würdest du außerdem das ActionPerformed-Handling einrichten.
Entweder indem du das über eine anynome Inner-Klasse löst, so wie das
jetzt ansatzweise in deinem Code vorhanden ist, oder indem du MyBrowser
außerdem noch ActionListener implementieren läßt, so daß deine Klassen-
Deklaration so aussieht:
public class MyBrowser extends JFrame implements ActionListener
Du mußt dann natürlich die Methode "actionPerformed" implementieren.
Diese könnte dann durch den Aufruf von setPage() auf das JBrowserTextField-
Objekt die Seite wechseln.
Der Code könnte in etwa so aussehen:
adresse = adressTextfield.getText();
browserTextField.setPage(adresse);
Die Instanzvariable(!) "browserTextField" wäre also ein Objekt vom Typ
"JBrowserTextField", das du während der Initialisierung im Konstruktor
befüllst.
Aus JBrowserTextField machst du eine eigene Klasse in einer eigenen
.java-Datei.
So, mal sehen, ob du damit was anfangen kannst. Meine Beschreibung
ist möglicherweise ein bißchen durcheinander. Versuch dich mal ein
bißchen damit auseinanderzusetzen. Möglicherweise kommst du dann
schon drauf.
Falls du Fragen hast, weil ich zu wirr geschrieben habe oder falls
du sonst nicht weiterkommst, frag bitte einfach nach.
Ich gebe dir auf jeden Fall als Ratschlag, den Code vollständig von
vorne zu beginnen. Der bestehende Code ist nämlich stellenweise mehr
als falsch -- und zwar nicht nur syntaktisch -- und verwirrt dich in
seinem jetzigen Zustand sicherlich nur.
Insgesamt möchte ich dir noch folgende "Ratschläge" auf den Weg geben:
Du solltest dir klar werden, was eine lokale Variable und was eine
Instanzvariable ist. Das sind Grundlagen der Objektorientierung,
ohne die es nicht geht. Du solltest außerdem wissen, was Klassen sind
und wofür sie gut sind. Und wenn du das weißt, solltest du mit Übungen
anfangen, die einfachere Komponenten als die Browser-Komponente von
Java enthalten. :)
Gruß
Slyh
Hallo!
Vielen Dank für deine ausführliche Antwort! Jetzt gehe ich erst mal 8 Stunden lang in die Schule :'( und dann hoffe ich, dass ich Zeit habe deine ausführliche Antwort umzusetzen :) Vielen vielen Dank für dein Bemühen!
ciao, ww