java grafikausgabe mit swing
-
hallo !
wir haben als hausaufgabe auf ein kleines programm zur textverarbeitung zu schreiben. ich will das ganze in java swing realisieren. dazu habe ich schon eine application geschrieben die jframe extended. eine jmenubar und eine iconbar, die ein paar kleine icons in einem panel enthält (text linksbündig, blocksatz, speichern, usw,). für die contentpane benutze ich ein borderlayout was für meine zwecke ausreichen sollte. im centerbereich soll der text mittels der drawstring-methode geschrieben werden. zunächst soll der text einfach nur dargestellt werden können,der aus einem vector ausgelesen wird ,erst später kommt ein keylistener hinzu. da ich noch nie mit swing oder awt gearbeitet habe tue ich mich momentan noch schwer, bitte kein awt vorschlagen es ist aufgabe es in swing zu realisieren. nun gut ich habe also folgende klasse geschrieben :
import java.awt.*; import javax.swing.*; import java.util.*; public class GraphicPanel extends JPanel { public GraphicPanel(int width, int height) { setBackground(Color.white); setPreferredSize(new Dimension( width, height)); } public void paint(Graphics g) { paintComponent(g); } public void printWords(Vector words) { Graphics g = getGraphics(); if(g == null) System.out.println("null in g"); } }
ich erzeuge also ein neues graphicpanel. nun will ich dort hineinschreiben mit der mehtode printwords. ich weiss dass das hier so nicht geht, weil man das doch immer repainten muss , oder ?? wie man sieht bekommt die methode einen vector mit wörtern übergeben die auf den bildschirm geprinted werden sollen. meine idee hinter dieser klasse ist, dass ich einmal ein graphicspanel als object erstelle und dann immer wieder neu in das panel zeichnen kann wann immer ein wort hinzukommt oder buchstaben. ist das in der form wie ich das hier mache überhaupt sinnvoll, und wenn ja wieso funktioniert die sache nicht so wie ich mir das vorstelle. ich gebe zu bei der grafikausgabe mit graphicsobjekten und swing bin ich noch nicht so ganz durchgestiegen aber momentan habe ich damit wirklich noch zu kämpfen. kann man hier später auch ohne probleme einen keylistener hinzufügen, sicher oder ??
über eine antwort würde ich mich sehr freuen.
vielen dank & mfg
tom
-
Hi, Swing hat zur Textverarbeitung schon sehr nützliche Klassen. Einen eigenen Panel zum Text schreiben und anzeigen zu coden, der nichts mit den schon vorhandenen Text-Klassen zu tun hat, ist bis auf Ausnahmefälle unnötig.
Für Texte mit Attributen kannst du die Klasse JTextPane verwenden. Die ist allerdings nicht ganz einfach zu handlen. Lies dir am besten mal ne Doku oder ein Tutorial drüber durch. Wenn du trotzdem lieber alles selber coden willst (was natürlich wesentlicher aufwendiger ist), dann ist das mit paint und co etwa so:man überschreibt normalerweise nicht paint(Graphics g) direkt sondern paintComponent(Graphics g) (bei Swing-Componenten=JComponent und extended). Jetzt hast du irgendwo deine Daten(kann auch in ner ganz anderen Klasse sein), also in deinem Fall den Text + Textattribute, die du dann in paintComponent nach deinen Vorstellungen anzeigen lässt. Wenn jetzt der User ein neues Zeichen eingibt(was du normal über KeyListener abfragen kannst), änderst du zuerst dein Datenmodell ab (fügst das Zeichen also irgendwo in einem StringBuffer hintenan oder was auch immer) und rufst dann repaint() von deiner Komponente auf (bzw repaint(xPos,yPos,width,height) für Teil-repaint...wenn sich nur ein Zeichen ändert ist es Verschwendung alles nochmal zeichnen zu lassen) . Dieser Aufruf triggert (normalerweise) den Aufruf von paintComponent. Weil du ja dein Datenmodell abgeändert hast und paintComponent das Datenmodell auf dem Bildschirm ausgibt, erscheint wenn du es richtig gemacht hast, das neue Zeichen auf dem Bildschirm
cu crass
[ Dieser Beitrag wurde am 02.07.2003 um 22:46 Uhr von crass editiert. ]
-
Also ich würde das jetzt mal spontan ähnlich machen, aber mit dem Unterschied, dass ich in der Methode printWords() nichts zeichenn würde, sondern dort nur eine Variable setzen würde.
Danach rufst du repaint() aug und in paintComponent() (!) wird dann alles gezeichnet.[java]// Hier eine Membervariable, die eben den Text speichert
private Vector words = new Vector();public void paintComponent(Graphics g)
{
Iterator it = words.iterator();
for (int i = 1; it.hasNext(); i++) {
g.drawString((String)it.next(), 5, i*15);
}
}public void printWords(Vector words)
{
this.words = words;
repaint();
}[/code](Alles ungetestet)HTH.
Du solltest deine Methode paint() streichen. DAs könnte dir so große Probleme bereiten, wenn du da in der Aufrufhirarchie der Swing-Komponenten 'herumpfuschst' - Flimmern, langsame Ausgabe, ...)
[Edit]Da war wohl wer schneller
Naja ansich steht ohnehin in beiden Posts das selbe.[/Edit][ Dieser Beitrag wurde am 02.07.2003 um 22:51 Uhr von destruct0r editiert. ]
-
Naja ansich steht ohnehin in beiden Posts das selbe
ja bis auf das man normalerweise sowiseo JTextPane verwenden sollt. Man spart sich ne Menge Arbeit ein Wenn man alles selber macht muß man sich auch noch um Dinge wie Caret (TextCursor) Gedanken machen.. is ne Sauarbeit
-
ja bis auf das man normalerweise sowiseo JTextPane verwenden sollt. [...] is ne Sauarbeit
Stimmt. Ich weiß auch, wieviel Arbeit das ist, ich habe nämlich mal nen HTML-Editor geschrieben. Das war extrem viel Aufwand, bis das alles geparst war. Vorallem die Performance macht einem da richtig viel Schwierigkeiten. Und das ganze wie Cursor, Markierungen, Syntax-Highlighting, Tag-Insight, ... macht einfach nur viel Arbeit...
Ich habe ihm das JTextPane eigentlich gar nicht vorgeschlagen, weil ich angenommen habe, dass er es selber machen will.
-
Wollt auch mal nen HTML-Parser+Viewer schreiben, war dann aber zu faul
tom07 hat ja gepostet, daß er sich nicht mit Swing auskennt, deswegen geh ich mal davon aus, daß er gar nicht wußte daß es sowas wie JTextPane gibt..
-
hi crass !
tatsächlich hab ich nicht viel ahnung von swing aber wir müssen genau die sache alle selber machen also auch den textcursor.ich werd die sache nun mal ausprobieren.
mfg
tom
-
hi nochmal!
also ich hab mal folgendes gemacht :
import java.awt.*; import javax.swing.*; import java.util.*; public class GraphicComponent extends JComponent { private Vector words; public GraphicComponent(Vector words) { this.words = words; } public void paintComponent(Graphics g) { g.drawString("test text", 30,30); } public void printWords() { repaint(); } }
und dann die methode aus der klasse die das ganze behandelt:
private void addGraphicComponent() { Container contentPane = getContentPane(); GraphicComponent gComponent = new GraphicComponent(words); JPanel panelForText = new JPanel(); JScrollPane scrollPane = new JScrollPane (panelForText); panelForText.setPreferredSize(new Dimension(600,350)); panelForText.setBackground(Color.white); panelForText.add(gComponent); contentPane.add(panelForText , BorderLayout.CENTER ); scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); contentPane.add( scrollPane ,BorderLayout.SOUTH); gComponent.printWords(); }
allerdings habe ich nun zwei probleme. zum einen ist die jscrollpane verschwunden und zum anderen wird auch nichts gezeichnet. das panel wird jedoch richtig initialisiert.
was hab ich denn nun schon wieder falsch gemacht ???mfg
tom
-
Hi, hab das ganze mal etwas für dich umgeschrieben, jetzt funktioniert es soweit ..du hattest u.A JScrollPane falsch verwendet (JScrollPane ist ein Container für andere Comps , keine ScrollBar )
class GraphicComponent extends JComponent { private Vector words; public GraphicComponent(Vector words) { this.words = words; } public void clearBackground(Graphics g) { Graphics copG=g.create(); copG.setColor(getBackground()); copG.fillRect(0,0,getWidth(),getHeight()); } public void paintComponent(Graphics g) { clearBackground(g); //JPanel hat das Background löschen schon auto drin //mit nem Aufruf von super.paintComponent() g.drawString("test text", 30,30); } public void printWords() { repaint(); } } private void addGraphicComponent() { Container contentPane = getContentPane(); GraphicComponent gComponent = new GraphicComponent(words); gComponent.setPreferredSize(new Dimension(600,350)); gComponent.setBackground(Color.white); JScrollPane scrollPane = new JScrollPane (gComponent); contentPane.add( scrollPane ,BorderLayout.CENTER); gComponent.printWords(); }
[ Dieser Beitrag wurde am 03.07.2003 um 21:02 Uhr von crass editiert. ]
-
hi crass !
vielen dank. leider habe ich das gefühl ,dass ich immer weniger bei der sache mit grafikausgabe unter java verstehe. gibt es vielleicht ein vernünftiges buch was einem sowas mal erklärt. weil ehrlich gesagt find ich den ansatz den du jetzt grad beschrieben hast ziemlich unintuitiv. oder vielleicht wie kann ich mir abstrakt gesehen das object graphics vorstellen ??mfg
tom
-
Graphics ist das Objekt, das du dir wie einen Bildschrirm vorstellen kannst. Du kannst die Farbe bestimmen, dann Flächen, Linien, ..., Strings zeichenn und am Ende der paintComponent() wird das ganze, was du auf dem Graphics-Objekt gemacht hast für dich von java auf den Bildschirm gebracht.
Jetz mal ganz abstrakt
-
Ich hab in clearBackground das Graphics-Objekt kopiert (mit create() ) damit sich die Änderungen an dem Objekt (in diesem Fall nur die Zeichenfarbe) nicht auch in paintComponent auswirken.. du kannst das auch anders machen..
wenn du dich mit Java allgemein noch nicht so gut auskennst, kann ich dir als Buch "Handbuch der Java-Programmierung" von Guido Krüger empfehlen. Speziell für Swing hab ich das Buch "Java Swing" vom O'Reilly - Verlag (mehrere Autoren).. is ein ziemlich ausführliches, hilfreiches Buch, gibts aber glaub ich nur auf Englisch. Für Java2D-API (die Grafik-Sachen) gibts das Buch Java2D Api-Graphics von Vincent J. Hardy (auch empfehlenswert, aber englisch)
-
alles klar! vielen dank an euch beide. ihr habt mir ja schon ziemlich weitergeholfen...:)
mfg
tom