Sie befinden sich hier: Home » Wissenstransfer » Java » Java FAQ
Java FAQ
Übersicht
- Lang
- Util
- Awt
- Swing
- Applets
- Net, RMI
- JSP/Servlets
- IO
- XML
- JDBC
- Java ME
- Externe Bibliotheken
- Enterprise Java / JPA / Hibernate / Entwurf
- Tools
- Laufzeitumgebung, JVM
Andere FAQs
- jGuru FAQ
- Java FAQ (Peter van der Linden. Letzte Änderung 2001)
- comp.lang.java FAQ (Elliotte Rusty Harold. Letzte Änderung 1997)
- FAQ der Newsgroup de.comp.lang.java (Letzte Änderung 2004)
- Java 3D FAQ
- Frequently Asked Questions About JDBC (Sun)
- Java Network Programming FAQ (David Reilly. Letzte Änderung 2000)
Lang
Ich benötige eine Routine zur Bestimmung aller Subklassen einer Klasse bzw. aller Klassen die ein Interface implementieren zur Laufzeit. Leider scheint mit Java Reflection (Class etc.) hier keine Lösung anzubieten (in SmallTalk-80 wäre das kein Problem gewesen ;-)
Das Problem lässt sich allgemein auch in Java nicht lösen. Die einzige bekannte (suboptimale) Lösung ist, sich eine Liste aller Klassen zu besorgen (auch das funktioniert nur im Spezialfall) und dann jede Klasse zu fragen, ob sie Unterklasse ist. Dabei muss jedes Class-Objekt auch geladen werden -- die Performance ist natürlich richtig schlecht. Dieser Ansatz wird etwa hier realisiert: http://freerails.cvs.sourceforge.net/freerails/jfreerails/src/jfreerails/util/ClassLocater.java?revision=1.2&view=markup. Die Idee ist, zu schauen, welcher Klassenlader die Klassen lädt, und dann über diesen an das Verzeichnis bzw. Jar-Archiv heranzukommen und das dann vollständig zu durchsuchen.
Eine andere Lösung, die oft vorgeschlagen wird, ist die, dass man jede Klasse in einem static {} Block an einer Zentrale anmeldet, sodass man später nur noch diese Zentrale als "Liste aller Klassen" durchsuchen muss. Wenn die Klassen über ein Framework wie JPA oder Spring verwaltet werden ist das auch wieder einfacher. Bei JPA/Hibernate kann zum Beispiel eine Anfrage auf Entity-Beans wie "select o from java.lang.Object o" helfen.
Ich möchte einen Byte Array per OutputStream senden. Leider werden alle Werte größer als 0x7F als Integer 0x0000 interpretiert? Warum ist das so? Wie kann ich Werte wie 0x80 und größer als Byte Array definieren?
byte[] data = { 0x6f, 0x00 };
Es fehlt eine Typanpassung so wie bei byte b = (byte) 0x6f.
long und double sind ja nicht atomare Datentypen. Ist denn eine Objektzuweisung atomar?
Object a,b; a = new Object(); b = a; //atomar?
Ja das ist auch atomar. Entweder gibt's eine Zuweisung oder keine. Eine Unterbrechung in der Hälfte, wie es tatsächlich prinzipiell bei long/double vorkommen kann, gibt es hier nicht.
Wie viel Speicherplatz verbracht etwa ein String-Objekt? Sind das die üblichen 256 Byte oder ist das dynamisch, je nach Länge des Strings?
Die Größe ist dynamisch mit dem String. Wenn du näheres über den Speicherverbrauch herausfinden möchtest, kannst du dir von der Sun-Seite das Tool "hat" holen. Dies ist ein Server, der dir den Speicherverbrauch auflistet.
Aus einem Buch unter dem Kapitel "Sprachdesign und Compiler" habe ich folgenden Satz gefunden und als Zitat in meiner Diplomarbeit verwendet: "Variablen können bei der Initialisierung mit dem Schlüsselwort "final" gekennzeichnet werden, was bedeutet, dass sich der Wert dieser Variablen nicht mehr verändern kann." Der Kommentar meines Prof. war: "So einfach ist das nicht"! Ist es nicht so, dass eine mit final deklarierte Variable nicht mehr verändert werden kann?
Worauf dein Prof anspielt ist, dass man final Variablen nicht zwingend
bei der Deklaration einen Wert zuweisen muss. Dies kann man später machen,
dann aber nur einmal. Nun muss der Compiler durch Flussanalyse verfolgen, ob
schon jemand schreibend zugegriffen hat. Und da hat sich der Javac damals in
die Nesseln mit gesetzt und das mach den jikes heute immer noch so. Das
Problem war ein switch(). Wenn man den durchfallen lässt, kann man in beiden
Teilen die Variable belegen. Ein Beispiel dafür findest du in der FAQ.
Das mit final Variablen und Zuweisungen führt manches mal zu sehr
abgefahrenen Lösungen, etwa in der System Klasse. Dort sind die
Konsolenströme (in,out,err) final und über einen Hack werden sie nativ bei
einer Systeminitialisierung wieder geändert. Das musste man machen, da final
Variablen prinzipiell inline gesetzt werden könnte. Das musste man
verhindern.
Kann mir jemand sagen, wie ich den Exponenten und die Mantisse(?) von double erhalte?
In der Double Klasse findet man die statische Methode doubleToLongBits(). Dort kannst du ein Long bekommen und die Doku beschreibt, an welcher Bitposition Mantisse und Exponent liegen.
Kennt jemand eine bessere Methode, in Java Potenzen von (kleinen) ganzen Zahlen zu berechnen, als java.lang.Math.pow() zu benutzen und dann von double auf int zu casten?
Wenn man nur 2^n braucht, dann tut es doch ein Shift. Man muss dann aber aufpassen, dass die Bits nicht rausrutschen.
int twoPow( long n )
{
return 1 << n;
}Ab welcher Anzahl von Threads, die von einem Applet gestartet werden, könnte es Probleme geben (etwa drastische Geschwindigkeitseinbußen, Abstürze oder sonstige unerwünschte Erscheinungen.
Na ja, das hängt wohl auch von der Maschine ab ;-) Es ist allerdings ein
beliebte Angriff (DOA, DOS), so viele Threads zu starten, dass das System
aufgibt. Eine Beschränkung aus Java gibt es nicht, wird aber bemängelt. Gute
BSY lässt sich die maximale Anzahl von Prozessen oder Threads einstellen.
Bei nativen Threads könnte hier das BSY einlenken. (Da hat doch ein
intelligenter Student doch tatsächlich mal so viele Threads gestartet, bis
Windoof abstürzte. Wahnsinnsmeldung ;-) In der Regel kannst du in einer
schönen Schleifen 5000 Threads bauen und den Nutzer verärgern. Wenn du dann
noch in jedem Thread eine Namensauflösung macht, ist auch der
Netzwerkverkehr gestorben. Und wenn du dann noch in jedem Thread ein
AWT-Fenster öffnest ist auch die Benutzerinteraktion gestorben ;-)
Fazit: Thread nehmen. Erst bei vielen Threads (tja, du willst bestimmt eine
Zahl, oder??) wird's langsamer. Muss man Testen, mit dem Rumpf des Threads
wie lange es braucht. Abstürze sind nicht zu erwarten. Normalerweise
existiert von BSY keine Einschränkung der Threads.
Ich möchte gerne ein Char-Array in einen String umwandeln. Leider funktioniert bei mir "String token = valueOf(tokenChar)" nicht, trotz import java.lang.String.
Nimm einfach einen Konstruktor von String. Bitte schau' in die API-Hilfe, denn da steht ein Beispiel in den ersten Zeilen!
Wie kann ich die Länge eines Strings ermitteln und das erste Zeichen dieses Strings löschen?
mit dem length Attribut gibt's die Länge. Da man String Objekte nicht verändern kann, musst du einen neuen anlegen und die Referenz der Variablen zuweisen. Das erste Zeichen ausschneiden kannst du mit substring(1, länge).
Kann mir jemand eine gute Erklärung geben warum ich eine abstrakte Methode nicht static deklarieren kann?
Eine abstrakte Methode ist ja eine Methode, die nicht implementiert ist, also etwa so etwas
abstract class A
{
abstract void m();
}Später wird dann die abstrakte Klasse erweitert und die
Implementierung nachgeliefert. Wenn die Methode m() aber in A keine
Implementierung hat, dann kann Sie auch keine Klassenmethode sein,
da Klassenmethoden (statische Methoden) ja nicht an ein Objekt
gebunden ist, sondern an die Klasse. Wenn
Sie statisch wäre, dann könnte man ja etwa
A.m();
schreiben. Doch was soll hier passieren? Also geht das nicht. Eine ähnliche Begründung gilt für private. Wenn die Methode nicht für andere sichtbar ist, dann kann sich aber auch nicht überschrieben werden, da sie keiner sieht. Auch mit final ist es das gleicht. final heißt ja, keiner darf überschreiben. Aber abstract muss man überschreiben.
Wie kann man in Java einzelne Strings de/komprimieren. So wie man es in einem Zip-File machen kann nur eben ohne Zip.
Nehme ein String und trage es in einen ByteArray[Output|Input]Stream ein. Dann nehme den GZIPOutputStream/..InputStream und komprimiere den String in einen ByteArrayXXXStream. Diesen kannst du dann wieder zu einem Bytefeld konvertieren.
Ich bin für eine größere Applikation auf der Suche nach einer Möglichkeit um das Resultat der Tastenkombination Ctrl-C, das sofortige beenden der VM, zu unterdrücken, da es zwingend notwendig ist, das die Applikation immer über ihren vorgeschriebenen Weg heruntergefahren werden kann.
Dies geht nur mit JNI. In der Newsgroup gab es schon mal eine Anfrage danach. Such' mal bei http://groups.google.com/.
Util
Ich habe vor ein Programm zu schreiben welches das Argument mit dem ich das Programm starte, auf seinen Typ überprüft. (int, String oder Hex) und dann fortfährt. Wie kann ich das am einfachsten bewerkstelligen?
Du kannst zunächst mit Integer.parseInt() drangehen. Wenn der eine NumberFormatException schmeißt, was das nix mit einer Zahl. Wenn das gut ging, hast du die Zahl. Nun lässt sich mit parseInt(String,16) die zahl auf Hex Prüfen. Wieder NumberFormatException testen. Wenn das auch eine Exception gibt, dann war es wohl ein String. Das ist nicht empfehlenswert für viele Test, etwa wenn eine Datei so aufgebaut ist, und da sind Tausende von Zeichenketten drin. Das Exception-Handling kostet recht viel Laufzeit. Du solltest daher besser den String auf die Zeichenbereichte prüfen, dass eine Exception nicht mehr ausgeführt wird.
Gibt es eine Möglichkeit, eine Gruppe von Objekten, etwa Strings, zu sortieren?
Nehme die neuen Collection APIs. Dann muss du den Sortieralgorithmus nicht mehr selber schreiben. Hänge die Objekte etwa in eine Liste hinein und implementiere einen Comparator, damit man die Objekte nach einem Kriterium vergleichen kann. Das Beispiel zeigt einen vorgefertigten Comparator (ohne Java 5 Generics):
import java.util.*;
public class CollectionsReverseSortDemo
{
public static void main( String args[] )
{
List v = new ArrayList();
for ( int i=0; i<10; i++ )
v.add( new Double(Math.random()) );
Comparator comparator = Collections.reverseOrder();
Collections.sort( v, comparator );
System.out.println( v );
}
}
Ich benötige für ein Applet 16 Zufallszahlen. Das habe ich mit Random gelöst und soweit klappt das auch. Dummerweise soll jede Zahl nur einmal vorkommen, was nicht der Fall ist (liegt wohl in der Natur von Zufallszahlen). Wie kann ich das denn lösen?
Du kannst die Collection API nutzen. Erzeuge ein ArrayList der Größe 16. Dann rufe shuffle() auf, welches dir das Feld durchwürfelt. Nun kannst du einen Iterator darüber laufen lassen. Ist dieser am Ende, dann shuffle() einfach neu.
Ich hab folgendes Problem: Das Programm produziert je nach Wunsch des Users mehrere Resultat-Objekte, welche am Schluss noch ausgewertet werden. Wie kann ich eine unbestimmte Zahl der Resultat-Objekte serialisieren, so dass alle in einer Datei landen? Die Objekte sind alle vom gleichen Typ (Klasse mit diversen Datenfeldern). Zusätzlich sollen noch die Ausgangsdaten, welche für alle Resultat-Objekte die gleichen sind mitgespeichert werden. Das Problem ist, wie ich mehrere Objekte (Anzahl unbestimmt), welche vom User dann erzeugt werden, schlussendlich in eine Datei serialisiere.Beispiel:
class ResultatKlasse implements java.io.Serializable {...}
class DatenKlasse implements java.io.Serializable {...}Der Benutzer will mit den Ausgangsdaten (DatenKlasse) mehrere Varianten errechnen (Objekte vom Typ ResultatKlasse). Wie gesagt, die Anzahl ist unbekannt. Wie serialisiere ich dann alle diese Objekte in eine Datei, sodass ich die einzelnen wieder finde?
Man könnte etwa eine Containter-Klasse entwickeln. Diese nimmt dann die Objekte "von beliebiger Anzahl" auf. Intern könnten deine Container-Klasse dann die Objekte in einem Vector speichern und schwupp, dieser lässt sich seriallisieren. Beim Einlesen würdest du dann immer den kompletten Vektor laden und deine Dateistruktur Zugriff auf die entsprechenden Elemente garantieren.
AWT
Wie kann man rausfinden, ob mit der maus auf eine zuvor gezeichnete Linie geklickt wurde?
Das geht mit der Standard-Java-Bibliothek nicht. Da musst du selbst was programmieren; es gibt aber reichlich vorgefertigtes. Unter anderem das sehr leistungsfähige JGraph (http://jgraph.sourceforge.net/). Allerdings muss man sich schon etwas einarbeiten.
Weiß jemand wie es möglich ist von mehreren Linien den Schnittpunkt zu berechnen. Eigentlich geht es darum festzustellen ob sich Linien schneiden. Diese Linien sind durch Koordinaten x und y bestimmt.
Das sind genau genommen zwei Probleme. a) Schneiden sie sich überhaupt
und b) wo schneiden sie sich. Dann kommt noch eine Frage hinzu: Soll
getestet werden, ob sich eine bestimmte Linie mit irgend einer anderen Linie
schneidet, oder soll getestet werden, ob sich irgendeine Linie mit
irgendeiner anderen schneidet.
Ein schnelles Verfahren für die Lösung ist der klassische Sweep-Line-Ansatz.
Eine Anfrage mit Google dürfte schnell ein Ergebnis liefern. Bei ein paar
wenigen Linien reicht ein ein Doofi-Verfahren jeder-mit-jedem mit
intersectsLine(Line2D) aus Line2D.
Wenn ich eine Taste gedrückt halte, sollte alle x Millisekunden ein KeyEvent ausgelöst werden.
Ich denke, dass du Robot und Timer nutzen kannst. Mit der Timer-Klasse kannst du alle x Millis eine Aktion auslösen und mit der Robot-Klasse kannst dein ein Event in die Queue hängen. Aus der API-Doku vom Timer:
int delay = 1000; //milliseconds
ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
//...Perform a task...
}
};
new Timer(delay, taskPerformer).start();Dann Robot.keyPress().
Ich bekomme beim Übersetzen immer eine Fehlermeldung der Art "java.lang.NoSuchMethodError: java/awt/Point: method getX()D not found".
Das liegt daran, das unter 1.2 Point von Point2D erbt und daher auch getX() mit Rückgabe double kommt (in Point sind die Koordinaten vom Typ int). Wenn du unter IE mit einem JDK < 1.2 kompiliert, sucht er natürlich in der Bib nach getX()D, also double getX(), die es da nicht gibt. Daher der Fehler. Abhilfe: Kompilieren unter 1.1, oder nutze einfach p.x anstatt von p.getX().
Gibt es eigentlich keine Möglichkeit mit Java 2D ein einfaches Clipping zu machen, sodass zum Beispiel ein Bild in einer einfachen Sechseck Form dargestellt werden kann?
Setze Clipping mit setClip(). Als Parameter gebe ein Shape Objekt an, etwa ein Polygon (dein Sechseck). Wende setClip() auf den den Graphics an und male dann dein Bild. Restauriere dann den Graphics.
Ich möchte ein Applet programmieren, in dem ich 2 Rechtecke zeichne. Wenn die beiden Rechtecke sich überschneiden, dann soll die Schnittmenge in einer anderen Farbe dargestellt werden. Nun man kann das natürlich mit einzelnen Punkten machen, 24 If Fälle aber... In Java 2 gibt es aber eine Methode die mir diese Schnittmenge berechnet. Wie fange ich die beiden Koordinaten dann auf? Wie kann ich die weiterverarbeiten?
Wenn die Rechtecke nicht gedreht sind, ist das mit der Klasse Rectangle zu lösen. createIntersection(Rectangle2D r) liefert dir ein Rectangle2D Objekt zurück. Mit getWidth, getX, getY kommst du dann an die Werte ran.
Wie fügt man mehrer Bilder zu einem Bild zusammen?
Für Image Objekte gibt es einen Konstruktur, in dem du auch die Größe angeben kannst. Nimm diesen und erzeugt ein das Objekt. Anschließend kannst du dir mittels getGraphics() einen Grafik-Kontext holen und diesen dann Offline zum Platzieren der Bilder nehmen. Neben Image gibt es auch noch BufferedImage. Mit einem PixelGrabber und MemoryImageSource kann man du auch arbeiten, aber das ist ungünstig, da createImage() leider relativ viel Rechenzeit kostet.
Wie kann ich das, was ein Programm zeichnet, in eine PNG speichern?
Um eine Bildschirmanzeige zu speichern, kann man die einfache statische Funktion write() von ImageIO nutzen --- die gibt es erst jedoch seit 1.4. Aber dann kann man ja beim Versuch eine kleine Box anzeigen... Um write() nutzen zu können, braucht man ein RenderedImage (also etwa ein BufferedImage). Wenn man nicht mit Hintergrundgrafiken arbeitet, die vom Typ BufferedImage sind, kann man einen zweiten Weg gehen: Anlegen eines BufferedImages der passenden Größe, besorgen vom Graphics2D und dann zeichnen auf dem Hintergrundbild.
BufferedImage bi= new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics2D g2d = bi.createGraphics();
Nun kann man alles das, was man sonst auf den Bildschirm zeichnet, auf das g2d zeichnen. Um den Programmcode wiederzuverwenden, kann man eine neue Funktion wie drawAll() einführen, die von paint(Graphics g) aufgerufen werden kann, sowie von der Speicherroutine. Dann übergibt man der drawAll()-Funktion einfach das g2d-Objekt. Ist das BufferedImage dann gefüllt, speichert man es etwa mit
ImageIO.write( bi, "png", new File(dateiname) );
Ich will zwei JPEG-bilder (gleicher Größe) lesen, untereinander kleben und als eine JPEG-Datei wieder speichern.
Folgendes sollte klappen (ungetestet)
Image i1 = ... Image i2 = ... // deine beiden Bilder // Bilder jetzt laden (ImageIcon der MediaTracker) Image i3 = createImage( i1.width(), i1.height() + i2.height() ) Graphics g = i3.getGraphics(); g.drawImage( i1, koordinaten ) g.drawImage( i2, koordinaten )
Wie funktioniert der Zeilenumbruch im Label? Folgendes funktioniert leider nicht:
Label l = new Label();<br>
l.setText("Text1" + '\n' + "Text2");<br>
l.setText("Text3 \n Text4");Eine Lösung besteht darin, die TextArea-Klasse zu nehmen. Eine andere Möglichkeit wäre, eine Hilfsfunktion zu bauen, die den Text auseinander nimmt und ihn in zwei Zeilen aufteilt. Aber diese Mühe kann man sich sparen, wenn man in einer Suchmaschine nach MultiLineLabel sucht. Man findet etwa etwas in Java in a Nutshell.
Kann ich bei einer Liste in einem Frame die Farbe des Selektionsbalkens beeinflussen? Also der Balken, der über ein Element gelegt wird, wenn man einmal draufklickt, ich hätte ihn gern grau, weiß aber nicht wie!
Das geht zumindest bei AWT-Komponenten leider nicht. Das liegt
daran, dass die vom BSY gezeichnet werden und da gelten die
Systemeinstellungen. Die Farben des Systems bekommst du übrigens mit Hilfe
der SystemColor Klasse.
Wie kann ich ein *.gif oder *.jpg von ein Klient zum Server kriegen mit RMI?
Entweder ein Icon-Objekt (Swing) draus machen, oder ein Bytefeld (PixelGrabber) und auf der anderen Seite wieder zusammensetzten. Leider bekommt man ja ein Image-Objekt nicht serialisiert.
Ich wäre sehr daran interessiert, wie man einzelne Bildpunkte eines Bildes setzen kann.
Wenn du ein Image Objekt hat dann natürlich mit einer drawPixel()
Methode, die es nicht gibt, dafür aber drawLine(x,y,x,y). Aber vermutlich
willst du das nicht.
Wenn du ein ByteArray der Grüße h*w , dann kannst du mit a[y*w+x] auf alle
Punkte zugreifen. Anschließend konvertierst du das Feld mit createImage und
dem MemoryImageSource. Dann allerdings für eine Animation nicht wieder mit
createImage() sondern mit flush(). Um aus dem Image Objekt wieder ein Feld
zu machen, nehme den PixelGrabber. Wenn du jedoch das Feld behältst braucht
du nur zu flushen. Etwas schneller für Animationen mit setAnimated(true) und
Pixel-Update-Methode.
Ich möchte in einem Applet nur einen Ausschnitt eines Bildes anzeigen. Wie macht man das?
Nutzte den CropImageFilter aus dem java.awt.image Paket. Beispiele für ImageFilter bekommst du auf vielen Internetseiten.
Gibt es die Möglichkeit ein Serializable Image zu implementieren, so
das man es z. B. mittels RMI versenden könnte?
Oder gibt es da irgendeinen anderen komfortablen Weg der Bilderübertragung
vom Server zum Client?
Image ist nicht serializable, da ein Producer/Konsumer Konzept dahinter steckt. Nimm ein Icon, wenn du die Möglichkeit hast, Java 1.2 zu verwenden. Andernfalls konvertiere das Image in ein Pixel Array (PixelGrabber) und baue es auf der anderen Seite wieder mit einem MemoryImage wieder zusammen.
Für unser Reporting möchten wir aus Java heraus Text in ein Word-Dokument einfügen. Wie macht man das?
Dies geht zwar, aber mit Umwegen, die nicht immer einfach sind. Das liegt auch daran, das M$ viel Geld für die Spezifikation haben will und sie daher in so schönen Büchern wie "Dateiformate", "Noch mehr Dateiformate", ... nicht beschrieben ist. Es bieten sich drei Lösungen an
- Die Ursprungs-Dokumente werden nicht im binären Format gespeichert, sondern als RTF, was ASCII ist. Den kann Word schreiben, lesen und anzeigen. Man legt etwa einen Platzhalter wie #1, #2 im Text an, speichert den Text aus liest aus Java die Datei in einem String ein und ersetzt mit replace("#1", bla) einfach die Platzhalter mit dem Text; dann speichert man in Java das alles wieder zurück.
- Die neuen Office-Versionen können den Text im XML-Format speichern (hier gibt sogar gleich mehrere Formate) . Das kann man dann so nutzen wie RTF.
- Office lässt sich über COM fernsteuern, wenn auf dem Rechner Word installiert ist. Eine COM-Brücke ist etwas com4j.
- OpenOffice kann Word öffnen. Die UNO-Schnittstelle erlaubt dann Zugriff.
Ich habe eine JFrame und öffne einen modalen JDialog. Das JFrame
übergebe ich als owner an den JDialog(der Dialog ist nur eine kleine Box man
sieht auf jeden Fall das JFrame im Hintergrund). Wenn ich jetzt nach dem
Start der Applikation noch weitere Anwendungen im Hintergrund geöffnet habe
und ich mit ALT+TAB z.B. in eine Excel-Anwendung wechsel und dann wieder zu
meiner Java-Anwendung zurückwechseln will- dann erscheint zunächst nur der
JDialog und erst beim Schließen
des Dialogs erscheint das JFrame auf dem Bildschirm. Wie kann Ich das JFrame
und den Dialog verknüpfen, dass beide auf dem Bildschirm erscheinen (nach
ALT+TAB Aktionen)?
Versuche, beim Dialog einen Listener zu setzen. Wenn der Dialog wieder sichtbar wird (WindowListener, windowDeiconified(), vielleicht auch windowActivated()) kann er dann vom Frame die toFront()-Methode (von Window geerbt) aufzurufen.
Wie kann man in einer TextArea einen Text suchen und ihn dann markieren oder Ersetzen ?
Du solltest den Text mit textfield.getText() in ein String kopieren. Dann sucht du innerhalb des String, etwa mit indexOf(Suchstring). Mit der Position und der Länge des Suchwortes werden mit substring() zwei weitere Teilstrings erzeugt. Der erste vor dem Suchwort und der zweite danach. Anschließend schreibt man die ersten Teil mit dem neuen Teil und mit dem abschließenden letzen Teil in einen neuen String und weist ihn mittels setText() dem Textfeld zu.
Ich bin auf der suche nach einem Archiv mit möglichst vielen DUKE-gifs. Ich habe schon mal bei Sun rumgestöbert aber leider nix gefunden.
Bei der http://www.java.com/en/dukeszone/ gibt's Infos über den Duke. Das Copyright ist gelockert, sodass man Duke-Logo heutzutage einfacher nutzen kann. Allgemeine Lizenzbestimmungen, ob man etwa das Wort Java in seiner URL nutzen darf, stehen hier: http://www.sun.com/policies/trademarks/.
Wie kann man in einer TextArea einen Text suchen und ihn dann markieren oder Ersetzen ?
Du solltest den Text mit textfield.getText() in ein String kopieren. Dann sucht du innerhalb des String, etwa mit indexOf(Suchstring). Mit der Position und der Länge des Suchwortes werden mit substring() zwei weitere Teilstrings erzeugt. Der erste vor dem Suchwort und der zweite danach. Anschließend schreibt man die ersten Teil mit dem neuen Teil und mit dem abschließenden letzen Teil in einen neuen String und weist ihn mittels setText() dem Textfeld zu.
public void replace( TextArea t, String search, String replace )
{
String s = t.getText();
int pos = s.indexOf( search );
// System.out.println( s + " " + pos );
if ( pos >= 0 )
{
s = s.substring(0,pos) + replace + s.substring(pos+search.length(), s.length() );
t.setText( s );
}
}Hat man unter Java irgendwie die Möglichkeit zu erfahren an welcher Position sich der Schieberegler befindet. Für meinen Zweck würde es sogar reichen wen ich wüsste ob sich der Scrollbalken am Anfang oder am Ende der TextArea sich befindet.
Mit den Standardklassen sieht es schlecht aus. Weder TextArea noch das Peer Objekt verwalten Scrollbars. Das übernimmt die GUI für sich. Doch du kannst eine andere Lösung wählen, die macht es allerdings davon abhängig, wo der Cursor steht. Und der Scroller wird ja immer mitbewegt. Wenn es dir reicht, dass der Benutzer den Scroller duch den Cursor nach unten bewegt hat, dann kann ich dir dazu etwas schicken. Das Problem ist hier nur, dass ja der Benutzer den Scroller ohne Cursorbewegung nach unten stellen kann. Das bekommt man nicht mit.
Ich erzeuge einen Ressourcenfresser durch häufiges Aufrufen (40 bis 2000 mal kurz hintereinander) von createImage() für eine Bildanimation. Trotz flush() und des Aufrufes des Garbage-Collector System.gc() nach der Animation werden die Ressourcen nicht freigeben. Wer hat Ideen, die mit createImage() erzeugten Ressourcen wieder freizugeben?
Mal g.dispose() benutzen, da das AWT unter dem GC liegt.
Ich muss als ToolTip Text ziemlich viel darstellen und würde das gerne mit Zeilenumbruch (\n) machen.
Das geht durch HTMT-Tags, also <HTML>Erste Zeile<BR>Zweite</HTML>
Gibt es einen Befehl, mit dem man die Maus festhalten kann, d.h. das wenn der Benutzer auf einem Feld die linke Maustaste drückt, und dann per Mausbewegung ein Menu bewegt, den Mauscursor selbst aber nicht?
Jein, aus Sicht der Benutzerführung ist dies sicherlich nicht gut und du solltest es vermeiden. Bei BSS gilt immer noch: Es machen alle so, also mache ich das auch so. Nichts sind nerviger als Oberflächen mit AHA-Erlebnissen. Insbesondere gibt es für Swing Oberflächen ein wunderschönes Styleguide (als Buch und im Internet), was ich sehr empfehlen kann.
Ich stecke im Moment ziemlich fest, da ich ein Image drehen muss und überhaupt nicht weiß, wie ich das angehen soll?
Im Java Tutorial von Sun gibt's ein ein Beispiel, wo ein Rotationsfilter entwickelt wird. Da es das Buch auf den Sun Seiten gibt, würde ich da mal reinschauen.
Wie kann ich den Wordwrap bei einer Textbox ausschalten?
Ohne horizontalen Schieberegler wird Zeitenumbruch automatisch eingeleitet. TextArea.SCROLLBARS_NONE oder TextArea.SCROLLBARS_VERTICAL_ONLY einschalten. Standardmäßig wird die TextArea mit horizontalem und and vertikalem Schieberegler ausgestattet. Setze dies im Konstruktor oder später mit der set() Methode.
Swing
Ich möchte den Inhalt einer JTable drucken. Was für einfache Möglichkeiten gibt es. Es muss nicht Pixelgenau stimmen!
Wenn du nicht das Standard-Drucken einer JComponent nutzten möchtest, dann entsteht ein anderes Problem. Das Model enthält zwar alle Daten, aber erst die Renderer stellen den Inhalt benutzerdefiniert dar. Das heißt, wenn Renderer im Spiel sind, reicht das Model nicht aus.
Eine schöne Lösung sind natürlich die Report-Generatoren, von denen es einige freie gibt, auch als Eclipse-Plugin. Such doch mal zum Beispiel nach Jasper Reports. iReport ist da ein Gui-Tool.
Falls es einen Ausdruck geben soll, bevorzuge ich gerne PDF. Leicht zu erstellen mit einer Bibliothek wie iText, die auch HTML rendert. Lege die Tabelle einfach in HTML und übergebe sie iText. Eine Funktion, die ein TabellenModel in HTML ausgibt war mal eine Java-Aufgabe.
public String saveTableToHtmlString( TableModel model )
{
Writer sw = new StringWriter();
PrintWriter ps = new PrintWriter(sw);
ps.println("<table>");
for (int i = 0; i < model.getRowCount(); i++)
{
ps.println("<tr>");
for (int j = 0; j < model.getColumnCount(); j++)
{
Object o = model.getValueAt(i, j);
ps.println("<td>");
ps.println(o == null ? "" : o);
ps.println("</td>");
}
ps.println("</tr>");
}
ps.println("</table>");
ps.close();
return sw.toString();
}Applets
Wenn ich in meiner Seite ein Applet benutze, wird dazugehörige Class-Datei auf dem Client (wer meine Seite aufruft) heruntergeladen. Dann kann jeder diese Class-Datei doch benutzen, oder ist es nicht so?
Ja. Der einzige Weg das erst einmal zu umgehen ist, sich die Adresse des Servers zu holen und zu vergleichen, ob das deiner ist. Das ist dann im Applet verdrahtet.
Net
Wie kann man RMI dazu bewegen, eine komprimierte Verbindung zu nutzen (z.B. via GZIPOutputStream, GZIPInputStream)?
Das Problem bei der Kompression macht oft das Flush. Daher würde ich eine einfachere Lösung vorschlagen, die funktioniert, wenn von den übermittelten Daten nur ein Teil wirklich komprimiert werden muss. Denn statt einer Kompression des gesamten RMI-Datenstroms kannst du die Objekzustände komprimieren, die sehr groß sind. Dazu schreibe eigene readObject()/writeObject()-Methoden um die Standard-Serialisierung "abzuschalten". Zum Schreiben etwa
private void writeObject( ObjectOutputStream out ) throws IOException
{
GZIPOutputStream gz = new GZIPOutputStream( out );
ObjectOutputStream oo = new ObjectOutputStream( gz );
oo.writeObject( data );
oo.flush();
gz.finish();
}Wichtig ist das finish(). Das Objekt wird jetzt das große Datum data komprimiert in den ObjectOutputStream schreiben. readObject() ist unkompliziert.
Ist es möglich, das Name-Caching der Klasse java.inet.InetAddress für einen bestimmten Lookup abzuschalten? Im konkreten Fall geht es um eine dyndns-Adresse, die nicht gecacht werden soll. Das globalNamenscaching soll nicht abgeschaltet werden.
Unter http://www.dnsjava.org/ gibt es eine pure Java-Implementierung, mit der man den Cache ganz präzise steuern.
Ich habe eine Frage zu RMI. Kann mir jemand die Notwendigkeit
des ClassLoaders erklären?
Der Klassenlader ist nötig, damit dem Server oder Client unbekannte Klassen
über das Netzwerk übertragen werden können. So macht es auch der
Applet-Klassenlader. Ein Beispiel: Der Server bietet eine remote-Methode
f():
class A
{
void f( Date ) { ... }
}
Jetzt der Client. Er steckt eine Unterklasse von Date (etwa SuperDate) rein, die nur auf der Client-Seite existiert. Dennoch muss dem Server die Klasse bekannt sein. Daher schickt der Client die Klasse SuperDate an den Server. Damit der Server die Klasse laden und initialisieren, benötigt er einen Klassenlader. Aber wie das Beispiel zeigt, braucht man den nur, wenn einige Klassen übertragen werden, die den Partnern nicht bekannt sind.
Ich habe ein gegrabtes Bild von einer Webcam per Pixelgrabber in ein int[] gewandelt, um das über eine Multicast-Verbindung zu verschicken. Dummerweise ist das Bild (wie Bilder nun mal eben sind) nicht gerade klein und der Buffer von DatagramPacket läuft über, was zur Folge hat, das das Bild als int[] nicht verschickt bzw. empfangen wird.
Ein Datagramm kann leider nur 64k minus Verwaltungsinformationen groß sein. Das ist gerade die Eigenschaft von TCP, dass es große Pakete zerstückelt und wieder zusammenfügt. UDP macht das nicht, und es ist erhöhter Aufwand, wenn man das selber macht. Daher es es wohl einfacher, gleich eine Socket-Verbindung zu nutzen. (Bei UDP könnten auch Daten fehlen, oder falsch übertragen werden.) Das Bild in 64k reinzubekommen wird sicherlich schwierig. Sonst könntest du mit einem JPeg-Encoder das Bild im Speicher komprimieren und dann wegschicken.
Es gibt doch irgendeine Möglichkeit einem Objekt, das von mir serialisiert wurde eine eigene Signatur zu geben. Weiß jemand wie und wo das geht?
Meinst du eine digitale Signatur um die Unveränderlichkeit festzustellen? Dann berechne vorher von dem Datenstrom eine MD5 oder SHA1. Wie das geht, erfährst du unten im Tutorial. Einfach ist, wenn du den Strom vorher in ein Byte-Feld lenkst. Dann lässt sich die Signatur berechnen und du kannst gleichzeitig das Bytefeld in ein ObjectOutputStream schreiben.
Wie schreibe ich in Java ein solches ICMP-Ping, bzw. Implementiere ich ICPM unter Java? Wo im Internet finde ich solche Implementierungen?
http://www.geocities.com/SiliconValley/Bit/5716/ping/
Mein Problem ist momentan eine funktionierende FTP-Client-Klasse...kennt da jemand eine?
Eine einfache Klasse mit Bsp. findest du bei Apache.
Ich möchte die Klasse MulticastSocket erweitern und bekomme die Fehlermeldung, dass der Konstruktor der Superklasse eine Exception wirft und das deshalb der Konstruktor dieser Klasse explizit definiert werden muss. Mit wenig Java Programmiererfahrung habe ich allerdings keine Ahnung wie man so was macht. Hast Du eine Idee?
Du hast die Frage doch eigentlich schon selbst beantwortet.
import java.net.*;
import java.io.*;
class MyMulticastSocket extends MulticastSocket {
MyMulticastSocket() throws IOException { }
}Wenn du einen eigenen Konstriktor baust, der IOException erweitert ist das schon alles. Ein Konstruktor ruft automatisch den Konstruktor der Oberklasse auf. Dies ist auch der Grund, warum du den Konstruktor neu implementieren musst. Denn würdest du keinen Konstruktor angeben, gäbe es automatisch einen Standard-Konstruktor. Dieser würde dann, wie oben beschrieben, den Konstruktor der Oberklasse aufrufen. Da der Programmcode des Konstruktors der Oberklasse jedoch eine IOException auslösen kann, würde die eigene Klasse (mit dem Standard-Konstruktor) ja diese IOException nicht auffangen.
JSP/Servlets
Warum sollte man z.B. mit JSP programmiert und nicht mit PHP oder ASP? Was sind ihre besondere Vorteile?
Andere Technologien sind nicht schlechter; auch PHP und ASP sind gute Lösungen. Wenn denn allerdings die Geschäftslogik in Java implementiert ist, sind Web-Frameworks in Java eine gute Lösung. Dann aber auch nicht pure JSPs, sondern JavaServer Faces (bzw. Facelets) oder andere MVC-Implementierungen. Ein Unternehmen würde nicht etwa die Technologie wechseln, wenn man sowieso schon alles in Java entwickelt. Wenn man aber in C# programmiert, würde man ebenfalls in der .NET Familie bleiben und kein Java einsetzen.
Ich habe mir Jakarta Tomcat 4.0.2 installiert. Wird ein Servlet einmal ausgeführt, bleibt es jedoch im Cache des Servers. Das ist beim Entwickeln einer Anwendung sehr unpraktisch; wenn ich in der Javaklasse eine Änderung machen möchte, muss ich den Tomcat neu starten.
Bei JSP/Servlet-Klassen werden neue Class-Versionen erkannt und eingebunden. Entwickelst du Beans, und die sind vom Klassenlader erfasst, wüsste ich auch keine Möglichkeit, wie man die automatisch wieder losbekommt. Da muss man Tomcat tatsächlich neu starten.
IO
Ich habe eine HTML-Datei, und dich muss ich parsen. Nimmt mir dabei jemand die Arbeit ab?
Ja. Einmal gibt es im Paket unter javax.swing.text.html.parser einen Parser. Ein Beispiel findet sich unter http://java.sun.com/products/jfc/tsc/articles/bookmarks/. Des weiteren lässt sich der sehr performate HTML-Parser unter http://htmlparser.sourceforge.net/ nutzen. Mit http://jtidy.sourceforge.net/ du bekommst einen DOM-Baum aus einem HTML-Dokument.
Can somebody give me a script which extracts numbers from a string, ex. from the string "u17mnh.6fgji90f", it returns 17, 6 and 90.
You may use a StreamTokenizer. Use nextToken() an you will get a
TT_NUMBER.
Ich möchte einen Strom, der über einen Puffer auf ein Socket ausgegeben wird, AUCH auf die Konsole ausgeben. Wie kann ich diesen Strom eben in zwei Puffer umleiten oder aus dem Puffer lesen ohne die Daten aus Diesem damit zu entfernen.
So etwas wie ein tee unter Unix gibt es in den Bibliotheken nicht. Aber
das Umgekehrte: SequenceOutputStream. Wenn du dazu den Quellcode nimmst,
könntest du dir damit deinen eigenen Doppel-Dreifach-xxfach-Ausgabe-Strom
bauen.
Wie kann ich etwas nicht am Bildschirm anzeigen lassen, sondern einfach eine Textdatei erstellen, die mir alles speichert, was mir die Prozedur normal auf dem Bildschirm ausgibt?
Leite einfach den Ausgabestrom in eine Datei. Zum Umleiten gibt es
setOut() in der Systemklasse. Du musst einen Datenstrom übergeben. Dafür
öffne einfach die Datei.
Ich will nur die letzten 20 Zeilen aus einer Datei in ein TextArea einfügen. Bis jetzt zeigt er mir die ganze Datei an.
Du könntest einen RandomAccessFile bauen und dann einfach mal das letzte
Kilobyte lesen (Dateilänge mit length() holen und mit seek(filelen-1024)
setzen (filelen>1024). Von hinten zählst du dann die Returns. Bist du bei
der nullten Stelle, hast aber noch keine 20 Returns gezählt kannst du einen
neuen Block einlesen und weiterzählen oder einfach einen größeren Block
einlesen und mit dem Zählen von vorne beginnen.
Andere Lösung (dann musst du dich nicht um das Endezeichen kümmern): Mit
seek() die Position setzen und dann readLine() bis zum Ende aufrufen. Die
Zeichenketten in einer Queue der Länge 20 speichern. (Oder halt den Vector,
dann eventuell viel Speicherverbrauch.) Wenn's wieder zu wenig wäre seek()
davor und dann noch mal durchlaufen. 1024 könnten ja eigentlich reichen. Die
Zeilen dürfen dann durchschnittlich 1024/20 = 51 Zeichen lang sein. Wenn man
die Daten kennt, kann man das ja leicht abschätzten.
Can anyone help me with getting th elengt of a file? The method
File.length() returns the length in bytes, but I need to know how many lines
the file has. (i know that this may be system dependant)
Is there any other solution than scanning through the file and counting the
lines myself??? - There must be a better way..
There is no other way. But it is simple with the LineNumberInputStream (or LineNumberReader) class. Go through the file with
LineNumberInputStream lsis = new LineNumberInputStream( new FileInputStream( file ) ); while ( ( c = lsis.read())!= -1 ) ; System.out.print( lsis.getLineNumber() );
Wie kann ich einen LineNumberReader zurücksetzen in die erste Zeile? Andauerndes Öffnen und Schließen ist ja nicht so das Wahre. Und gibt es zur Bestimmung der Zeilenanzahl einer Datei eine schnelle und elegante Lösung?
Den LineNumberReader kannst du einfach mit setLineNumber(int lineNumber) zurücksetzen. Leider kann man den LNR nicht auf einen neuen Reader setzen. Du kannst aber mittels des SequenceInputStream mehrere Streams (ja, das sind noch keine Reader ;-( ) zusammenschließen und dann mit LineNumberInputStream arbeiten.
Um die Anzahl der Zeilen in einer Datei zu lesen müsstest du direkt die Daten öffnen und anschließend in einen Puffer schreiben (Größe am besten nach der Puffergröße des BS). Dann kannst du die Bytes schnell durchsuchen (wenn es kein Unicode ist). Das wäre am schnellsten. readLine() und indexOf() oder ähnliche Lösungen sind viel zu langsam und selbst Sun hat eigene Klasse dafür gestrickt.
Kennt jemand eine einfache Möglichkeit in Java Dateien zu kürzen?
Du kannst eine Datei kürzen, indem du von RandomAccessFile die setLength() Methode nutzt. Leider kann man vorne keine Blöcke ausschneiden (und das möchte man ja eigentlich).
Ich möchte ein bestimmtes Verzeichnis nach einem bestimmten Dateityp durchsuchen und diese dann in eine Liste (bzw. Array / Vector) speichern. Gemeint ist eine Suchfunktion wie z.B. in Windows die dann eine Liste der Dateien erzeugt, ganz simpel...
Dies kann man durch einen FilenameFilter machen.
String a[] = entries.list( new FilenameFilter() {
public boolean accept( File d, String name ) {
return d.isDir();
} } );
Im Java 2 gibt es eine Methode listRoots() (in der Klasse File). Diese Methode listet alle Verzeichnis-Wurzeln vom aktuellen System. Unter UNIX einfach '/' und Windows die Wurzeln der Laufwerkbuchstaben. Gibt es eine solche Methode auch vor JDK 1.2?
Vor 1.2 gab es keine solche Funktion. Schau dir aber mal das Paket jconfig an, das dürfte so etwas haben. Änderfalls kann man aus den System Properties das OS herausbekommen und dann z.B. unter Windows mit File.exists( Laufwerk ) einmal die Laufwerke durchgeben. Das funktioniert leider nicht bei allen Laufwerken, so etwa liefert File.exists ("a:\" ) false, wenn keine Diskette drin' liegt.
XML
Ich möchte gerne mit JDOM ein XML-Dokument ohne Attribute ausgeben. Gibt es eine Möglichkeit, das mit dem Outputter einfach zu realisieren?
Baue eine Unterklasse von XMLOutputter. Dann kann man schön das Template-Pattern in Anwendung sehen, in dem man die Methode printAttributes() leer lässt:
protected void printAttributes( Writer out, List attributes,
Element parent, NamespaceStack namespaces)
throws IOException { }
Anstatt dann den XMLOutputter einfach die eigene Klasse nehmen.
Der SAX Parser parst doch sequentiell immer die folgende Reihenfolge 1. startDocument(), 2. startElement(), 3. characters(), 4. endElement(), 5. endDocument(), oder?
Durch Character-Chunking kann characters() auch öfters hintereinander aufgerufen werden. Siehe dazu www.tutego.com/blog/javainsel/2007/01/character-chunking-bei-sax.html. So etwas wie processingInstruction() kann natürlich auch noch kommen.
JDBC
Ich würde gerne aus einer MySQL-Datenbank jeweils eine Zeile auslesen, manche Spalten davon bearbeiten und letztendlich alles wieder in eine andere Datenbank schreiben. Im Moment sieht's ungefähr so aus: a) Verbindung zur Datenbank, b) ResultSet holen, c) Zeilöe verarbeiten und was machen. Jetzt hab ich aber beim Einlesen schon ein Problem. Ich bekomme bei dem ResultSet (mit "SELECT * FROM DB") einen Speicherüberlauf. Die Datenbank besteht aus mehreren 100.000 Zeilen und ich weiß leider nicht, wie ich das sonst lösen sollte. Kann man zum Beispiel das ResultSet begrenzen? Also beispielsweise immer wieder 1000 Zeilen lesen oder so? Oder gibt's noch eine elegantere Lösung?
MySQL kennt leider kein echtes Cursor-Konzept, sodass der JDBC-Treiber alle Daten auf die Client-Seite überträgt. Mit dieser Technik muss die Datenbank nicht gelockt werden und muss keine Transaktionen unterstützten. Das löst auf einfache Weise ein Problem wie: Der Abholer braucht 10 Stunden für das Lesen, die Tabelle wird aber beschrieben. Kopiert man alles, muss die Datenbank nur für die Übertragung gelockt werden. Schöne Optimierung-Parameter wie fetch-size oder so sind da völlig wertlos. Hier helfen
Statement stmt = con.createStatement( ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE ); // SENSITIVE ode INSENSITIVE gut überlegen ResultSet uprs = stmt.executeQuery( "SELECT Bla FROM Blub" ); // Auf die passende Zeile steuern, dann etwa uprs.updateFloat( "Groesse", 183f ); uprs.updateRow();
Mein Clients hat keinen Zugriff auf die Datenbank, sondern erledigen das alles über einen Server, der für die speziellen Aufgaben ensprechende Methoden über RMI anbietet und dahinter die DB spezifischen Statements ausführt. Was mache ich mit Rückgabewerten? ResultsSets gehen ja bekanntlich nicht über RMI, da sie nicht serialisiert werden können.
Zumindest Programmieraufwand kannst du dir sparen, in dem du einen Blick auf http://rmijdbc.objectweb.org/documentation.html wirfst. Da jedoch jeder kleine Aufruf über RMI geht, ist die Performance nicht toll. Zudem ist http://java.sun.com/j2se/1.4.2/docs/api/javax/sql/RowSet.html einen Blick wert, bzw. CachedRowSet. Der CachedRowSet ist eine serialisierbare Bean, die sich wie ein serialisierter ResultSet verhält. Eine Alternative zu Sun ist von Apache und heißt org.apache.commons.beanutils.ResultSetDynaClass bzw. RowSetDynaClass. Sie sind Teil vom common Paket BeanUtils.
Mich würde interessieren, ob es eine komfortablere Lösung für das Kopieren von int-Werten aus einem ResultSet in ein int-Array gibt, als sie erst ein ein Vector zu packen und dann wieder auszupacken.
Wenn du den Vector gleich mit der richtigen Größe anlegst, dann muss er sich ja nicht resizen. Also kannst du vorher ein Select COUNT(*) machen, um die Anzahl auszulesen. Dann ist der Vector groß genug. Sollte man auch machen, da der Vector ein Verdopplungsstrategie fährt, und die kostet bei vielen Daten auch viel Speicher.
Mit der festen Größe kannst du aber auch gleich das Array anlegen. (Hier war wohl das Problem, warum du den Umweg über den Vector nahmst ;-) Sonst konstruiert das Programm ja wirklich viele Objekte. Integer rein, dann als Zahl wieder raus ins Array...
Für Umlaute bekomme ich eine Fragezeichen wie hier :
Assistentin/Sekret?rin der Gesch?ftsleitung
Ich habe einen Servlet und versuche die Datensätze in eine HTML Seite darzustellen. Meine Datenbank ist Informix. Ich hab jetzt von Kollegen gehört, dass ich einen Parser schreiben muss. Gibt es eventuell schon eine Parser-Funktion für das Problem?
Einen Parser brauchst du natürlich nicht. Es gibt jetzt verschiedene Möglichleiten für dein Problem. Es kann sein, dass Unicode in deine DB reinkommt, aber nicht mehr raus. Dann kannst du mit einem Konverter deinen Datenstrom umbauen, sodass er einer anderen Codepage gehorcht. Gib doch mal den ASCII-Code deines Zeichens raus. Dann weißt du, ob alles das gleiche Zeichen ergibt, oder nicht. Vergleiche doch mal mit dem "echten" Umlaut. Eventuell mache eine Umsetzung über eine einfache case-Anweisung, in dem du über den String läufst. (Doch der Parser :-)
Bei anderen Datenbanken, funktioniert es auch, die Kodierung ausdrücklich zu setzen, um damit eine Konvertierung vorzuschreiben. Man muss allerdings die Texte dann als Bytestrom holen. Die String-Konvertierung bei getString() intern würde sonst die Sonderzeichen wieder vernichten, sodass man sie anschließend nicht wieder hinbekommt.
new String( read_rs.getBytes(1),"ISO-8859-1" )
Wenn alles in Java implementiert wird, also wenn auch die Daten über Java reinkommen, kannst du eine eigene einfache Kodierung nutzen, die 7-Bit ASCII nimmt. Dazu nutze URLEncoder.encode() und URLDecoder.decode().
Java ME
Ein MIDlet lädt eine WML-Seite herunter und verarbeitet sie weiter. Leider dauert das Öffnen der HTTP-Verbindung und Empfangen der Daten viel zu lange. Wenn ich den telefoneigenen Browser nehme um die Seite zu öffnen wird nur etwa ein Drittel der Zeit für das Herunterladen und Interpretieren der Seite benötigt. Ich würde gerne einen gepufferten Inputstream verwenden, nur leider scheint es den im MIDP nicht zu geben... Wie kann man den Datentransfer mittels HTTP beschleunigen kann?
Zwei Optimierungen sind sinnvoll und lohnenswert:
- Verbindungen offen halten (falls es das Bezahl-Modell zulässt).
- Einen Proxy verwenden.
Im Allgemeinen wird man einen Proxy (Server) einrichten, zu dem die Verbindung offen bleibt. Das mobl. EG wird dann über den Proxy gehen und der geht ins Internet und holt die Daten. So braucht man nur eine Verbindung zum Server und nicht viele kleine. Das schöne ist, dass man später über diese "Middleware" auch komprimieren oder cachen kann. Für WML-Dateien gibt es WBXML und die Java-Impl. für mobl. EG unter http://kxml.enhydra.org/index.html.
Der Trick ist ja gerade der, dass man nur eine Zentrale hat, über die man kommuniziert. Wenn man eine Datei laden möchte, schickt man einen Request an die Zentrale (Proxy) mit der URL, die man möchte --- im Idealfall baut man die Verbindung nicht ab. So muss sich das mob. EG nicht um viele verschiedene Host-Aufbauen kümmern, sondern das ist dann Sache des Proxies.
Man verwendet nicht in dem Sinne die HttpConnection weiter, als dass man
dort sich wirklich zu verschiedenen Servern connected. Das funktioniert nur
über ein eigenes Server-Protokoll! HttpConnection bringt auch nichts, es sei
denn, wir nutztes so etwas wie Keep-Alive, denn über HttpConnection kann ich
nur das etwas anfragen und dann wieder holen, wieder anfragen und holten,
wenn Keep-Alive gesetzt ist.
Aber das möchte ich nicht nutzen und diese
Quelle empfiehlt das auch nicht. So habe ich mir das gedacht (MIDP 2.0
JSP 118, muss sonst nicht funktionieren.)
SocketConnection conn = (SocketConnection)Connector.open( "socket://server:port" );
// con.setSocketOption(DELAY, x); überlegen, ob die zu setzen
sind
// con.setSocketOption(KEEPALIVE, y);
InputStream is = conn.openInputStream();
OutputStream os = conn.openOutputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
// das für jede URL machen
{
// Request weg.
String s = "Neuer Server";
os.write( s.getBytes() );
// Antwort holten
// Server schickt erst die Länge (3 Bytes) , dann so viel Daten.
int len = (is.read() << 16) + (is.read() << 8) + (is.read() << 0));
baos.reset();
for ( len Bytes lesen , (ch = is.read() )
baos.write( ch );
byte b[] = baos.toByteArray();
// Hier jetzt wbxml oder sonst weiterverarbeiten.
// Bereit für den nächsten RequestExterne Bibliotheken
Ich möchte mein Programm als Bildschirmschoner laufen lassen. Ich habe sie in eine *.exe umgewandelt und in eine *.scr umbenannt. Wenn ich das Programm nun als Bildschirmschoner einstelle, wird es auch geladen, jedoch immer und immer wieder. Win98 ist sozusagen nicht klar, dass es schon als Bildschirmschoner aktiv geworden ist. Auch weiß ich nicht, wie ich in meinem Programm eine Schnittstelle zu den Win98 Eintrag Eigenschaften unter der Rubrik Bildschirmschoner herstellen kann. Um es kurz zu machen, ich weiß nicht wie ich das Betriebssystem in mein Programm integrieren kann.
Bei den Bildschirmschonern kann man zwar ein .scr in ein .exe gültig umwanden, aber nicht umgekehrt. Dazu fehlt in der .exe die nötigen Informationen über Einstellmöglichkeiten usw. Erstell einfach mit VB oder sonst was ein Wrapper, der dann die Java-EXE aufruft.
Gibt es irgendwo eine Java-Klasse, mit der man MS Word Dokumente und deren Eigenschaften anzeigen kann?
Es gibt von einer Firma (die ich dummerweise vergessen habe :-( ) eine Klasse zur Konvertierung. Wenn man jedoch mit Office 2000 arbeitet, da kann man leicht einen XML Parser anwenden. Oder wenn die Dinger in RTF sind, geht es auch einfach. Sonst schau mal im Internet, da gibt es eine Implementierung für einen Doc to RTF. Wenn du den Quelltext nimmst, lässt sich bestimmt herausfinden, wo die Eigenschaften liegen.
Weiß jemand,wo die Sourcecode von Class sun.tools.java.Scanner steht. Also die Datei Scanner.java?
Entweder man macht sich bei Sun beliebt und erwirbt die Souce-Code Lizenzen oder man Decompiliert die Klasse in der Jar Datei tools.jar (etwa mit jad). Wenn du an der Uni München bist, hat die vermutlich die Source-Lizenz. Musst mal fragen...
Gibt es eine Möglichkeit Word und Access unter Java anzusprechen?
Also man kann mit Python Word versteuern. Da ist auch ein Demo bei den Win32 Libs dabei. Da es auch JPython gibt, könnte ich mir vorstellen, dass das so klappen könnte.
Enterprise Java
Warum bekomme ich bei Hibernate mit session.load(clazz, x) bei Sammlungen ein PersistentSet und kein normales Set?
Der Grund ist einfach: Hibernate verwaltet eine eigenes Set, um Lazy-Loading zu ermöglichen. Ist Lazy-Loading bei 1:n:-Assoziationen eingestellt (Standard), dann wird die Sammlung erst dann geladen, wenn es einen Zugriff auf die Sammlung gibt (Anfragen, add(), ...). Der Punkt ist nun: Wie sollte ein Persistence-Provider mitbekommen, dass jmd. nun Daten aus der Sammlung lesen will? Daher fängt das PersistentSet (http://www.hibernate.org/hib_docs/v3/api/org/hibernate/collection/PersistentSet.html) von Hibernate als Proxy die Anfragen ab (PersistentSet ist ein waschechtes java.util.Set) und kann so vor dem tatsächlichen Zugriff auf die Sammlung die Daten schnell laden.
Übrigens hat man in der JPA auch nur die Basis-Collection-Schnittstellen wie Set, List, ... aber keine konkreten Klassen wie HashSet, TreeSet,... Die PersistentSet-Doku schreibt aber: "The underlying collection is a HashSet."
Ich habe eine sehr große DB (Microsoft SQL Server) mit vielen Tabellen und Einträgen. Ich möchte eigentlich Hibernate einsetzen, ist eine grosse schon vorhandene DB da ein Problem? Die DB hat wirklich viele Tabellen und Einträge, meinst Du mit normalen SQL das wäre da besser?
Das einfachste ist, mit dem Hibernate-Tools (http://www.hibernate.org/255.html) aus den Relationen automatisch Beans zu generieren. In den aktuellen Versionen erzeugen die Tools auch ganz ordentlich EJB Entity Beans mit den passenden Annotationen für Spaltentyp, Assoziationen, usw. Das generierte Bean-Geflecht sollte man im nächsten Schritt überarbeiten und so anpassen, dass es so ist, wie man sich es wirklich vorstellt; konkretisieren von Lazy-Fetch, usw. Eigentlich sollte man das Objekt-Modell ja getrennt vom DB-Modell aufbauen, um ein schönes, tolles, DB-Modell zu erhalten. In einem Kundenprojekt habe ich das auch getan. Die Konsequenz ist viel Arbeit beide zusammen zu bringen, denn beides sah total anders aus. Man muss sich bei der Generierung also überlegen, wie viel Wert einem ein vielleicht weniger optimales Design ist. Auf der anderen Seite kann man sehr elegant die Schicht DB -> Hibernate -> generierte Beans nehmen und die Beans als Service sehen, die dann mit einer anderen Schnittstelle vom Client genutzt werden. Mit der Performance sehe ich überhaupt kein Problem. Es kommt eher auf die HQL-Ausdrücke bzw. EQB-QL (welcher Join?) als auf die Zwischenschicht des OR-Mappers selbst an. Hibernate nutzt ein ordentliches Caching und wenn man will, kann man immer noch mit nativem SQL arbeiten. Auch wenn es um EJB-QL versus Hibernate geht würde ich mit dem Entity-Manager beginnen, und wenn seine API etwas nicht abdeckt, spezielles Locking etwa, würde ich mir vom Entity-Manager den Hibernate-Session geben lassen. Eine Möglichkeit ist, den Entity-Manager von EJB 3 auf die Implementierung HibernateEntityManager zu casten und sich dann die Session zu holen:
Session session = ((HibernateEntityManager)entityManager).getCurrentSession();
Eine weitere Möglichkeit ist, sich von JBoss direkt eine Hibernate Session spritzen zu lassen:
private @PersistenceContext Session session;
Ich habe eine Klasse die jeweils mit JAXB2 Mitteln entweder aus einem Schema--> Java Klassen erzeugt und dann später wieder XML daraus. Ist es jetzt sinnvoll diese Hauptklasse als SessionBean zu annotieren? Und die von JAXB2 erzeugten Objekt-klassen implementieren ja standardmäßig nicht "java.io.Serializable" müsste ich das dann auch machen?
Das würde ich nicht tun. Die JAXB-Klassen sind ja so eine Art Value-Objekt, die man weitergibt. Das sind selbst keine Klasen mit Logik, sondern eher verwandt mit Entity-Beans, nur das Entity-Beans klassischerweise auf eine relationale DB gehen, und JABX-Klassen in eine XML-Datei.
Sollte man bei EJB 3 noch das DAO Pattern anwenden? Man füllt ja mit den EntityManager direkt die Entity-Beans. In EJB 3 macht man doch eigentlich nur noch:
Customer c = new Customer(); c.set( "tutego" ); entityManager.persist( c );
Eigentlich ist er ja laut EJB3 Persistence Definition obsolet.
Der DAO ist ja eine Schnittstelle/Klasse mit Funktionen
interface CustomerDao
{
List<Customer> getAllCustomers();
}
Die Implementierung bekommt den EM injiziert und realisiert damit den DAO. DAO ist wichtig zur Abstraktion, damit die Geschäftsschicht nicht mehr "sieht", woher die Objekte kommen; aus einer DB, XML-Datei, CSV, ... Alle, die Daten brauchen gehen immer über den DAO, der dann im Sinne einer SOA ein Service ist.
Nicht die DAOs sind obsolet, sondern die Transferobjekte (DTO). Der DAO hilft, die Entity-Beans erst zu erfragen. Im Client-Code steht also etwas:
CustomerDao dao = DaoFactory.getInstance().getCustomerDao(); List<Customers> customers = dao.getAllCustomers();
Der EM ist quasi ungetypt und er DAO getypt (er kann nur Customer, Invoices, ...). Alles, was der Client mit irgendwelchen Enddaten machen will -- speichern, laden, aktualisieren, holt er sich über den DAO. Der Client macht dann gerade nicht (!):
Customer c = new Customer(); c.set( "tutego" ); entityManager.persist( c );
sondern
Customer c = new Customer(); c.set( "tutego" ); dao.saveCustomer( c );
Das Client "sieht" ja den EM gar nicht, sondern seine einzige API ist der DAO. Das gilt für JEDEN Client, also auch für die Session-Bean, der man ja eigentlich auch den EM spritzen könnte. Doch der EM wird ausschließlich in die DAO-Implementierung injiziert. Der Client kennt den DAO als "Holer" und den Customer als Geschäftsobjekt.
Tools
Wie kann ich ein Programm als Service unter Windows starten?
Mit dem Microsoft Programm SRVANY lässt sich java.exe als Programm (Application) in der Registry eintragen. Als Parameter (AppParameters) wird dann die Java Klasse und der Classpath für alle Klassen angegeben.
Mit Hilfe des Parameters -exclude kann man bei Javadoc komplette Pakete von der Dokumentation ausschließen. Nun möchte ich allerdings nur einzelne Klassen innerhalb eines Pakets ausschließen. Ist das irgendwie möglich?
Wenn du ant (http://ant.apache.org/manual/CoreTasks/javadoc.html)
benutzt, schau dir doch mal das FileSet
(http://ant.apache.org/manual/CoreTypes/fileset.html) an.
<fileset dir="${server.src}" casesensitive="yes">
<include name="**/*.java"/>
<exclude name="**/*Test*"/>
</fileset>
Damit sollte das gehen, etwa so:
<javadoc packagenames="..." destdir="..." ... <fileset dir="..."> <include name="**/*.java" /> <exclude...> </fileset> </javadoc>
JVM
Java 5 heiß ja lange Tiger. Gibt es auch für die anderen Java-Versionen solche Bezeichner?
Für fast jede Java-Version gibt es Code-Namen, etwa für 1.1.4 Sparkler (Diamant), 1.1.5 Pumpkin (Kürbis, auch Trottel), 1.1.6 Abigail (Zofe), 1.1.7 Brutus und 1.1.8 Chelsea . Java 1.2 hieß Playground, und für die folgenden Versionen nutzte Sun Tiernamen (http://java.sun.com/j2se/codenames.html): Cricket 1.2.2 (Grille), 1.3 Kestrel (Turmfalke), Ladybird 1.3.1 (Marienkäfer), 1.4.0 Merlin (Falke), 1.4.1 Hopper (Heuschrecke), 1.4.2 Mantis (Gottesanbeterin), 5 Tiger, 6 Mustang und 7 Dolphin (Delfin). Vielleicht finden wir demnächst auch Java-Flugfrosch, Java-Nashorn und Javaneraffe (lat. Macaca fascicularis, eine krabbenfressende Affenart) – diese Tiere gibt’s wirklich und einen Java-Tiger auch. (Der ist übrigens vom Aussterben bedroht.)