Mors
Osaako joku heittää vinkkejä tai jopa pientä koodinpätkää miten saisin ohjattua nuo System-viestit tekstipaneeliini (ei mitään tiedosto ja logihommia vaan ihan oikeaan UI:hin siististi)? Rekisteröinkö itseni niiden kuuntelijoiksi vai miten saan sen uudelleenohjattua?
Osaako joku heittää vinkkejä tai jopa pientä koodinpätkää miten saisin ohjattua nuo System-viestit tekstipaneeliini (ei mitään tiedosto ja logihommia vaan ihan oikeaan UI:hin siististi)? Rekisteröinkö itseni niiden kuuntelijoiksi vai miten saan sen uudelleenohjattua?
Vastaukset 8
Vanhimmat
Siis onks sulla joku rivi tyyliin
System.out.prinln("Tässä errori" error);
ja haluut sen GUIhin vai mistä on kyse?
Jep, juuri niin. Eli luon sen saman output konsolin mitä normaalisti esiintyy IDE työkaluissa.
Luulisin ettei sitä mitenkään helposti tai pienellä koodin pätkällä saa tehtyä. Metodeilla System.setErr(PrintStream ps), System.setOut(PrintStream ps) ja System.setIn(InputStream is) voit muuttaa "standardi" virtoja. Googlella löysin alla olevan jutun, jossa on myös jotain koodia, (tosin en tiedä onko siitä apua, enkä myöskään ole testannut kyseisten koodien toimivuutta).
http://forum.java.sun.com/thread.jspa?threadID=591668&messageID=3088246
Jos satut löytämään jostain toimivan koodi esimerkin, niin heitä linkki myös tänne.
Moi
Pitää varmaan itse vääntää toi.
Uskoisin että menee jotenkin näin:
Väsätään se paneeli komponentti ja sillä on kaksi muuttujaa errorStream ja outStream. Haetaan ne streamit noilla sun osoittamilla komennoilla ja talletetaan ne viitteet tähän paneeliin. Paneelista voisi tehdä vaikka oman threadin pienimmällä prioriteetilla.
Paneeli sitten vaan looppaa ja lukee niitä streameja ja tulostaa ruutuun kaman mitä tulee ulos.
Se on hyvä että mielenkiintoa riittää. Laitan tähän viestiin äsken väsäämäni koodin pätkän, joka kaksinkertaistaa OUT ja ERR virtojen merkkien määrän. Toivottavasti saat esimerkki koodista jotain vinkkiä siihen miten "virtojen" kaappauksen mahdollisesti voisi tehdä. Luulisin että tässä sinun projektissasi, suurin homma on juuri se "paneeli" komponentin tekemisessä, ainakin jos haluat siihen vieritys palkit, autoscrollit, yms. Itse lähtisin asiaa tekemään niin, että "virran kaappaaja" lukisi dataa virrasta vakio mittaiseen taulukkoon, ja sitten tämä paneeli kävisi tietyn väliajoin lukumassa kyseisen taulukon ja päivittäisi itsensä. Kun ohjelmaa tekee, niin tulee huomioida se että Swing komponentit (kuten tämä paneeli) suoritetaan Swing säikeessä, joten tällöin tulee ottaa synkronointi huomioon (ainakin silloin kun paneeli käy lukemassa sen mitä virtaan on kertynyt).
--- ALKU: Esimerkki.java ---
import java.io.PrintStream;
public class Esimerkki {
public static void main(String[] args) {
System.setOut(new PrintStream(new OmaOutputStream(System.out)));
System.setErr(new PrintStream(new OmaOutputStream(System.err)));
System.out.println("Output virta");
System.err.println("Virhe virta");
}
}
--- LOPPU: Esimerkki.java ---
--- ALKU: OmaOutputStream.java ---
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
public class OmaOutputStream extends OutputStream {
private PrintStream vanhaVirta;
public OmaOutputStream(PrintStream vanhaVirta) {
this.vanhaVirta = vanhaVirta;
}
public void write(int value) throws IOException {
vanhaVirta.write(value);
vanhaVirta.write(value);
}
}
--- LOPPU: OmaOutputStream.java ---
Luo JTextArea, ja anna se vaikka konstruktorin parametrina tälle output-hässäkälle. Nyt riittää kutsua OmaOutputStreamin write-metodeissa (tai omassa metodissa) textarea.append(string).
JTextArea huolehtii itse oman ulkoasunsa päivittämisestä.
public void print(String s) {
textarea.append(s);
textarea.setCaretPosition(textarea.getDocument().getLength());
}
class OmaOutputStream extends OutputStream {
public void write( int b ) throws IOException {
print( new String( new byte[]{ (byte)b },0, 1 ));
}
public void write( byte b[] ) throws IOException {
print(new String( b, 0, b.length ));
}
public void write( byte b[], int off, int len ) throws IOException {
print(new String( b, off, len ));
}
public void flush() throws IOException { }
public void close() throws IOException { }
} // end class
Totta; noinhan sen vissiinkin saa yksinkertaisesti ja näppärästi tehtyä. Sinne print metodiin kannattaa harkita vielä sitä dokumentin koon rajoitinta, jottei se koko muistia pääsisi kahmaisemaan. *Heh* En tosin tiedä, onko siinä Document objektissa automaattisesti joku rajoitus juttu vai ei, ja toisaalta aika paljon saa tekstiä tulla jotta muisti täyttyisi. :-)
Ainut heikko kohta koodissa voi olla setCaretPosition rivi. JTextArea:n append metodi on thread-safe (eli säie turvallinen), mutta setCaretPosition metodista en mene takuuseen (?? -korjatkaa- ??). Jos ohjelma siis heittää satunnaisesti epämääräisiä poikkeutuksia niin se voi johtua tuosta setCaretPosition rivistä.
Moi
Kyllä tämä homma kuulostaa nyt selvältä ja yksinkertaisemmalta kuin ajattelin aluksi. Täytyy kokeilla ensi viikolla. Kiitos!