/* * Skel.java * egy szkeleton megjelenítője: application és applet is, JDK1.2.2 szükséges * by pts@fazekas.hu at Wed Mar 21 18:25:59 CET 2001 * további doksi: a README-ben és e file legkülső class-ának fejkommentjében * * Kincskereső Kisgömböc (C) Early May 2001 by eNTitánok (Rév Szilvia, * Szabó Péter <pts@inf.bme.hu>, Szurdi Miklós, Weizengruber Attila). * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package eNTitanok.gfx; import java.io.StringWriter; import java.io.PrintWriter; import java.applet.Applet; import java.util.StringTokenizer; import java.util.Vector; import java.awt.Component; import java.awt.Canvas; import java.awt.Graphics; import java.awt.TextField; import java.awt.TextArea; import java.awt.GridBagLayout; import java.awt.GridBagConstraints; import java.awt.FlowLayout; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Frame; import java.awt.event.WindowAdapter; import java.awt.Label; import java.awt.Dimension; import java.awt.Font; import java.awt.FontMetrics; import java.awt.Toolkit; import java.awt.IllegalComponentStateException; import java.awt.event.ComponentAdapter; import java.awt.event.ComponentEvent; import java.awt.event.ComponentListener; import java.awt.event.WindowEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowListener; import java.awt.event.MouseEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseListener; import java.awt.event.FocusEvent; import java.awt.event.FocusAdapter; import java.awt.event.FocusListener; import java.awt.event.KeyEvent; import java.awt.event.KeyAdapter; import java.awt.event.KeyListener; import eNTitanok.gfx.OkosAWT.OkosApplet; import eNTitanok.gfx.OkosAWT.OkosFrame; import eNTitanok.gfx.OkosAWT.OkosCanvas; /** * Ez a file tartalmazza egy (akármilyen) szkeleton program megjelenítéséért * felelős részeit. A futtatáshoz JDK1.2.2 kell, mert a JDK1.1.7-ben teljesen * hibás (bugos, deadlock-os) a java.awt.TextField widget. Az itt megvalósított * szkeleton modell az eljárások neveit a Java metódushívási fa elemzésével * állapítja meg, amibe nagyon bekavarnak az öröklésék és a JIT optimalizáció. * Érdemes tehát <code>javac -g</code>-vel fordítani. * * <P>Próbáltam a Linux-os JDK1.1.7-tel, de a program végtelen ciklusba került * ha TextField.setEditable()-t vagy TextField.getText()-et hívtam. JDK1.2-vel * pedig tökéletesen futott. Ezen a ponton feladtam a JDK1.1-gyel való * kompatibilitást -- ha annyira bugos egy implementáció, hogy egy * stringlekérdező függvényre lefagy a program, arra nem lehet fejleszteni. * Ki tudja, hogy még mennyi felfedezetlen bug várt volna rám. */ public class Skel extends OkosApplet implements Runnable { public static class StackKeret { public static final String CONSTRUCTOR="<constructor>"; protected String klassz, metodus, filenev; protected int sorszam; StackKeret(String klassz, String metodus) { this.klassz=klassz; this.metodus=metodus; } public String getKlassz() { return klassz; } public String getMetodus() { return metodus; } public String getFilenev() { return filenev; } public int getSorszam() { return sorszam; } public void setFilenev(String filenev) { this.filenev=filenev; } public void setMetodus(String metodus) { this.metodus=metodus; } public void setSorszam(int sorszam) { this.sorszam=sorszam; } public String toString() { return "[at "+klassz+"."+metodus+"("+filenev+":"+sorszam+")]"; } public String toString2() { return klassz+"."+metodus+" ["+filenev+":"+sorszam+"]"; } } public static StackKeret[] honnanHivtak(int kezd) { /* @param kezd: a tetejéről számított hányadik indextől adjuk vissza. * ha kezd==0, akkor egy honnanHivtak-os sor lesz a 0. visszadott elem. * @return null, ha a Java nem támogatja a sorszám-debug-ot */ StringWriter sw=new StringWriter(); PrintWriter pw=new PrintWriter(sw,true); try { throw new Exception("honnanTeszt"); } catch (Exception e) { e.printStackTrace(pw); } String ss=sw.toString(); // sw.toString() tipikus kimenete (Sun JDK1.1.7): // java.lang.Exception: ... // at Skel.honnanHivtak(Skel.java:16) // at Skel.hejho(Skel.java:22) // at Skel.init(Skel.java:26) // at sun.applet.AppletPanel.run(AppletPanel.java:281) // at java.lang.Thread.run(Thread.java) // vvv Most pedig foggal-körömmel-kisbaltával feldolgozzuk ss-et, és // jól kezelhető StackKeret objektumokat hozunk létre. Ez különösen // fáradságos, méltatlan, hálátlan, pilinszázós feladat, mivel // Java-ban nincsenek regexp-ek (miért is lennének?? miért is kapjon // a programozó végre egy hatékony eszközt a kezébe??). if (ss.startsWith("java.lang.Exception")) { int i=ss.indexOf('\n'); if (i==-1) return null; ss=ss.substring(i+1); } // System.out.println(ss); StringTokenizer st=new StringTokenizer(ss, "\010\011\012\013\014\015\000\n\r\t \"~!@#%^&*()+|{}:<>?`-=[];',",true); // ^^^ kimaradtak: . / \ $ _ Vector v=new Vector(); // elemei: StackKeret final int KLASSZ=1, FILENEV=2, SORSZAM=3, FILENEV_NYIT=4, SORSZAM_NYIT=5, SOREMELES=6; int varjuk=KLASSZ; StackKeret k=null; while (st.hasMoreTokens()) { String s=st.nextToken(); char c=s.charAt(0); if (c==010 || c==011 || c==040 || c==0 || c=='\t') continue; // ^^^ nem sortörő white space kihagyása if (c>=010 && c<=015 || c=='\n' || c=='\r') c='\n'; // ^^^ sortörő white space konvertálása '\n'-né if (c=='\\') c='/'; if (c=='\n') { if (k!=null) { v.addElement(k); k=null; } varjuk=KLASSZ; continue; } boolean nev_e=Character.isJavaIdentifierStart(c); //System.out.println(varjuk); //System.out.println(nev_e); if (varjuk==KLASSZ && nev_e) { if (s.equals("at") || s.equals("in") || s.equals("from")) continue; int i=s.lastIndexOf('.'); if (i==-1) { varjuk=SOREMELES; continue; } varjuk=FILENEV_NYIT; k=new StackKeret(s.substring(0,i), s.substring(i+1)); // System.out.println("klassz,metodus: "+s); } else if (varjuk==FILENEV_NYIT && c=='<') { k.setMetodus(StackKeret.CONSTRUCTOR); } else if (varjuk==FILENEV_NYIT && c=='(') { varjuk=FILENEV; } else if (varjuk==FILENEV && (nev_e||c=='/')) { if (s.equals("Compiled")) { k=null; varjuk=SOREMELES; } else { varjuk=SORSZAM_NYIT; // System.out.println("filenev: "+s); k.setFilenev(s); } } else if (varjuk==SORSZAM_NYIT && (c==')' || c==',')) { varjuk=SOREMELES; v.addElement(k); k=null; } else if (varjuk==SORSZAM_NYIT && c==':') { varjuk=SORSZAM; } else if (varjuk==SORSZAM && Character.isDigit(c)) { varjuk=SOREMELES; int i=0; try { i=Integer.parseInt(s); } catch (NumberFormatException e) {} // System.out.println("sorszam="+i); k.setSorszam(i); v.addElement(k); k=null; // } else { System.out.println(">"+s+"<"); } } { // hack, hogy NT-s Java-n is menjen... int i=0; while (i<v.size() && !((StackKeret)v.elementAt(i)).getKlassz().equals("java.lang.Exception")) i++; if (i!=v.size()) { Vector ujv=new Vector(); for (i+=1;i<v.size();i++) ujv.addElement(v.elementAt(i)); v=ujv; } } if (v.size()<=kezd) return null; StackKeret t[]=new StackKeret[v.size()-kezd]; for (int i=0;i<t.length;i++) t[i]=(StackKeret)v.elementAt(i+kezd); // for (int i=0;i<t.length;i++) System.out.println(">>>"+t[i]); return t; } public static StackKeret[] honnanHivtak() { return honnanHivtak(2); } // --- szekvenciadiagram rajzolása // by pts@fazekas.hu at Sunday, March 25, 2001 public static class SzekvenciaFejlec { public String klassz, klassz_kiir; public int idx; public int x; // középvonal x koordinátája megjelenítéshez public int van; // hány objektumpéldány létezik az adott klassz-ból public int fut; // hány metódus fut éppen az adott klassz objektumpéldányaiból } public static class SzekvenciaBejegyzes { public static final int TAVOLSAG=69; // 9*69==621 public static final int SORTAV=30; private SzekvenciaFejlec fejlec; private int van, volt; // hány objektumpéldány létezik az adott klassz-ból private int fut, futott; // hány metódus fut éppen az adott klassz objektumpéldányaiból private boolean aktiv; public SzekvenciaBejegyzes(String klassz, String klassz_kiir, int idx) { fejlec=new SzekvenciaFejlec(); fejlec.klassz=klassz; fejlec.klassz_kiir=klassz_kiir; fejlec.idx=idx; fejlec.x=TAVOLSAG/2+TAVOLSAG*idx; fejlec.van=this.van=this.volt=0; fejlec.fut=this.fut=this.futott=0; aktiv=false; } public SzekvenciaBejegyzes(SzekvenciaBejegyzes regi) { /* az új sorhoz tartozó bejegyzést állítjuk elő a régi sorhoz tartozóból */ fejlec=regi.fejlec; volt=van=regi.van; fut=futott=regi.fut; aktiv=regi.aktiv; } public int getX() { return fejlec.x; } public int setVan(int van) { return this.van=fejlec.van=van; } public int setFut(int fut) { return this.fut=fejlec.fut=fut; } public int addVan(int van) { return this.van=fejlec.van+=van; } public int addFut(int fut) { return this.fut=fejlec.fut+=fut; } public boolean setAktiv(boolean aktiv) { return this.aktiv=aktiv; } public boolean isKlassz(String klassz) { return this.fejlec.klassz.equals(klassz); } public void kirajzol(SzekvenciaCanvas sc, int y) { Graphics g=sc.getGraphics2(); g.setColor(Color.cyan); if (futott<1) g.drawLine(fejlec.x, y-SORTAV+1, fejlec.x, y-7); else g.fillRect(fejlec.x-1, y-SORTAV+1, 3, SORTAV-7); if (fut<1) g.drawLine(fejlec.x, y-6, fejlec.x, y); else g.fillRect(fejlec.x-1, y-6, 3, 7); } public void fejlec_kirajzol(SzekvenciaCanvas sc, int y) { sc.drawStringKeret(fejlec.klassz_kiir+"*"+van, fejlec.x, y); } } /// class SzekvenciaBejegyzes public static class SzekvenciaSor { public static class MarHivtakError extends Error {} public static class HibasTipusError extends Error {} public static final int T_SEMMI=0, T_HIVAS=1, T_VISSZATERES=2, T_KONSTRUKTOR=3; private SzekvenciaBejegyzes bejegyzesek[]; private int aktiv_idx; private int aktiv_volt_idx; private int mindenes_idx; // melyik bejegyzéshez kerül az ismeretlen klassz-ú metódushívás private int tipus; private String metodus; // metódus neve private int honnan_idx; // melyik bejegyzés hívta a metódust private int hova_idx; // melyik bejegyzés metódusát hívtuk public SzekvenciaSor(SzekvenciaBejegyzes bejegyzesek[], int mindenes_idx) { this.bejegyzesek=bejegyzesek; this.mindenes_idx=mindenes_idx; this.aktiv_idx=this.aktiv_volt_idx=mindenes_idx; this.tipus=T_SEMMI; bejegyzesek[mindenes_idx].addFut(1); } public SzekvenciaSor(SzekvenciaSor regi) { /* az új sort hozzuk létre a régiből */ bejegyzesek=new SzekvenciaBejegyzes[regi.bejegyzesek.length]; for (int i=0;i<regi.bejegyzesek.length;i++) bejegyzesek[i]=new SzekvenciaBejegyzes(regi.bejegyzesek[i]); aktiv_volt_idx=aktiv_idx=regi.aktiv_idx; tipus=T_SEMMI; } private int klassz_keres(String klassz) { /* -1, ha nincs olyan klassz */ int i=bejegyzesek.length-1; while (i>=0 && !bejegyzesek[i].isKlassz(klassz)) i--; return i; } private int klassz_keres_mindenes(String klassz) { int j=klassz.lastIndexOf('$'); if (j!=-1) klassz=klassz.substring(j+1); int i=klassz_keres(klassz); return i==-1?mindenes_idx:i; } private void setAktiv(int idx) { if (aktiv_idx>=0) bejegyzesek[aktiv_idx].setAktiv(false); bejegyzesek[idx].setAktiv(true); aktiv_idx=idx; } public void esemeny(StackKeret honnan, StackKeret hova, int tipus) { if (this.tipus!=T_SEMMI) throw new MarHivtakError(); this.tipus=tipus; metodus=hova.getMetodus(); honnan_idx=klassz_keres_mindenes(honnan.getKlassz()); hova_idx=klassz_keres_mindenes(hova.getKlassz()); if (tipus==T_HIVAS) { bejegyzesek[hova_idx].addFut(1); } else if (tipus==T_KONSTRUKTOR) { bejegyzesek[hova_idx].addVan(1); bejegyzesek[hova_idx].addFut(1); } else if (tipus==T_VISSZATERES) { bejegyzesek[hova_idx].addFut(-1); } else throw new HibasTipusError(); setAktiv(hova_idx); } public void kirajzol(SzekvenciaCanvas sc, int y) { for (int i=0;i<bejegyzesek.length;i++) bejegyzesek[i].kirajzol(sc,y); if (tipus==T_HIVAS) { sc.drawStringNyil(metodus, bejegyzesek[honnan_idx].getX(), y-7, bejegyzesek[hova_idx].getX()); } else if (tipus==T_KONSTRUKTOR) { sc.drawStringNyil("<c.tor>", bejegyzesek[honnan_idx].getX(), y-7, bejegyzesek[hova_idx].getX()); } else if (tipus==T_VISSZATERES) { sc.drawStringNyil("<vissza>", bejegyzesek[hova_idx].getX(), y-7, bejegyzesek[honnan_idx].getX()); } } public void fejlec_kirajzol(SzekvenciaCanvas sc, int y) { for (int i=0;i<bejegyzesek.length;i++) bejegyzesek[i].fejlec_kirajzol(sc,y); } } /// class SzekvenciaSor public static class SzekvenciaCanvas extends OkosCanvas { private FontMetrics fm; private Graphics g; protected SzekvenciaSor sorok[]; protected int utso; // első már nem használt index a sorok-ban, mindig >=1 public SzekvenciaCanvas() { font2=new Font("sansserif",Font.PLAIN,12); setBackground(new Color(255,240,208)); } public void ujsor() { int kifer=hanySorFerKi(); if (utso>=kifer) { System.arraycopy(sorok, utso-kifer+1, sorok, 0, kifer-1); utso=kifer-1; } sorok[utso]=new SzekvenciaSor(sorok[utso-1]); utso++; } public void esemeny(StackKeret honnan, StackKeret hova, int tipus) { ujsor(); sorok[utso-1].esemeny(honnan, hova, tipus); repaint(); // Imp: scrolling } public int hanySorFerKi() { int kifer=(this.getSize().height-18)/SzekvenciaBejegyzes.SORTAV; if (kifer<2) kifer=2; if (sorok==null || kifer>sorok.length) { SzekvenciaSor ujsorok[]=new SzekvenciaSor[kifer]; if (sorok!=null) for (int i=0;i<utso;i++) ujsorok[i]=sorok[i]; sorok=ujsorok; } return kifer; } public Graphics getGraphics2() { return g; } public synchronized void paint(Graphics g) { // synchronized fontos! int kifer=hanySorFerKi(); this.g=g; g.setFont(font2); fm=g.getFontMetrics(); int y=18; sorok[utso-1].fejlec_kirajzol(this,y); for (int i=utso-kifer;i<utso;i++) { if (i<0) continue; y+=SzekvenciaBejegyzes.SORTAV; sorok[i].kirajzol(this,y); } } public void drawStringKozep(String str, int x, int y) { // x: középső pixel // y: baseline int w=fm.stringWidth(str); g.drawString(str, x-w/2, y); } public void drawStringKeret(String str, int x, int y) { // x: középső pixel // y: keret alsó vonala int w=fm.stringWidth(str); int a=fm.getAscent(); int d=fm.getDescent(); g.setColor(Color.white); g.fillRect(x-w/2-1, y-a-d+1, w+2, a+d-1); g.setColor(Color.black); g.drawString(str, x-w/2, y-d); g.setColor(Color.blue); g.drawRect(x-w/2-2, y-a-d-1, w+4, a+d+1); g.drawLine(x,y+1,x,y+1); } public void drawStringNyil(String str, int x1, int y, int x2) { // nyíl: (x1,y)->(x2,y) int w=fm.stringWidth(str); g.setColor(Color.red); int sx; if (x1==x2) { sx=x1+5; y-=5; g.drawLine(x1,y ,sx+w/2, y ); g.drawLine(x1,y+5,sx+w/2, y+5); g.drawLine(sx+w/2,y,sx+w/2,y+5); // vvv nyíl hegye g.drawLine(x2+3,y+5+3,x2,y+5); g.drawLine(x2+3,y+5-3,x2,y+5); } else { sx=(x1+x2-w)/2; g.drawLine(x1,y,x2,y); if (x2>x1) { g.drawLine(x2-3,y-3,x2,y); g.drawLine(x2-3,y+3,x2,y); } else { g.drawLine(x2+3,y-3,x2,y); g.drawLine(x2+3,y+3,x2,y); } } g.drawString(str, sx, y-2); } } /// class SzekvenciaCanvas // --- /*public static void hejho() { StackKeret t[]=honnanHivtak(); for (int i=0;i<t.length;i++) System.out.println(t[i]); }*/ private static class JobbTextArea extends TextArea { protected int position2; protected boolean maradt; public void setCaretPosition2(int position) { // Ismét egy hülyesége a Java AWT-nek: csak kirajzolt TextArea // kurzorpozícióját lehet megváltoztatni. Őrület. position2=position; try { super.setCaretPosition(position); } catch (IllegalComponentStateException e) {} } public int getCaretPosition2() { return position2; } public synchronized void print(String s) { if (maradt) { append("\n"); maradt=false; } if (s.endsWith("\n")) { append(s.substring(0,s.length()-1)); maradt=true; } else { append(s); // setText(getText()+s); } setCaretPosition2(getText().length()); // ^^^ azért nem ez, mert az utolsó sor soremelése miatt nem szeretnénk // folyton üres sort látni } public synchronized void println(String s) { print(s+"\n"); } public void kurzortIgazit() { setCaretPosition2(position2); } } /// class JobbTextArea public static class JobbTextField extends TextField implements KeyListener { private static class Monitor {} protected volatile String sor; protected JobbTextArea jta; protected Monitor monitor; public JobbTextField(JobbTextArea jta) { monitor=new Monitor(); this.jta=jta; addKeyListener(this); } public String getSor() { return sor; } public String xreadln() { // ezt csak this.thread-ből szabad hívni setEditable(true); setText(""); synchronized(monitor) { try { monitor.wait(); } catch (InterruptedException e) {} } // sor=null; //while (sor==null) // try { Thread.sleep(100); } catch (InterruptedException e) {} // if (true) return ""; //synchronized(monitor) { // try { monitor.wait(); } catch (InterruptedException e) {} // Thread.currentThread().stop(); } //} // Thread.yield(); // synchronized(this) {} // try { Thread.sleep(2000); } catch (InterruptedException e) {} setEditable(false); // ^^^ ez a sor a vacak JDK1.1.7-ben deadlock-ot okozna. De miért? // Miért nem állíthatom át a flag-eket akkor, amikor akarom?? // Most csak a Java bugos, az implementáció bugos, vagy én nem értek // valamit?? A kék könyv és a Sun-féle API doksi semmit nem ír // erről. Igazán nem nagy kérés, hogy akkor állíthassam // szerkeszthetőre a mezőt amikor én akarom. De vannak olyan // programnyelvek, akiknek nagy kérés... // sor=getText(); // ^^^ ez is deadlock. No comment. // System.out.println("GEM"); // jta.println(">> "+sor); return sor; } public String readln() { xreadln(); jta.println("$$ "+sor); return sor; } public void keyPressed(KeyEvent e) { int i=e.getKeyCode(); // System.out.println("KT"+KeyEvent.VK_ENTER); if (i==KeyEvent.VK_ENTER) { synchronized(monitor) { sor=getText(); monitor.notifyAll(); } } } public void keyReleased(KeyEvent e) {} public void keyTyped(KeyEvent e) { // System.out.println("BE"); char c=e.getKeyChar(); if (c=='\n' || c=='\r') { synchronized(monitor) { sor=getText(); monitor.notifyAll(); } // System.out.println("gt"); // sor=getText(); //synchronized(monitor) { // System.out.println("monig"); // // sor=getText(); // System.out.println("gott"); // monitor.notifyAll(); //} // thread.interrupt(); // System.out.println("opp"); } // System.out.println("KI"); // ta.setCaretPosition2(Integer.MAX_VALUE); } } public static Skel skel; public void skel_main() { } private static final String sok_plussz="++++++++++++++++++++++++++++++++++++++++++++++++"; public static String n_db_plussz(int n) { /* n db '+'-ot tartalmazó String-et ad vissza */ if (n<=sok_plussz.length()) return sok_plussz.substring(0,n); return sok_plussz+n_db_plussz(n-sok_plussz.length()); } public static String[] str_split(char c, String s) { /* felvágja s-et c mentén */ // Még ezt az egyszerű függvényt is nekem kell megírnom. int n=0; int i=0; while (-1!=(i=s.indexOf(c,i))) { n++; i++; } String t[]=new String[n+1]; i=0; n=0; int j=0; while (-1!=(j=s.indexOf(c,i))) { t[n++]=s.substring(i,j); i=j+1; } t[n]=s.substring(i); return t; } private int alapPlussz; private String mostPlussz; public void println_plussz(String s) { ta.println(mostPlussz+s); } public void enter() { StackKeret t[]=honnanHivtak(2); // for (int i=0;i<t.length;i++) ta.println(t[i].toString()); if (t.length-alapPlussz>mostPlussz.length()+1) return; // ^^^ túl mélyre kerültünk (pl. szülő osztály konstruktoraiba) ta.println((mostPlussz=n_db_plussz(t.length-alapPlussz))+" >>"+t[0].toString2()); if (t.length>=2) c.esemeny(t[1],t[0],SzekvenciaSor.T_HIVAS); } public void constructor() { StackKeret t[]=honnanHivtak(2); if (t.length-alapPlussz>mostPlussz.length()+1) return; // ^^^ túl mélyre kerültünk (pl. szülő osztály konstruktoraiba) ta.println((mostPlussz=n_db_plussz(t.length-alapPlussz))+" +>"+t[0].toString2()); if (t.length>=2) c.esemeny(t[1],t[0],SzekvenciaSor.T_KONSTRUKTOR); } public void leave() { StackKeret t[]=honnanHivtak(2); if (t.length-alapPlussz>mostPlussz.length()) return; // ^^^ túl mélyre kerültünk (pl. szülő osztály konstruktoraiba) ta.println((mostPlussz=n_db_plussz(t.length-alapPlussz-1))+"+ <<"+t[0].toString2()); if (t.length>=2) c.esemeny(t[1],t[0],SzekvenciaSor.T_VISSZATERES); } public int ask(String kerdes, String valaszok[]) { ta.println(mostPlussz+" ?? "+kerdes); ta.print(mostPlussz+" |: "); for (int i=0;i<valaszok.length;i++) { if (i!=0) ta.print(" | "); ta.print(i+"="+valaszok[i]); } ta.println(""); int i; while (true) { String valasz=tf.xreadln(); i=0; while (i<valaszok.length && !valasz.equals(valaszok[i])) i++; if (i<valaszok.length) break; try { i=Integer.parseInt(valasz); } catch (NumberFormatException e) {} if (i>=0 && i<valaszok.length) break; Toolkit.getDefaultToolkit().beep(); } ta.println(mostPlussz+" $$ "+valaszok[i]); return i; } public int ask_int(String kerdes, int legalabb, int legfeljebb) { ta.println(mostPlussz+" ?? "+kerdes); ta.println(mostPlussz+" |: egy "+legalabb+" és "+legfeljebb+" közötti egész számot várok."); int i; while (true) { String valasz=tf.xreadln(); try { i=Integer.parseInt(valasz); if (i>=legalabb && i<=legfeljebb) break; } catch (NumberFormatException e) {} Toolkit.getDefaultToolkit().beep(); } ta.println(mostPlussz+" $$ "+Integer.toString(i)); return i; } public String ask_string(String kerdes) { ta.println(mostPlussz+" ?? "+kerdes); int i; String valasz=tf.xreadln(); ta.println(mostPlussz+" $$ "+valasz); return valasz; } public int ask(String kerdes, String valaszok) { return ask(kerdes, str_split('/', valaszok)); } private static final String ask_boolean_s[]={"nem","igen"}; public boolean ask_boolean(String kerdes) { return ask(kerdes, ask_boolean_s)==0?false:true; } Thread thread; public void run() { /* a szkeleton szál főfüggvénye, ez fut napestig this.thread()-ben */ ta.println("Ez a Kincskereső Kisgömböc szkeletonja."); ta.println("Felül látható a szekvenciadiagram, középen (itt) párbeszéd-mező, alulra pedig a válaszokat lehet írni."); ta.println("A választ a `??' megjelenése után kell beírni, majd Enter-t kell ütni."); ta.println("A szkeletonból az ablak bezárásával lehet kilépni."); // alapPlussz=honnanHivtak(2).length+1; alapPlussz=honnanHivtak(2).length+1; mostPlussz=""; tf.requestFocus(); skel_main(); tf.setText(""); ta.println("A szkeleton futása véget ért, a programból ki lehet lépni"); } protected SzekvenciaCanvas c; private JobbTextField tf; private JobbTextArea ta; public void initFont2() { if (font2==null) font2=new Font("sansserif",Font.PLAIN,12); // ^^^ ha nemlétező Font-ot kérünk, akkor próbál valamit helyettesíteni, // ami lehet, hogy nagyon vacak. Hát igen, a fontkezelést sem sikerült // megoldaniuk a Java AWT programozóinak. Különböző platformokon // teljesen másmilyen (és más méretű!) betűk jelennek meg. Azt meg, hogy // a .class-hoz a programozó mellékeli a neki tetsző betűtípust, nem // lehet megoldani. Miért is lehetne??... } public void init() { // Imp: Csak egy egyszerű egymás alá pakolást akarok, fix szélességgel. // hát olyan nagy kérés ez?? skel=this; setSize(620,440); initFont2(); // hejho(); int width=this.getPreferredSize().width; // setBackground(Color.blue); this.setLayout(new GridBagLayout()); GridBagConstraints gc=new GridBagConstraints(); gc.gridx=0; gc.gridy=0; gc.gridwidth=1; gc.gridheight=1; // GridBagConstraints.REMAINDER; gc.weighty=2; gc.weightx=1; gc.fill=GridBagConstraints.BOTH; // GridBagConstraints.NONE; gc.anchor=GridBagConstraints.NORTH; if (c==null) { c=new SzekvenciaCanvas(); c.setBackground(Color.red); } c.setFont2(this.font2); // c=new KkkgSzekvenciaCanvas(font2); // c.setSize(width,20); // muszáj, mert különben 0 lesz. Ez ilyen buta // c=new OkosCanvas(); c.setBackground(Color.red); ta=new JobbTextArea(); ta.setColumns(1); ta.setRows(1); // 0-t nem szereti ta.setBackground(Color.pink); // :-) ta.setFont(font2); ta.addFocusListener(new FocusAdapter() { public void focusGained(FocusEvent e) { ta.transferFocus(); } }); // ^^^ csak így tudjuk kikapcsolni a Tab-bejárást a komponensre. ta.setEditable(false); // azért a bill. fókuszt megkaphatja // ta.disableEvents(AWTEvent.FOCUS_EVENT_MASK); // ^^^ protected :-(( // ta.setEnabled(false); // ^^^ ez használhatatlan, mert elrondítja az egészet, és scrollozni sem // lehet ta.setText(""); // ta.setText("próba\nalma\n1\n2\n\3\n4\n5\n6\n7\n8\n9\nnegyvenkettő\n"); ta.setCaretPosition2(Integer.MAX_VALUE); tf=new JobbTextField(ta); //tf.addKeyListener(new KeyAdapter() { // public void keyTyped(KeyEvent e) { // char c=e.getKeyChar(); // if (c=='\n' || c=='\r') ta.setCaretPosition2(Integer.MAX_VALUE); // } //}); // tf.setSize(width,300); // hatástalan add(c,gc); gc.weighty=1; gc.gridy=1; // GridBagConstraints.RELATIVE; add(ta,gc); // ta.setCaretPosition(Integer.MAX_VALUE); gc.weighty=0; gc.gridy=2; // GridBagConstraints.RELATIVE; add(tf,gc); thread=new Thread(this); } public void destroy() { // Imp: nem sokat segít..., xreadln még mindig nullpointer-t ad vissza if (thread.isAlive()) { thread.interrupt(); } } public void stop() { // thread.stop(); -- deprecated // System.out.println("Stopp!"); } public void start() { if (!thread.isAlive()) thread.start(); } } /// class Skel