Sie sind auf Seite 1von 25


Vezi pe site-urile componente gata facute, look and feel-uri: are pe langa componente si un docking sistem(ferestre) cu visual editor propriu, e folosit de Oxygen XML. In Swing, events generated by the user interface are received by the JVM and stored in an event queue. Inside of the JVM, an event dispatch thread (implemented in the class java.awt.EventQueue) monitors this queue and dispatches incoming events to interested listeners. This is a typical example of the Observer pattern. Swing and concurrency (cauta tot felul de tipuri) Pagini unde exista widget-uri gata facute: Citeste si link-ul acesta la SwingTimers:

Swing Timers (Fires one or more ActionEvents at specified intervals (good in ANIMATION), a unique thread handles the firing of all timers and the timers are executed by the event dispatch thread => must be executed rapidly (else use SwingWorker).
A Swing timer (an instance of javax.swing.Timer) fires one or more action events after a specified delay. Use Swing timers rather than general-purpose timers for GUI-related tasks because Swing timers all share the same, pre-existing timer thread and the GUI-related task automatically executes on the event-dispatch thread!!!. However, you might use a general-purpose timer if you don't plan on touching the GUI from the timer, or need to perform lengthy processing. You can use Swing timers in two ways: To perform a task once, after a delay. Ex: the tool tip manager uses Swing timers to determine when to show/hide a tool tip. To perform a task repeatedly. Ex: perform animation or update a component that displays progress toward a goal. When you create the timer, you specify an action listener to be notified when the timer "goes off". The actionPerformed method in this listener should contain the code for whatever task you need to be performed. When you create the timer, you also specify the number of milliseconds between timer firings. If you want the timer to go off only once, you can invoke setRepeats(false) on the timer. To start the timer, call its start method. To suspend it, call stop. Although all Timers perform their waiting using a single, shared thread (created by the first Timer object that executes), the action event handlers for Timers execute on another thread -- the event-dispatching thread!!! This means that the task can safely manipulate components, but it also means that the task should execute quickly. If the task might take a while to execute, then consider using a SwingWorker instead of or in addition to the timer. An example use is an animation object that uses a Timer as the trigger for drawing its frames. Setting up a timer involves creating a Timer object, registering one or more action listeners on it, and starting the timer using the start method. For example, the following code creates and starts a timer that fires an action event once per second (as specified by the first argument to the Timer constructor). The second argument to the Timer constructor specifies a listener to receive the timer's action events.
int delay = 1000; //milliseconds. ActionListener taskPerformer = new ActionListener() { public void actionPerformed(ActionEvent evt) { //...Perform a task...

animator.repaint(); // In paintComponent(Graphics g) the corresponding sequence is painted. } }; new Timer(delay, taskPerformer).start();

Ex: Here is an animated applet, images must be relative to directory from where the class file of the applet is loaded, the images are loaded with a SwingWorker because this takes longer and they are put in ImageIcons, waiting between sequences is done with Timer:
/* * requires these files: all the images in the images/tumble directory (or, if specified * in the applet tag, another directory [dir] with images named T1.gif ... Tx.gif, where x is the total * number of images [nimgs]) the appropriate code to specify that the applet be executed such as the HTML * code in TumbleItem.html or TumbleItem.atag, or the JNLP code in TumbleItem.jnlp */ public class TumbleItem extends JApplet implements ActionListener { int loopslot = -1; //the current frame number String dir; //the directory relative to the codebase from which the images are loaded Timer timer; //the timer animating the images int pause; //the length of the pause between revs int offset; //how much to offset between loops int off; //the current offset int speed; //animation speed int nimgs; //number of images to animate int width; //width of the applet's content pane Animator animator; //the applet's content pane ImageIcon imgs[]; //the images int maxWidth; //width of widest image JLabel statusLabel; //Called by init. protected void loadAppletParameters() { //Get the applet parameters. String at = getParameter("img"); dir = (at != null) ? at : "images/tumble"; at = getParameter("pause"); pause = (at != null) ? Integer.valueOf(at).intValue() : 1900; at = getParameter("offset"); offset = (at != null) ? Integer.valueOf(at).intValue() : 0; at = getParameter("speed"); speed = (at != null) ? (1000 / Integer.valueOf(at).intValue()) : 100; at = getParameter("nimgs"); nimgs = (at != null) ? Integer.valueOf(at).intValue() : 3; at = getParameter("maxwidth"); maxWidth = (at != null) ? Integer.valueOf(at).intValue() : 0; } /** * Create the GUI. For thread safety, this method should * be invoked from the event-dispatching thread. */ private void createGUI() { //Animate from right to left if offset is negative. width = getSize().width; if (offset < 0) { off = width - maxWidth; } //Custom component to draw the current image //at a particular offset. animator = new Animator(); animator.setOpaque(true); animator.setBackground(Color.white); setContentPane(animator); // Setez content pane-ul la containerul jpanel-ului. //Put a "Loading Images..." label in the middle of the content pane. Center the label's text in //the applet, put it in the center part of a BorderLayout-controlled container, and center-align //the label's text. statusLabel = new JLabel("Loading Images...", JLabel.CENTER); animator.add(statusLabel, BorderLayout.CENTER); } //Background task for loading images. SwingWorker worker = new SwingWorker<ImageIcon[], Void>() { @Override public ImageIcon[] doInBackground() { final ImageIcon[] innerImgs = new ImageIcon[nimgs]; for (int i = 0; i < nimgs; i++) { innerImgs[i] = loadImage(i + 1); } return innerImgs; } @Override public void done() { //Remove the "Loading images" label. animator.removeAll(); loopslot = -1; try { imgs = get(); } catch (InterruptedException ignore) {} catch (java.util.concurrent.ExecutionException e) {

String why = null; Throwable cause = e.getCause(); if (cause != null) { why = cause.getMessage(); } else { why = e.getMessage(); } System.err.println("Error retrieving file: " + why); } } }; //Called when this applet is loaded into the browser. public void init() { loadAppletParameters(); //Execute a job on the event-dispatching thread: creating this applet's GUI. try { SwingUtilities.invokeAndWait(new Runnable() { public void run() { createGUI(); } }); } catch (Exception e) { System.err.println("createGUI didn't successfully complete"); } //Set up timer to drive animation events. timer = new Timer(speed, this); timer.setInitialDelay(pause); timer.start(); //Start loading the images in the background. worker.execute(); } //The component that actually presents the GUI. public class Animator extends JPanel { public Animator() { super(new BorderLayout()); } protected void paintComponent(Graphics g) { super.paintComponent(g); if (worker.isDone() && (loopslot > -1) && (loopslot < nimgs)) { if (imgs != null && imgs[loopslot] != null) { imgs[loopslot].paintIcon(this, g, off, 0); } } } } //Handle timer event. Update the loopslot (frame number) and the offset. If it's the last frame, restart the // timer to get a long pause between loops. public void actionPerformed(ActionEvent e) { //If still loading, can't animate. if (!worker.isDone()) { return; } loopslot++; if (loopslot >= nimgs) { loopslot = 0; off += offset; if (off < 0) { off = width - maxWidth; } else if (off + maxWidth > width) { off = 0; } } animator.repaint(); if (loopslot == nimgs - 1) { timer.restart(); } } public void start() { if (worker.isDone() && (nimgs > 1)) { timer.restart(); } } public void stop() { timer.stop(); } /** * Load the image for the specified frame of animation. Since this runs as an applet, we use getResourceAsStream * for efficiency and so it'll work in older versions of Java Plug-in. */ protected ImageIcon loadImage(int imageNum) {

String path = dir + "/images" + imageNum + ".gif"; int MAX_IMAGE_SIZE = 2400; //Change this to the size of //your biggest image, in bytes. int count = 0; BufferedInputStream imgStream = new BufferedInputStream(this.getClass().getResourceAsStream(path)); if (imgStream != null) { byte buf[] = new byte[MAX_IMAGE_SIZE]; try { count =; imgStream.close(); } catch ( ioe) { System.err.println("Couldn't read stream from file: " + path); return null; } if (count <= 0) { System.err.println("Empty file: " + path); return null; } return new ImageIcon(Toolkit.getDefaultToolkit().createImage(buf)); } else { System.err.println("Couldn't find file: " + path); return null; }

public String getAppletInfo() { return "Title: TumbleItem v1.2, 23 Jul 1997\n"; } public String[][] getParameterInfo() { String[][] info = { {"img", "string", "the directory containing the images to loop"}, {"pause", "int", "pause between complete loops; default is 3900"}, {"offset", "int", "offset of each image to simulate left (-) or " + "right (+) motion; default is 0 (no motion)"}, {"speed", "int", "the speed at which the frames are looped; " + "default is 100"}, {"nimgs", "int", "the number of images to be looped; default is 16"}, {"maxwidth", "int", "the maximum width of any image in the loop; " + "default is 0"} }; return info; } }

Execute applet as application in one program:

public class JocApplet extends JApplet { //Applet constructor. public JocApplet() { //this.setContentPane(new RollDicePanel()); } public void init() { setContentPane(new JocFrame2().getContentPane()); } /** * Metoda main. Putem rula fie ca aplicatie fie ca applet dintr-un browser web(sau cu java sun.applet.AppletViewer myApplet.html). * @param args */ public static void main(String[] args) { //JocFrame jf = new JocFrame(); JocFrame2 jf = new JocFrame2(); jf.setTitle("Joc echitabil sau nu?"); JocApplet jocApplet = new JocApplet(); jf.getContentPane().add(jocApplet); jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); jf.pack(); jf.setVisible(true); } }

Vezi clasa SwingWorker.

SwingUtilities.invokeLater(new Runnable(){ public void run(){ repaint(); } });

Vezi ca exista in clasa UIManager default-urile de look and feel pentru background, foreground, font pentru toate componentele Swing asa ca le poti modifica aici pt a crea un LF minimal. Exista un LF nou numit Synth LF care permite definirea LF in fisiere XML. De cele mai multe ori se implementeaza un LF custom prin suprascrierea claselor BasicWidgetUI corespunzatoare.

The Graphics class plays two different but related roles within the abstract windowing toolkit (AWT). First, it maintains the graphics context, which consists of all of the information that will affect the outcome of a graphics operation. This includes the drawing color, the font, and the location and dimensions of the clipping rectangle (the region in which graphics can be drawn). More importantly, the graphics context defines the destination for the graphics operations about to be discussed (destinations include components and images). In addition to its role as the graphics context, the Graphics class provides methods for drawing simple geometric shapes, text, and images to the graphics destination. All of the graphics-related operations on a component or image occur via one of these methods. In order to draw, a program requires a valid graphics context (represented by an instance of the Graphics class). Because the Graphics class is an abstract base class, it cannot be instantiated directly. An instance typically is created by a component, and then handed to the program as an argument to a component's update() and paint() methods. These two methods are called as part of the normal drawing cycle initiated within the AWT.
Nu uita ca decat sa faci un LF from scratch ai putea mai simplu sa obtii default-urile still-ului default: UIDefaults table = UIManager.getDefaults(); iar apoi sa le schimbi ex: table.put("Button.font", font); Poti avea astfel aceste chei intr-un fisier properties si astfel LF este usor configurabil fara recompilarea codului. O alta varianta ar fi folosirea synth LF thin Java care fol XML. ____________________________________

Java provides a small number of predefined "virtual" font names and maps them to real fonts available on the host. In JDK 1.0, each Java font name mapped to exactly one host font. In JDK 1.1, a Java font name can map to a series of host fonts. The series of host fonts can be chosen to cover as much of the Unicode character set as is desired.

Text placement
Because text is just another kind of figure to the AWT, a line of text can be placed anywhere -- even on top of another line of text. The effect of haphazard placement, however, will not necessarily be pleasing to the eye. In order to assist the programmer in producing aesthetically pleasing text, a font definition includes guidelines for line and character placement. These guidelines, if followed, will help produce pleasing output. Figure 4 contains a line of text that has been marked up to indicate the characteristics that we are about to discuss.

Figure 4: A line of text The y coordinate parameter in the methods in the previous section specifies the location of the baseline of a line of text. The baseline is the line upon which most of the characters in a line of text rest (the exception being those characters with descenders such as "g" and "y"). The baseline isn't really a characteristic of a font but is the reference point to which all of the other characteristics refer. The ascent is the distance from the baseline to the top of most of the characters in a font. This typically is the height of the capital letters in the font and of characters like "f" and "h". This figure is only a guideline, however. Some characters in the font may actually extend above this distance. The descent is the distance from the baseline to the bottom of the characters in a font that have descenders -- characters like "p", "g", and "y". As with ascent, this figure is only a guideline. Some characters in the font may actually extend below this distance.

The leading (pronounced "ledding") is the amount of space between the descent of one line of text and the ascent of the line below it. The height of a line of text (the distance from the baseline of one line of text to the baseline of a line of text above or below it) includes this extra space. In addition to the characteristics governing a font as a whole, each character in a font has an advance. The advance specifies how many pixels separate the beginning of the character from the beginning of a character to its right; in short, it is a character's width. Once again, some characters in a font may actually extend beyond this distance. By adding up the widths of all of the characters in a line of text, the length of the entire line of text can be calculated. The FontMetrics class below provides a method that does just this, and more.
fontMetrics.getDescent() = 3 (in rosu) fontMetrics.getAscent() = 13 (in galben) fontMetrics.getLeading() = 2 (in albastru) fontMetrics.getHeight() = 18 (suma celor 3 de mai sus)

BreakIterator The BreakIterator class implements methods for finding the location of boundaries in text. Actual line breaking needs to also consider the available line width and is handled by higher-level software(deci locul unde decid unde sa fie spart e ales de noi, pentru GUI se foloseste clasa Utilities din pachetul javax.swing.text). Foloseste MediaTracker ca sa-ti asiguri faptul ca o imagine e incarcata. Cand creezi un obiect Image asta nu asigura faptul ca imaginea s-a incarcat, de aceea folosesti: if ( myImage != null ) { MediaTracker tracker=new MediaTracker(this); tracker.addImage(mTitleImage,0); tracker.waitForAll(); }

______________________________________________________________________________ import java.applet.Applet; import java.awt.Graphics; class Appletul_meu extends Applet { public void paint(Graphics g) { g.drawString("Salut cam asa arata h3",10,10); } } testare.html: <html> <head> <title> Salut </title> </head> <body bgcolor=beige>

<h3> Iata:</h3> <applet code=Appletul_meu.class width=300 height=300> </applet> </body> </html> Un applet este o aplicatie Java ce se executa in contextul unui browser,se creaza un fisier html care se conecteaza prin tagul applet de programul Java obtinut dupa compilare. Conditii(altfel da eroare): 1)fisierul contine o clasa publica cu numele identic cu numele fisierului si sa fie derivata din clasa Applet 2)sa contina o metoda publica paint care este prima metoda apelata de browser pentru afisarea appletului,sau una din metodele init() sau start() ______________________________________________________________________________________________

Performance & Optimizations

Avoid excessive object instantiations. While newer Java VMs more effectively reduce the performance impact of creating many small objects, the fact remains that object creation is still an expensive operation. Since strings are immutable, the String class is one of the biggest offenders; every time a String is modified, one or more new objects is created.
A memory leak is where an unreferenced object that will never be used again still hangs around in memory. since Java automatically garbage collects unreferenced objects. packratting Sometimes called loitering or object leaks. Holding references to Objects long after the practical life of the Object has passed. This is a form of memory leak, though calling it a true memory leak would be like blaming the garbage man because your Mom wrote "DO NOT DISCARD" on all the bundles of junk in her attic. In Java, true memory leaks are theoretically impossible (unless you use JNI or your JVM is buggy), though packratting is common. In fact it is almost impossible to write a program that nullifies references to every object the instant it will never be needed again. So every program is guilty of minor packratting. Java talks to the underlying GUI which is typically written in C++ which does not have automatic garbage collection. Therefore you see workarounds in Java dispose methods, to help it along. If you fail to use dispose properly, Java wont run out of RAM, but the GUI will. Failing to use dispose create true memory leaks. Here are some common packratting situations: There is a gray area where Listeners wont be garbage collected unless you detach them manually before using dispose. So call dispose on each JFrame once you have finished with it. Setting the frame invisible with with setVisible( false ) does not make the Frame (and everything contained in it) eligible for gc. There are many ways to close a Frame. Call dispose on any Graphics objects that you create programmatically. Failing to do so will gradually fill memory with peer junk. The underlying OS GUI does not have an automatic garbage collection system. Just as you must manually close files, you must manually dispose Graphic objects. Call flush on Images after you have finished with them to free up their associated peer contents before dropping the reference. Threads are huge objects. Make sure you nullify pointers to them after you no longer need them. You cant reuse them for anything after they stop so you might as well nullify the references as soon as possible, even before they stop. Make sure you properly terminate threads or you will fill up RAM with moribund Threads. If you create a Thread and fail to start it, it will not be eligible for garbage collection, even if your app drops all references to it. It stays alive through a reference in the parent ThreadGroup. This is fixed in JDK 1.5+. But as a general principle, dont create Threads until you are ready to start them. In Swing make sure you use JFrame. setDefaultCloseOperation ( JFrame. DISPOSE_ON_CLOSE ); instead of the default JFrame.setDefaultCloseOperation ( JFrame.HIDE_ON_CLOSE ); otherwise, when a user closes a window, the frames are just hidden. You dont recover the resources. Use JFrame. setDefaultCloseOperation ( JFrame. DO_NOTHING_ON_CLOSE ); when you have a WindowListener. windowClosing method. To permanently close a frame programmatically, use
frame.setVisible( false ); frame.dispose();

frame = null;

Strength reduction Strength reduction occurs when an operation is replaced by an equivalent operation that executes faster. The most common example of strength reduction is using the shift operator to multiply and divide integers by a power of 2. For example, x >> 2 can be used in place of x / 4, and x << 1 replaces x * 2. Common sub expression elimination Common sub expression elimination removes redundant calculations. Instead of writing
double x = d * (lim / max) * sx; double y = d * (lim / max) * sy;

the common sub expression is calculated once and used for both calculations:
double depth = d * (lim / max); double x = depth * sx; double y = depth * sy;

Scaderea numarului de pasi ale unui loop sau efectuarea a cat mai multe calcule per ciclu.
javac, JITs, and native code compilers The level of optimization that javac performs when compiling code at this point is minimal. It defaults to doing the following: Constant folding -- the compiler resolves any constant expressions such that i = (10 *10) compiles to i = 100. Branch folding (most of the time) -- unnecessary goto bytecodes are avoided. Limited dead code elimination -- no code is produced for statements like if(false) i = 1. Then there are just-in-time (JIT) compilers that convert Java bytecodes into native code at run time. Several are already available, and while they can increase the execution speed of your program dramatically, the level of optimization they can perform is constrained because optimization occurs at run time. A JIT compiler is more concerned with generating the code quickly than with generating the quickest code. javac does offer one performance option you can enable: invoking the -O option to cause the compiler to inline certain method calls:
javac -O MyClass

Inlining a method call inserts the code for the method directly into the code making the method call. This eliminates the overhead of the method call. For a small method this overhead can represent a significant percentage of its execution time. Note that only methods declared as either private, static, or final can be considered for inlining, because only these methods are statically resolved by the compiler. Also, synchronized methods won't be inlined. The compiler will only inline small methods typically consisting of only one or two lines of code.
class A { private static int x = 10; public static void getX () { return x; } } class B { int y = A.getX(); }

the call to A.getX() in class B will get inlined in class B as if B had been written as:
class B { int y = A.x; }

However, this will cause the generation of bytecodes to access the private A.x variable that will be generated in B's code. This code will execute fine, but since it violates Java's access restrictions, it will get flagged by the verifier with an IllegalAccessError the first time the code is executed. This bug doesn't make the -O option useless, but you do have to be careful about how you use it. If invoked on a single class, it can inline certain method calls within the class without risk. Several classes can be inlined together as long as there aren't any potential access restrictions. And some code (such as applications) isn't subjected to the bytecode verifier. You can ignore the bug if you know your code will only execute without being subjected to the verifier.

Fortunately, the JDK comes with a built-in profiler to help identify where time is spent in a program. It will keep track of the time spent in each routine and write the information to the file To run the profiler, use the -prof option when invoking the Java interpreter:
java -prof myClass

Or for use with an applet:

java -prof sun.applet.AppletViewer myApplet.html

There are a few caveats for using the profiler. The profiler output is not particularly easy to decipher. It is also possible to "profile" code by inserting explicit timing into the code:
long start = System.currentTimeMillis(); // do operation to be timed here long time = System.currentTimeMillis() - start;

The next best option is to convert method and especially interface invocations to static, private, or final calls. If you have methods in your class that don't make use of instance variables or call other instance methods, they can be declared static. If a method doesn't need to be overridden, it can be declared final. And methods that shouldn't be called from outside the class should always be declared private anyway. By far the most expensive type of call in Java is to a synchronized method. Not only does the overhead of calling a synchronized method dramatically increase the calling time, especially with a JIT compiler, but there is always the potential that the call will be delayed waiting for the monitor for the object. And when the method returns, the monitor must be released, which takes more time. Because of the way a synchronized method is invoked, it is slightly faster to call a synchronized method than to enter a synchronized block. Also, a call to a synchronized method when the monitor is already owned by the thread executes somewhat faster than the synchronized method when the monitor isn't owned. So for the four combinations of these you get:
class Test { static int x;

void test () { meth1(); meth2(); synchronized (this) { meth1(); meth2(); } }

// slowest // fastest

synchronized void meth1 () { x = 1; } void meth2 () { synchronized (this) { x = 1; } } }

Of course, these timings don't include the time it took to enter the synchronized block inside test(). If you have a heavily synchronized class that is calling lots of synchronized methods from other synchronized methods, you may want to consider having synchronized methods delegate the work to private non-synchronized methods to avoid the overhead of reacquiring the monitor.
class X { public synchronized void setStuff (int i) { doSetStuff(); } private doSetStuff () { // setStuff code goes here }

synchronized void doLotsOfStuff () { doSetStuff(); // instead of calling setStuff() // do more stuff... } }

If Swing is the problem, you might consider redoing the GUI in IBMs SWT. file:///C:/My%20Web %20Sites/http___java.sun.com_docs_books_tutorial_java_index.html/

Both Java and C# have strong and weak object references. Java allows registering a listener that will be notified when a reference is garbage collected, which allows for the good performance of the WeakHashMap that C# lacks. Si cel mai tare site cu performance tips:

__________________ First time java is run the JVM is loaded into memory, thats what making java slow. If you start you program, then close it and then start in another time, is it slow then? In that case, it probably has something to do with the application. c# is faster since it compiles the byte code into native code the first time a program is run. The native code is saved in a cache and reused everytime the program is started. c# runtime is also loaded into memory when windows starts making startup speed alot faster. On my PC a notepad written in java takes 3-4 seconds to load the first time and the second time it takes less then 2 seconds. joegoodman Posts:2 Registered: 3/17/04 Re: Java swing desktop apps SLOW Mar 17, 2004 10:47 AM (reply 3 of 45)

First of all I develop applications in Java and love it. I can run the notepad demo on a 3Ghz Intel with 1GB RAM with almost no delay. Most of the Java applications we have developed perform very well. The great thing about Java is that it is easier to develop and maintain applications than in C++. I know this because I developed C++ GUI applications for serveral years. Swing makes GUI application development much easier to do and Java is much more robust as far as error handling goes. With C++ you often encounter "voodoo magic" errors, such as resource leaks, that kill your whole system, but not with Java. The worst case is you get an exception that tells you exactly where the error is located. Deadlocks are easy to find too, just hit ctrl-break and it tells you the exact lines of code that the application is deadlocked on. Java will almost always be a tad bit slower than C++ because of Java being interpreted. I believe that the Sun JRE does compile some of the code to native code at runtime but not all of it. I wish that Sun would take a hint from C# and compile as much of the code as possible during the first execution of the program or simply have a compiler option that would generate some native code. It seems that speed is everybodies biggest gripe about Java. Sun really should face this complaint head-on. Maybe there is something we could do through the JCP to make this happen?

Java will almost always be a tad bit slower than C++ because of Java being interpreted. I believe that the Sun JRE does compile some of the code to native code at runtime but not all of it. I wish that Sun would take a hint from C# and compile as much of the code as possible during the first execution of the program or simply have a compiler option that would generate some native code.

Use the native filechooser instead of JFileChooser, and check out SwingWT ( which can be compiled to native code (Win32/Linux).

One BIG improvement that JDK 1.5 will bring is similar to what .NET does, and that is to "image" a big portion of its library and load it into memory directly, rather than creating 1000's of objects as it loads the runtime. I think it will also do this with individual applications loaded, in that it will save parts of applications as memory dumped images, so upon restoring the app, it will load faster. After Java 1.4, Swing Slow really means the screens do not paint completely because painting is not completing due to a long task running in the event handler thread. I myself had quite a few cases where I could see a hole in the middle of the screen, or where a screen will freeze. In all cases, I fixed it by simply removing the long running tasks out of the event handler.

Java example
Here is an example that takes keyboard input and treats each input line as an event. The example is built upon the library classes java.util.Observer and java.util.Observable. When a string is supplied from, the method notifyObserver is then called, in order to notify all observers of the event's occurrence, in the form of an invocation of their 'update' methods - in our example, ResponseHandler.update(...). The file contains a main() method that might be used in order to run the code.
/* File Name : */ package OBS; import java.util.Observable; import; //Observable is here

import; import; public class EventSource extends Observable implements Runnable { public void run() { try { final InputStreamReader isr = new InputStreamReader( ); final BufferedReader br = new BufferedReader( isr ); while( true ) { final String response = br.readLine(); setChanged(); notifyObservers( response ); } } catch (IOException e) { e.printStackTrace(); } } } /* File Name: */ package OBS; import java.util.Observable; import java.util.Observer; /* this is Event Handler */ public class ResponseHandler implements Observer { private String resp; public void update (Observable obj, Object arg) { if (arg instanceof String) { resp = (String) arg; System.out.println("\nReceived Response: "+ resp ); } } } /* Filename : */ /* This is main program */ package OBS; public class myapp { public static void main(String args[]) { System.out.println("Enter Text >"); // create an event source - reads from stdin final EventSource evSrc = new EventSource(); // create an observer final ResponseHandler respHandler = new ResponseHandler(); // subscribe the observer to the event source evSrc.addObserver( respHandler ); // run the program; } }

[edit] Implementations
The observer pattern is implemented in numerous programming libraries and systems, including almost all GUI toolkits. Some of the most notable implementations of this pattern: The Java Swing library makes extensive use of the observer pattern for event management

import import import import import

java.awt.*; java.awt.event.*;*;*; javax.swing.*;

public class TicTacToeServer extends JFrame { private private private private private private byte board[]; boolean xMove; JTextArea output; Player players[]; ServerSocket server; int currentPlayer;

public TicTacToeServer() { super( "Tic-Tac-Toe Server" ); board = new byte[ 9 ]; xMove = true; players = new Player[ 2 ]; currentPlayer = 0; // set up ServerSocket try { server = new ServerSocket( 5000, 2 ); } catch( IOException e ) { e.printStackTrace(); System.exit( 1 ); } output = new JTextArea(); getContentPane().add( output, BorderLayout.CENTER ); output.setText( "Server awaiting connections\n" ); setSize( 300, 300 ); show(); } // wait for two connections so game can be played public void execute() { for ( int i = 0; i < players.length; i++ ) { try { players[ i ] = new Player( server.accept(), this, i ); players[ i ].start(); } catch( IOException e ) { e.printStackTrace(); System.exit( 1 ); } } // Player X is suspended until Player O connects. // Resume player X now. synchronized ( players[ 0 ] ) { players[ 0 ].threadSuspended = false; players[ 0 ].notify(); } } public void display( String s ) { output.append( s + "\n" );

} // Determine if a move is valid. // This method is synchronized because only one move can be // made at a time. public synchronized boolean validMove( int loc, int player ) { boolean moveDone = false; while ( player != currentPlayer ) { try { wait(); } catch( InterruptedException e ) { e.printStackTrace(); } } if ( !isOccupied( loc ) ) { board[ loc ] = (byte) ( currentPlayer == 0 ? 'X' : 'O' ); currentPlayer = ( currentPlayer + 1 ) % 2; players[ currentPlayer ].otherPlayerMoved( loc ); notify(); // tell waiting player to continue return true; } else return false; } public boolean isOccupied( int loc ) { if ( board[ loc ] == 'X' || board [ loc ] == 'O' ) return true; else return false; } public boolean gameOver() { // Place code here to test for a winner of the game return false; } public static void main( String args[] ) { TicTacToeServer game = new TicTacToeServer(); game.addWindowListener( new WindowAdapter() { public void windowClosing( WindowEvent e ) { System.exit( 0 ); } } ); game.execute(); } } // Player class to manage each Player as a thread class Player extends Thread { private Socket connection; private DataInputStream input; private DataOutputStream output; private TicTacToeServer control; private int number; private char mark; protected boolean threadSuspended = true; public Player( Socket s, TicTacToeServer t, int num ) { mark = ( num == 0 ? 'X' : 'O' );

connection = s; try { input = new DataInputStream( connection.getInputStream() ); output = new DataOutputStream( connection.getOutputStream() ); } catch( IOException e ) { e.printStackTrace(); System.exit( 1 ); } control = t; number = num; } public void otherPlayerMoved( int loc ) { try { output.writeUTF( "Opponent moved" ); output.writeInt( loc ); } catch ( IOException e ) { e.printStackTrace(); } } public void run() { boolean done = false; try { control.display( "Player " + ( number == 0 ? 'X' : 'O' ) + " connected" ); output.writeChar( mark ); output.writeUTF( "Player " + ( number == 0 ? "X connected\n" : "O connected, please wait\n" ) ); // wait for another player to arrive if ( mark == 'X' ) { output.writeUTF( "Waiting for another player" ); try { synchronized( this ) { while ( threadSuspended ) wait(); } } catch ( InterruptedException e ) { e.printStackTrace(); } output.writeUTF( "Other player connected. Your move." ); } // Play game while ( !done ) { int location = input.readInt(); if ( control.validMove( location, number ) ) { control.display( "loc: " + location ); output.writeUTF( "Valid move." ); } else output.writeUTF( "Invalid move, try again" ); if ( control.gameOver() ) done = true; } connection.close(); } catch( IOException e ) { e.printStackTrace();

System.exit( 1 ); } } } // Client for the TicTacToe program import java.awt.*; import java.awt.event.*; import*; import*; import javax.swing.*; // Client class to let a user play Tic-Tac-Toe with // another user across a network. public class TicTacToeClient extends JApplet implements Runnable { private JTextField id; private JTextArea display; private JPanel boardPanel, panel2; private Square board[][], currentSquare; private Socket connection; private DataInputStream input; private DataOutputStream output; private Thread outputThread; private char myMark; private boolean myTurn; // Set up user-interface and board public void init() { display = new JTextArea( 4, 30 ); display.setEditable( false ); getContentPane().add( new JScrollPane( display ), BorderLayout.SOUTH ); boardPanel = new JPanel(); GridLayout layout = new GridLayout( 3, 3, 0, 0 ); boardPanel.setLayout( layout ); board = new Square[ 3 ][ 3 ]; // When creating a Square, the location argument to the // constructor is a value from 0 to 8 indicating the // position of the Square on the board. Values 0, 1, // and 2 are the first row, values 3, 4, and 5 are the // second row. Values 6, 7, and 8 are the third row. for ( int row = 0; row < board.length; row++ ) { for ( int col = 0; col < board[ row ].length; col++ ) { board[ row ][ col ] = new Square( ' ', row * 3 + col ); board[ row ][ col ].addMouseListener( new SquareListener( this, board[ row ][ col ] ) ); boardPanel.add( board[ row ][ col ] ); } } id = new JTextField(); id.setEditable( false ); getContentPane().add( id, BorderLayout.NORTH ); panel2 = new JPanel(); panel2.add( boardPanel, BorderLayout.CENTER ); getContentPane().add( panel2, BorderLayout.CENTER ); } // Make connection to server and get associated streams. // Start separate thread to allow this applet to // continually update its output in text area display. public void start() {

try { connection = new Socket( InetAddress.getByName( "" ), 5000 ); input = new DataInputStream( connection.getInputStream() ); output = new DataOutputStream( connection.getOutputStream() ); } catch ( IOException e ) { e.printStackTrace(); } outputThread = new Thread( this ); outputThread.start(); } // Control thread that allows continuous update of the // text area display. public void run() { // First get player's mark (X or O) try { myMark = input.readChar(); id.setText( "You are player \"" + myMark + "\"" ); myTurn = ( myMark == 'X' ? true : false ); } catch ( IOException e ) { e.printStackTrace(); } // Receive messages sent to client while ( true ) { try { String s = input.readUTF(); processMessage( s ); } catch ( IOException e ) { e.printStackTrace(); } } } // Process messages sent to client public void processMessage( String s ) { if ( s.equals( "Valid move." ) ) { display.append( "Valid move, please wait.\n" ); currentSquare.setMark( myMark ); currentSquare.repaint(); } else if ( s.equals( "Invalid move, try again" ) ) { display.append( s + "\n" ); myTurn = true; } else if ( s.equals( "Opponent moved" ) ) { try { int loc = input.readInt(); board[ loc / 3 ][ loc % 3 ].setMark( ( myMark == 'X' ? 'O' : 'X' ) ); board[ loc / 3 ][ loc % 3 ].repaint(); display.append( "Opponent moved. Your turn.\n" ); myTurn = true; } catch ( IOException e ) { e.printStackTrace(); } } else display.append( s + "\n" ); display.setCaretPosition( display.getText().length() );

} public void sendClickedSquare( int loc ) { if ( myTurn ) try { output.writeInt( loc ); myTurn = false; } catch ( IOException ie ) { ie.printStackTrace(); } } public void setCurrentSquare( Square s ) { currentSquare = s; } } // Maintains one square on the board class Square extends JPanel { private char mark; private int location; public Square( char m, int loc) { mark = m; location = loc; setSize ( 30, 30 ); setVisible(true); } public Dimension getPreferredSize() { return ( new Dimension( 30, 30 ) ); } public Dimension getMinimumSize() { return ( getPreferredSize() ); } public void setMark( char c ) { mark = c; } public int getSquareLocation() { return location; } public void paintComponent( Graphics g ) { super.paintComponent( g ); g.drawRect( 0, 0, 29, 29 ); g.drawString( String.valueOf( mark ), 11, 20 ); } } class SquareListener extends MouseAdapter { private TicTacToeClient applet; private Square square; public SquareListener( TicTacToeClient t, Square s ) { applet = t; square = s; } public void mouseReleased( MouseEvent e ) { applet.setCurrentSquare( square ); applet.sendClickedSquare( square.getSquareLocation() ); } }

APPLET as an application:

Cauta Swing tips pe,, etc.

Setarea LF curent existent pe sistemul de operare:

String laf = UIManager.getSystemLookAndFeelClassName(); try { UIManager.setLookAndFeel(laf); } catch (Exception e) { e.printStackTrace(); }


Logging API
The next code snippet logs where an exception occurred from within the catch block. However, rather than manually parsing the stack trace and sending the output to System.err(), it sends the output to a file using the logging facility in the java.util.logging package.
try { Handler handler = new FileHandler("OutFile.log"); Logger.getLogger("").addHandler(handler); } catch (IOException e) { Logger logger = Logger.getLogger(""); StackTraceElement elements[] = e.getStackTrace(); for (int i = 0, n = elements.length; i < n; i++) { logger.log(Level.WARNING, elements[i].getMethodName()); } }

Mai e pentru logging libraria de la Apache log4j : Vezi ca sunt intrebari si in tutorial la sfarsitul fiecarui capitol. Ar trebui sa le aduni toate aceste intrebari. Exista libraria Xstream care converteste obiectele in XML si le poti trimite pe reteas.

Adaugarea de listener la JtextField:

tf.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { JTextField textfield = (JTextField)evt.getSource(); System.out.println("apasat enter" + textfield.getText()); } }); tf.getDocument().addDocumentListener(new DocumentListener() { public void changedUpdate(DocumentEvent e) { } public void insertUpdate(DocumentEvent e) { } public void removeUpdate(DocumentEvent e) {

} });


Example: Breaking SwingUtilities.invokeAndWait()

is a popular utility method for executing a Runnable on the Abstract Windowing Toolkit (AWT) event thread. It is used when an application thread must update the graphical user interface (GUI) and obey all Swing threading rules. The documentation states that an uncaught exception from the will be caught and rethrown, wrapped in an InvocationTargetException. The implementation of this in Sun Microsystems' Java 2 Platform, Standard Edition (J2SE) 1.4.1 assumes, somewhat naively, that such uncaught exceptions can only be subclasses of java.lang.Exception. Here is an extract from java.awt.event.InvocationEvent used by SwingUtilities.invokeAndWait() behind the scenes:
javax.swing.SwingUtilities.invokeAndWait() public void dispatch() { if (catchExceptions) { try {; } catch (Exception e) { exception = e; } } else {; } if (notifier != null) { synchronized (notifier) { notifier.notifyAll(); } } }

The problem with this code is that if throws a Throwable, the catch block is not entered, and the notifier.notifyAll() line never executes. The calling application thread will then wait on a nonpublic lock object inside java.awt.EventQueue.invokeAndWait() that will never be signaled (lock.wait() will never execute):
public static void invokeAndWait(Runnable runnable) throws InterruptedException, InvocationTargetException { class AWTInvocationLock {} Object lock = new AWTInvocationLock(); InvocationEvent event = new InvocationEvent(Toolkit.getDefaultToolkit(), runnable, lock, true); synchronized (lock) { Toolkit.getEventQueue().postEvent(event); lock.wait(); } Exception eventException = event.getException(); if (eventException != null) { throw new InvocationTargetException(eventException); } }

_____________ Scoaterea se sunete: java.awt.Toolkit.getDefaultToolkit().beep(); _____________ La buffere pozitia actuala (deci poate fi folosita intr-u ciclu for) este data de position()
b.put((byte)7); b.put((byte)8); System.out.println(b.position()); b.rewind(); System.out.println(b.get()); System.out.println(b.get()); _______________ Atentie la GridBagLayout tot timpul il fortezi cu setminimumsize si setpreferedsize insa atentie sa se impace si cu celalte setprefered si setminimum fiindca altfel unele nu vor fi luate in considerare!!!


/** * @param args the command line arguments */ public static void main(String args[]) { java.awt.EventQueue.invokeLater(new Runnable() { public void run() { new CelsiusConverterGUI().setVisible(true); } }); }

/** * Create the GUI and show it. For thread safety, * this method should be invoked from the * event-dispatching thread. */ private static void createAndShowGUI() { //Create and set up the window. JFrame frame = new JFrame("CustomComboBoxDemo"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //Create and set up the content pane. JComponent newContentPane = new CustomComboBoxDemo(); newContentPane.setOpaque(true); //content panes must be opaque frame.setContentPane(newContentPane); //Display the window. frame.pack(); frame.setVisible(true);

public static void main(String[] args) { //Schedule a job for the event-dispatching thread: //creating and showing this application's GUI. javax.swing.SwingUtilities.invokeLater(new Runnable() { public void run() { createAndShowGUI(); } }); }

_________ Desenarea unei imagini de background pe un JPanel functia paint se modifica astfel: public void paint(final Graphics g) { if (mImage != null){ g.drawImage(mImage, 0, 0, null); // Mai intai imaginea. } super.paintChildren(g); // Atentie trebuie pictati doar copiii. } Sau cu metoda paintIcon din clasa ImageIcon. Deasemenea ImageIcon se poate incarca si cu SwingWorker vezi exemplul de la clasa Timer. Font stuff Setarea unui anumit font in cadrul unui anumit locale:
private static String getSpecialFont(String locale) { if ("ko".equalsIgnoreCase(locale)) { return "Batang"; }

return null; } public static void initCustomFonts() { // CUSTOM additions UIDefaults table = UIManager.getDefaults(); String fontName = getSpecialFont(ResourceUtility.getInstance().getPreferredLocale().getLanguage()); if (fontName != null) { FontUIResource font = new FontUIResource(new Font(fontName, Font.PLAIN, 11)); table.put("Button.font", font); table.put("CheckBox.font", font); } Daca nu se doreste setarea explicita a fontului din program atunci ea poate fi facuta din fisierul jre\lib\ care trebuie redenumit la si se configureaza corespunzator

Obtinerea tuturor fonturilor:

/ Get all available font faces names GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); Font[] fonts = ge.getAllFonts();

String[] fontNames = Toolkit.getDefaultToolkit().getFontList();

Fonturile au o functie cu care poti testa dc pot afisa un anume codepoint:

canDisplay(int codePoint)

Checks if this Font has a glyph for the specified character.

The java.text package provides collators to allow locale-sensitive ordering.

Ex: clasa Utilities ofera metoda de spargere a unui text: getBreakLocation ca sa intre intr-un anumit spatiu.

Class Desktop The Desktop class allows a Java application to launch associated applications registered on the native desktop to handle a URI or a file. Supported operations include: launching the user-default browser to show a specified URI; launching the user-default mail client with an optional mailto URI; launching a registered application to open, edit or print a specified file. This class provides methods corresponding to these operations. The methods look for the associated application registered on the current platform, and launch it to handle a URI or file. If there is no associated application or the associated application fails to be launched, an exception is thrown. An application is registered to a URI or file type; for example, the "sxi" file extension is typically registered to StarOffice. The mechanism of registereing, accessing, and launching the associated application is platform-dependent. Each operation is an action type represented by the Desktop.Action class. Note: when some action is invoked and the associated application is executed, it will be executed on the same system as the one on which the Java application was launched.
Nested Class Summary static class Desktop.Action Represents an action type.

Method Summary void browse(URI uri) Launches the default browser to display a URI. void edit(File file) Launches the associated editor application static Desktop getDesktop() Returns the Desktop instance of the current browser context.

and opens a file for editing.

static boolean isDesktopSupported() Tests whether this class is supported on the current platform. boolean isSupported(Desktop.Action action) Tests whether an action is supported on the current platform. void mail() Launches the mail composing window of the user default mail client. void mail(URI mailtoURI) Launches the mail composing window of the user default mail client, filling the message fields specified by a mailto: URI. void open(File file) Launches the associated application to open the file. void print(File file) Prints a file with the native desktop printing facility, using the associated application's print command.

Applet detecting which browser.

public void init() { if ( getAppletContext().toString().startsWith ( "netscape.applet.MozillaAppletContext" ) ) { environment = NETSCAPE_BROWSER; } else if ( getAppletContext().toString().startsWith ( "" ) ) { environment = MICROSOFT_BROWSER; } else if ( getAppletContext().toString().startsWith ( "sunw.hotjava.tags.TagAppletPanel" ) ) { environment = HOTJAVA_BROWSER; } else if ( getAppletContext().toString().startsWith ( "sun.applet.AppletViewer" ) ) { environment = APPLETVIEWER; } }

You can install the Java Plug-in 1.6.0_05 into IE as a side effect of installing the JDK or JRE. If you install the Plug-in into older versions of IE, you need weird OBJECT HTML to invoke Applets

It is possible for Java Applets to get out and peek at the web page document surrounding them in Java 1.4+. Another technique is to have JavaScript dynamically generate <applet <param tags. You can also have Java call JavaScript functions to let you get data from froms in insert data in forms.

La applet-uri ce ruleaza in broser cica unicul mod de a avea modal dialog boxes este de a cere parintele appletului: applet.getParent() si pt acesta se face dialog-ul. La un gridbag layout trebuie sa-i setezi la un panel care vrei sa aiba dimensiuni fixe trebuie sa setezi si minimum size cat si prefered size cu aceeasi valoare(pt ca la o redimensionare sa nu se "mareasca" dintr-odata la size-ul minim.

Tine minte ca daca maresti dimensiunile unei componente care este continuta de un container care face parte dintr-un layout s-ar putea ca dimensiunile layout-ului sa nu se schimbe pana cand nu apelezi functia revalidate() (nu merge cu validate()). Ex: am un label care afiseaza dintr-o data mai mult text si nu incape in panel. In acel moment preferedSize-ul panel-ului va fi mai mare decat size-ul sau actual iar in acel moment trebuie restabilit prefered si minim size-ul panel-ului care include panelul nostru si revalidat layout-ul.