14: The purpose of creating a window and applet is to "easily complete simple tasks, there is a way to complete complex tasks." [74]
When you originally designed Java 1.0's GUI class library, Sun's goal is to make programmers can make very beautiful interfaces under all platforms. But this goal has not been achieved. In contrast, the GUI made from Java 1.0 Abstract Window Toolkit (AWT) is so mediocre on all platforms. And its function is also very limited; only four fonts can not access the more complex GUI elements provided by the operating system. In addition, Java 1.0 AWT is very clumsy, non-objective programming mode. Once, a student in my class (in the Java start-up time, he did over SUN) explained to me: AWT from idea to design until finally a total of only one month. Although the efficiency is very high, the things made have become a reverse faculty who proof the importance of design.
The event model of Java 1.1 AWT has made the situation. It used the idea of more clear object-oriented solutions, which also introduced JavaBean. JavaBean is a Visual Programming Environment component programming mode for audio-programming environment. The Java Foundation Classes (JFC) of the final Java 2 (JDK 1.2) has replaced Java 1.0 AWT and completed this transformation. The GUI portion of the JFC is called "swing". This is a group of javabeans that are easy to use, can drag and drop (of course, handwritten code), can also be satisfactory with the GUI it creates. It seems that the "third edition" of the software industry (only the third edition, the product will mature) also applies to programming languages.
This chapter only introduces the Swing class library of Java 2, and reasonably assumes Swing is the development direction of the Java GUI class library. [75] If for some reason, you need to use "old" AWT (maybe you have to maintain the old code, or the browser has restrictions), you can go to www.bruceeckel.com to download the first edition of this book (CD- There is also ROM). Note that Java has retained some AWT components, sometimes you have to use them.
The beginning of this chapter will tell, use Swing Creating Applet what is different from creating applications, and how to create an application that can run in the browser in the browser, running the program in a normal application. Most of the GUI programs in the book can run this.
Please note that this book is neither a vocabulary of a Swing component, nor is it not prepared to explain these classes and their methods. So it is intentionally simplified. The Swing class library is huge, while the purpose of this chapter is just to let you start understanding and familiar with these concepts from the basics. If you have a higher request, you will probably do it as long as you are studying.
I assume that you have downloaded and installed the HTML document from Java.sun.com and install the JDK class library, and knows the details of the Swing class library in javax.swing classes. Swing has a simple structure, so in general, these materials are already enough to solve the problem. There are also countless (also is also a giant) Swing monograph. If you want to know deeper, or to modify Swing's default behavior, you can read this book.
The more you know Swing, the more you can experience:
Swing is a much better programming model compared to other languages or development environments. JavaBeans (where the end of this chapter will be introduced) is a class library designed for this architecture. For the entire Java development environment, the "GUI BUILDERS" (visual programming environment) is just a "social" level. When you put the components on the form with a graphics tool, it is actually the GUI Builder to write code for you to call JavaBeans and Swing. This can not only speed up the development speed of GUI, but also make you more experiments. This way you can try more solutions to get better results. Swing is easy to use and designed to make you get readable code even with GUI Builder. This solves an old problem of GUI Builder, which is the readability of the code. Swing includes all of the more trendy user interface elements: there should be all from the image of the image to the tree control and table control. Considering the size of the class library, its complexity is still ideal. If something is simple, the code will not be a lot, if the project is complicated, the code will become complicated accordingly. That is to say, it is easy to get started, but it can also become very powerful if necessary. Good feelings of swing are largely stem from its "orthogonality". In other words, once you understand the spirit of this class library, you can apply this concept to anywhere. This first is the naming specification of its standard. When writing this chapter, I often rely on the name of the way, and often guess, so I can save the file. Obviously, this is a characteristic of a well-designed class library. In addition, usually, if you want to nest the components in other components, you can insert it directly.
To take care of the running speed, the components are "lightweight". In order to cross the platform, Swing is written in Java.
Keyboard support is built-in; you can do not need to use your mouse when running Swing applications. This is not required. Plus rolling bars, it is easy, just embed the control directly to JScrollpane. Plus Tooltip is also as long as one line of code.
Swing also provides a more avant-garde, called "Pluggable Look and Feel" functionality, that is, the appearance of the user interface can dynamically change according to the habit of the operating system or user. You can even invent a set of appearance (of course hard).
Basic AppletJava creates Applets, which is a small program that can run in a web browser. Applet must be safe, so its function is limited. But Applet is a very powerful client programming tool, while the latter is a big topic for web development.
The restriction of Applet is much limited, so it is often referred to as "sandbox". Because there is always a person at time - just Java's runtime safety system - monitoring you.
However, you can also go out of the sandbox, write ordinary applications instead of applet, so you can access other features of the operating system. So far, we write this application, but they are all consistent processes without a graphical interface. Swing can also write the GUI interface application.
In general, if you want to know what applet can do, it is best to go to understand why there is applet: use it to extend the functionality of the web page in your browser. Because the people on the Internet can't really know that this page is from a malicious website, but you must ensure that all running code is safe. So you will find that its biggest limit is:
Applets cannot access local disks. That is to say, you can't read it, because you will never want Applet to read your private information without agreed, then pass it through the Internet. Of course, write is also banned, otherwise it is to open the door to welcome the virus. Java provides a digital signature for Applet. You can choose the applet that has a digital signature (signed by the trusted developer) accesses your hard drive, so that the applet has been released. At the back of this chapter, it will be introduced to the Java Web Start. Web Start is a scheme that securely delivers applications to the client via the Internet. Applet has a long start time, because everything has to be downloaded every time, and every time you download a class to send a request. Perhaps the browser will cache, but this is not certain. So you must put all components of the applet into a JAR (in addition to the .class file, including image, sound), so you can download the entire applet as long as you send a request. Things in JAR volumes can be "digital signature" one item by item. " The advantage of Applet If you don't care about these restrictions, Applet still has obvious advantages, especially when building Client / Server or other web applications: there is no problem with installation. Applet is a true platform-independent (including playing audio file), so you don't need to modify the program for different platforms, users don't need to be installed after installation. In fact, each time there is an Applet's web page, the installation is automatically completed. Therefore, the update of the software can not be alarmatically completed automatically. Build and install a new version of software for traditional Client / Server systems, usually a nightmare. Since the Java language and Applet have a built-in security mechanism, you don't have to worry about the error code will destroy someone else's machine. With these two advantages, Java can develop in the Intranet's Client / Server application. The so-called Intranet's Client / Server application refers to the CLIENT / Server application that exists within the company, or can define and control the user environment (web browser and plug-in) special occasions. Since the applet is automatically integrated into HTML, you have a document system that is not related to the platform, which supports the applet (the translator Note: refers to HTML). This is really interesting, because we usually think that the document is part of the program, not the opposite.
Application Framework Class libraries are usually classified according to functions. Some libraries are used directly, such as string and arraylist in the Java standard class library. Some class libraries are used to create other classes. There is also a class library called Application Framework. Its purpose is to provide a class with some basic functions to help programmers create an application. These basic functions are necessary for such applications. So when you write an application, just inherit this class, then write a few ways you are interested in as needed, customize its behavior. The default control mechanism of the application frame will call those methods you write in the appropriate timing. The application framework is a substrateful example of "will change and unchanging." Its design idea is to leave the personalized part of the program in the local area through overwriting methods. [76]
Applet is created with an application framework. You only need to inherit the Japplet class, and then overwrite several methods. The following methods can control the creation and execution of Applets on the web page:
Method Operation INIT () Applet is automatically called when the task includes the layout of the load assembly. Must override. Start () calls when the applet is displayed on a web browser. After the display is complete, Applet has started working properly, especially those with STOP () shut down). (In addition, the application framework) is called after init () will also call this method. STOP () lets Applet call from the web browser disappeared so that it will turn off some resource operations. This method will be called before () before (Application Framework Call) DESTROY (). DESTROY () When (browser) no longer needs this applet, this method will be called to release resources when uninstalling it from the page. After you know these, you can write a simple applet:
//: c14: applet1.java// Very Simple Applet.Import javax.swing. *; import java.awt. *; public class applet1 extends japplet {public void init () {getContentPane (). Add (new jlabel. Applet! "));}} ///: ~ Note that Applet does not require main (). It has been included in the application frame; you just put the boot code in init ().
This program only has a thing, just put a text label into the applet (AWT has given the name of Label and other components, so SWING components usually take "J"). The constructor of the JLabel requires a string as a parameter. In this program, the label is placed on the form.
The init () method is responsible for the component add () to the form. Maybe you will feel that it should be able to call the add () method of its own (JAPPLET). In fact, AWT is doing this. Swing requires that all components are added to the "Content Pane" ", so getContentPane () must be called before add ().
Run Applet in a web browser To run the program, first you have to put the applet into the web page, then open the page with a web browser that runs Java. You have to use a special tag [77] to put the applet in the web page, then let it tell the page how to load and run this applet.
This step was very simple. At that time, Java was very simple, everyone used the same Java, Java in the browser. So just change HTML a little, just like this:
For Internet Explorer, this extension mechanism is ActiveX control, and Netscape is Plugin. When you do the page, you must write a set of tags for these two browsers, but JDK comes with an HTMLConverter tool that automatically generates tags. Below is the HTML page of Applet1 processed by HTMLConverter:
You can add any multiple parameters as needed.
This book source code (www.bruceeckel.com provides free download) an HTML page for each applet, and there is also a number of examples of how to use the Applet tag. These pages are controlled by INDEX.HTML of this chapter. In addition, you can refer to java.sun.com, how to insert the latest and most complete information on the Applet in the web page.
AppletViewer Usage Sun JDK contains a tool called AppletViewer, which can find Applets in the HTML file according to
//: c14: applet1b.java// Embedding the applet tag for applet1b width = 100 height = 50> applet> import javax.swing. *; import java.awt. *; public Class Applet1b Extends Japplet {public void init () {getContentPane (). Add ("applet!"));}} ///: ~ You can use this command to start applet.
AppletViewer Applet1b.java This book will use this simple way to test the applet. In addition, you will see another way. It does not use AppletViewer, start the applet directly with the command line.
Applet test If you just want to test it, you don't have to go online. Start the web browser directly, open the HTML file containing the applet tag. When the browser is loaded with HTML, the Applet tag is discovered, and the corresponding .class file is found according to the value of the Code. Of course, it is found in ClassPath. If there is no ClassPath, it gives an error message in the status bar of the browser, telling you that the .class file is not found.
If you want to test Applet on a web site, the problem is somewhat complicated. First, you have to have a website first. For most people, the website is a directory on the ISP (Internet Service Provider) machine. Since Applet is just a few files, ISP does not provide special support, so you have to find a way to pass the HTML file and .class file to the specified ISP machine. This step is usually done by FTP. It's a lot of tools in FTP, some is freeware, some is Shareware. From this point of view, it seems to test the applet on the website, which is used to pass the file to the ISP machine, and then connect to the website, open the page with the browser, wait until the Applet jumps out, it is very good. Is it really?
This is where you will let you plant ahead. If the client's browser cannot find a .class file on the server, it will go to the client's classpath to find it. In this way, it is possible that the browser can't find the .class file on the server, so the applet is started with the file on your machine. So everything is normal, and others can't see anyone. So before testing, you must delete the local .class file (or .jar file), only this can you know that the program is in the correct server directory.
I have planted a very embarrassing head here. Once, when I uploaded HTML and Applet, I made a wrong Package name, so put the applet missed the directory. But my browser can also find the program in the local classpath, so I became the only one that can run this applet. Therefore, when you assign the Code parameter to the Applet, you must give a full name, this is very important. Many public published applets are not packaged, but in actual work, it is best to make a package. Start the applet with the command line Sometimes you will also want the GUI program to do something else. For example, when retaining Java's cross-platform, let it do some "ordinary" procedures. In the previous chapter of this book, we have been writing command line applications, but some operating systems (such as Macintosh) are no command lines. So we have countless reasons, use Java to write some non-applet's GUI program. This is of course a very reasonable requirement.
You can use the SWING class library to write an application that is exactly consistent with the current operating system's appearance. If you want to write the GUI program, first see if Java and related tools can be the most new version, only, that is worth writing. [78] Because only this can we write the program that will not let users feel annoying. If for some reason, you have to write an important GUI program with an old version of Java, then consider it carefully before receiving the task.
You will definitely want to write programs that can be started from the command line and can run when applet. It is very convenient to test the applet. Because typically starting from the command line to start faster than from a web browser and AppletViewer, it is more convenient.
To create an applet that can start with the command line, just add a main () in the class, let it put this Applet's instance to JFrame. [79] We take Applet1b.java as an example to see how to modify us to make it both applications and can run when applets.
//: c14: applet1c.java// An application and an applet.//
You will see main () explicitly call the applet's init () and start (). This is because these two steps are originally handed over to the browser. Of course, this does not completely replace the browser because the former will call Stop () and Destroy (), but roughly, this approach is still feasible. If you have any questions, you can call themselves. [80] Note that if there is no line:
Frame.setVisible (TRUE); then you can't see anything.
A framework for displaying Applets is very useful, although the code converts Applets into an application is very useful, but it is a waste of paper and people who are wasting them. So let's use the following frame to display the Swing example.
//: com: bruceeckel: Swing: console.java// Tool for running swing demos from the // console, Both applets and jframes.package.com; import javax.swing. *; import java.awt.event {String t = o.getclass (). Tostring (); // remove the word "class": if (T. IndexOf ("Class")! = -1) T = T.Substring (6); returnit t;} public static void Run (JFrame Frame, Int Width, int Height) {frame.setDefaultcloseOperation (jframe.exit_on_close) ; frame.setSize (width, height); frame.setVisible (true);} public static void run (JApplet applet, int width, int height) {JFrame frame = new JFrame (title (applet)); frame.setDefaultCloseOperation (JFrame .Exit_on_close; frame.getContentPane (). Add (applet); frame.setsize; applet.init (); applet.Start (); frame.setVisible (TRUE);} public static void Run (JPanel Panel, int width, int {j Frame frame = new JFrame (title (panel)); frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);. Frame.getContentPane () add (panel); frame.setSize (width, height); frame.setVisible (true);}} / //: ~ This is a tool that everyone has used, so I put it into com.bruceeckel.swing. Console is a class that is completely composed of static methods. The first method is responsible for extracting the name of the class belonging to the object (using RTTI). Since getClass () usually adds a "class" after the name of the class, use indexof () to determine if there is "class" in the name. If so, use substring () to strip it and return to this string. This name will appear on the title bar of the window displayed by Run (). SetDefaultCloseOperation () The role is to tell the procedure, once JFrame is turned off, the program should also exit. By default, JFrame does not mean to exit the program, so the program will not abort unless you call setDefaultCloseOperation () or write some similar code.
Run () made three overloads for Japplet, JPanel, and JFrame, respectively. Note that INIT () and START () are only required to be a japplet. Now just create a main (), then add the row in this line, you can run on the console:
Console.Run (New Myclass (), 500, 300); Finally, the two parameters represent width and high respectively. Below we use console to modify Applet1c.java:
//: C14: applet1d.java// Console Runs Applets from the command line .//
Making the button to make a button is simple: I want to let the button display, take it as a parameter to call the JButton constructor. Below we will do some more exciting things, such as what to put an icon on the button.
The usual button is a field of the class, so you can use it to indicate the button.
JButton is a component - it has its own small window - will be automatically refreshed when the update is updated. That is, you don't have to clearly indicate how the button is displayed or anything else; just put them in the form, they can draw themselves. So you have to put the button on the form:
//: c14: Button1.java/ Putting button on an applet.//
Swing's idea is to interface (graphic components) and implementation (after the component has an event, the code you want to run) clearly. What incidents can happen in the SWING component, and what happened. So if you are not interested in an event, such as the mouse over the button, you can do not pay attention to this event. In this way, you can solve the problem of event-driven, once you understand the basic concepts, you can even go directly from the Swing components that have never seen before. In fact, this model is also applicable to Javabean (discusses later after this chapter).
We still first comply with the main events of this control we want to use. In this example, this control jbutton, and "what we are interested in" is the press button. To indicate that you are interested in the button, you can call AddActionListener (). This method requires an ActionListener parameter. ActionListener is an interface that only has one method, ActionPerformed (). So if you want JButton to perform a task, you have to implement an ActionListener first, then register this class with the addActionListener method to jButton. This method will start when the button is pressed. (This is often referred to as callback)
So after the button is pressed, what should it be? We hope to see changes on the screen, so introducing a new Swing component here: jtextfield. This component can display text. Its text can be either user-entered or a program inserted. Although there are many ways to create JTextField, the simplest is the first to pass the width to the constructor of JtextField. Wait until JtextField is placed on the form, you can use setText () to modify the content (JtextField has many methods, please refer to the JDK document). Below is the modified program: //: c14: Button2.java// responding to button presses.//
We register the ButtonListener object with addActionListener () in init ().
Considering that each Listener usually requires only one instance, it is more convenient to implement ActionListener with anonymous internal classes. Below we use anonymous internal classes to rewrite Button2.java
//: c14: Button2b.java// using anonymous inner class code = button2b width = 200 height = 75> applet> import javax.swing. *; import java.awt.event. *; import java.awt *;. import com.bruceeckel.swing *;. public class Button2b extends JApplet {private JButton b1 = new JButton ( "Button 1"), b2 = new JButton ( "Button 2"); private JTextField txt = new JtextField (10); private activityListener BL = new actionListener () {public void actionPerformed (ActionEvent E) {string name = ((jbutton) E.GETSOURCE ()). GetText (); txtTTTTTEXT (Name);}}; Public void init () {b1.addactionListener (BL); b2.addactionListener (BL); container cp = getContentPane (); cp.setLayout (new flowLayout ()); cp.add (b1); cp.add (b2) CP.Add (txt);} public static void main (string [] args) {console.run (New Button2b (), 200, 75);}} ///: ~ This book will prefer anonymous internal class Method (unless you have to have you). Jtextarea is compared with Jtextfield, Jtextarea can accommodate multi-line text, providing more features, which are similar. The append () method is useful; you can use it to direct the output of the program to jtextarea so you can use the Swing program to improve our previously written, the command line printed on the standard output (because you can use The scroll bar saw the previous output). The following program uses the Geography generator in Chapter 11, and we use its output to fill Jtextarea:
//: C14: Textarea.java// using the jtextarea control. *; import java.awt.event. *; import java.awt. *; import java.util. *; import com.bruceeckel. swing *;. import com.bruceeckel.util *;. public class TextArea extends JFrame {private JButton b = new JButton ( "Add Data"), c = new JButton ( "Clear Data"); private JTextArea t = new JTextArea ( 20, 40); private Map m = new HashMap (); public TextArea () {// Use up all the data: Collections2.fill (m, Collections2.geography, CountryCapitals.pairs.length); b.addActionListener (new ActionListener () {PUBLIC VOID ACTIONPERFORMED (ActionEvent E) {Iterator IT = M.Entryset (). Iterator (); while (it.hasnext ()) {map.entry me = (map.Entry) (it.next ()) T.Append (me.getKey () ":" me.getValue () "/ n");}}}); c.AddActionListener (new actionListener () {public void actionPerformed (ActionEvent E) {t .SETTEXT ("");}}); Container CP = getContentPane (); CP. SetLayout (New flowLayout ()); cp.add (new JscrollPane (T)); cp.add (b); cp.add (c);} public static void main (string [] args) {console.run (New TextArea (), 475, 425;}} ///: ~ This class should be a JFRAME instead of a japplet because it is an applet to run in the HTML page as an applet. We put the country and the capital into the Map in init (). Note that these two buttons, we don't use intermediate variables during the creation and add ActionListener. This is because the other parts of the program do not need these two listeners (Listener). The "Add Data" button is responsible for the arrangement and adding of the data, and the "Clear Data" button is responsible for using the setText () method, emptying the text in jtextarea.
When jutxtrea joins Applet, we first embed it into JScrollpane, so once the text is more, the scroll bar will automatically appear. The ball roller is so simple. The Simple and Elegance of JScrollPane is really congestion compared to similar controls in other GUI programming environments.
The method of placing the component on the form in the form of the control layout can be different from the other GUI systems you have seen. First of all, it is all code, and there is no "resource" story at all. Second, the position of the component is not controlled by absolute positioning, but is controlled by an object called "layout manager". The role of the layout manager determines the position placed in accordance with the order of component add (). The size, shape, and placed position of the component will be significantly different from the layout manager. In addition, the layout manager automatically adjusts the position of the component according to the window size of the Applet or application, so that once the size of the window changes, the size, shape, and placement position of the component will be adjusted accordingly. JAPPLET, JFRAME, JWINDOW, and JDIALOG, these components have a getContentPane () method. This method can return a Container, and this Container's role is to resettle and display component. Container has a setLayout () method, you are using it to select the layout manager. Other classes, such as JPANEL, can resettle and display components directly, so you have to skip the content panel directly to set its layout manager.
Here, we will use the method of adding a button to the panel to examine various layout managers (so the simplest). We didn't write an event handler because the program here is just used to display the placement position of the button.
The default layout manager for BorderLayoutapplet is BorderLayout (in the first few examples, we change it into flowLayout). If there is no other instruction, BorderLayout puts all controls in the positive and stretched to the maximum.
It is better than these features in BorderLayout. It also has four boundaries and the concept of the central. When you add a controller to the panel of BorderLayout, you can also choose the overloaded add () method. At this time, give it a constant. This constant can be one of the five below:
BorderLayout. North side BorderLayout. South Border BorderLayout. East Right BorderLayout. West Left BorderLayout.center Fills, unless the edge of other components or forms
If you don't specify the area of the object, use the center by default.
Let's take a simple example. Since the Japplet is used by default, we will not have a layout:
//: c14: BorderLayout1.java// Demonstrates BorderLayout.//
Let's take an example of a FlowLayout. You will find that after using FlowLayout, the component will freeze it on its "inherent" size. For example, JButton will arrange the size according to the length of the string.
//: c14: FlowLayout1.java// Demonstrates FlowLayout.//
GridLayoutGridLayout means that the table is a component's form. When you add something to the left, it will put the components in the order from the top to the right. When you create a layout manager, you have to refer to the number of people and columns in the constructor, so that it can help you divide the form into a lattice. //: c14: GridLayout1.java// Demonstrates GridLayout.//
GridbagLayoutGridbagLayout is that when the size of the window changes, you can use it to accurately control the reactions of each part of the window. But at the same time, it is also the most difficult and most complex layout manager. It is mainly for the GUI Builder generated code (perhaps the GUI Builder is not absolutely positioned but gridbaglayout). If your design is very complicated, you have to use GridbagLayout, so I suggest you use the GUI Builder. If you think it is necessary to understand the details inside, I suggest you read Horstmann and Cornell's Core Java 2, Volume 1, (Prentice Hall, 2001), or watch Swing monographs.
Absolute positioning can also be absolutely positioned to the graphic components:
Set the container's layout manager to null: setLayout (NULL). When adding components to the panel, first adjust the setbounds () or reshape () method (according to each version), set a rectangle in pixels. This step can be placed in the constructor, or it can be placed inside to see you. Some gui builders are mainly used by this method, but in general, this is not the best way.
Boxlayout is too difficult to learn because GridbagLayout is hard, so Swing introduces a new boxlayout. It retains many advantages of GridbagLayout, but it is not so complicated. So when you want to control the layout of the control, you can give priority to use it (reiterate again, if the design is very complicated, it is best to use the GUI Builder). BoxLayout allows you to control components in both vertical and horizontal directions, which use some things called pillars and glue (glue) to control the distance between components. Let's first try it with the method of experiment other layout manager:
//: C14: BoxLayout1.java// Vertical and horizontal boxlayouts.//
//: c14: Box1.java// Vertical and horizontal boxlets.//
//: C14: Box2.java// adding struts.//
//: c14: Box3.java// using glue.//
//: C14: Box4.java// Rigid Areas Are Like Pairs of struts.//
Swing Event Model In Swing's event model, the component can initiate (or "shooting") event [translation 1]. Various events are classes. When there is an event occurs, one or more listeners will be notified and respond. Such an event's source is separated from its handler. Generally speaking, the programmer does not modify the Swing component, and they write some event handles. When the component receives the event [translation 1], the code is automatically called, so the Swing event model can be called The absolute example is separated by the interface and the implementation.
[Translation 1] This language previously lecture component issued an event, and the components received events later. As far as I understand, the previous event is that the component passed to the parameters that the component is called when the Listener method is called, and the latter event refers to the user's operation. Take the previous Button2.java example, the previous component is passed to its ActionEvent E when calling buttonListener's action, the next ActionEvent E, which means that the user presses the button.
In fact, event listener is an object that implements the Listener interface. So, the programmer is to create a Listener object and then register this object to the components of the initiating event. The process of registration is to call the AddXxxListener () method of the component, where "XXX" indicates the type of event initiated by the component. Just look at the name of the "AddListener" method, you can know which event can handle, so if you let it get wrong, then compile. Behind you will see that JavaBean will follow "AddListener" naming specification when deciding which events can handle. The transaction logic should be encapsulated into Listener. The only condition for creating Listener is that it must implement the interface. You can create a "global listner", but internal classes may be more appropriate. This is not only because of the logical grouping of Listener based on the UI or transaction logic (you will see), you can use the internal class to reference the characteristics of the host class, so you can cross the class or sub- The boundary of the system is called.
We have already involved Swing event model in the example, and we have completed the details of this model.
All Swing components in the event and the listener have the addXxxListener () and REMOVEXXXLISTENER () methods, so the components can add and delete the listener. You will find that "xxx" here is also the parameters of the method, such as AddMylistener (MyListener M). The following table lists the basic events, listeners, and methods, and corresponding to the ADDXXXLISTENER (), and components of the REMOVEXXXLISTENER () method. To know, this event model emphasizes scalability when designing, so you are likely to meet the events and listeners that have not been mentioned in this table.
Event, listener interface and add and remove methods support components ActionEventActionListeneraddActionListener this event () removeActionListener () JButton, JList, JTextField, JMenuItem and their derived classes JCheckBoxMenuItem, JMenu, and JpopupMenu AdjustmentEventAdjustmentListeneraddAdjustmentListener () removeAdjustmentListener () JScrollbar and implement interfaces Adjustable the assembly ComponentEventComponentListeneraddComponentListener () removeComponentListener () * component and its derived classes JButton, JCheckBox, JComboBox, Container, JPanel, JApplet, JScrollPane, Window, JDialog, JFileDialog, JFrame, JLabel, JList, JScrollbar, JTextArea, and JTextField ContainerEventContainerListeneraddContainerListener () removeContainerListener () Container and its derived class JPanel, JApplet, JScrollPane, Window, JDialog, JFileDialog, and JFrame FocusEventFocusListeneraddFocusListener () removeFocusListener () Component and "derived classes (derivatives *)" KeyEventKeyListeneraddKeyListener () removeKeyListener () Component and "derived class (DeriVative *) "MouseEvent (including click and mobile) MouselisteneraddMouseListener () RemoveMouseListener () Component and its derived class (DER) ivatives *) "MouseEvent [81] (including clicks and movement) MouseMotionListeneraddMouseMotionListener () removeMouseMotionListener () Component and" derived classes (derivatives *) "WindowEventWindowListeneraddWindowListener () removeWindowListener () Window its derived classes JDialog, JFileDialog, and JFrame ItemEventItemListeneraddItemListener ( ) removeItemListener () JCheckBox, JCheckBoxMenuItem, JComboBox, JList, and realized ItemSelectableinterface components TextEventTextListeneraddTextListener () removeTextListener () JTextComponent derived class, including JTextArea and JTextField you'll find a component supports only a few events. So I have to figure out that all components are very difficult. There is a simple way to modify the showMethods.java in Chapter 10, let it tell you which events support.
Chapter 10, we introduced the reflection, and give a program for displaying methods - or all methods, or by parameters, one of them can be listed. The magic of Reflection is that there is no way to traverse the inheritance system, it can get all methods of class. So for programming, this is a very valuable tool that saves time. Since most Java methods are very intuitive, you can choose a word you interested, let it go, then find the JDK documentation. But when I was 10, we haven't told Swing, so we wrote a procedure for a command line. Here we have to write a more practical GUI program, just it is specifically used to find the "addListener" method for the SWING component.
//: c14:. ShowAddListeners.java// Display the "addXXXListener" methods of any Swing class.// Container CP = getContentPane (); cp.add (borderLayout.North, TOP); cp.add (new jscrollpane (results)); // initial data and test: name.settext ("jtextarea"); Namelistener.ActionPerformed (New) ActionEvent ("0,"));} public static void main (string [] args) {console.run (new showaddlisteners (), 500, 400);}} ///: ~ Just in jtextfield into you want The name of the Swing component of the query, it will extract the result with the regular expression and then hand it over to Jtextarea display. You will find that there are no similar buttons on your form, allowing you to indicate the control of the query. This is because JtextField already has an ActionListener. This list will be updated immediately when you finish the ENTER. (Process is this,) If jtextfield is not empty, ActionListener finds class.Forname () based on this string. If the name is incorrect, class.Forname () will throw an exception and let the exception handler displays "No Match" in Jtextarea. If the name is correct (note is sensitive), class.Forname () will return normally, then getMethods () will return the array of Method objects. There are two regular expressions here. The first, that is, AddListener, responsible for matching "add" plus a number of words characters (translator Note: Original is Word Character, represents letters, numbers, and underline) plus "listener", plus any character enclosed in parentheses . Note that we put the entire regular expression in parentheses, that is, if the match is successful, we will use it as a group. Namel.ActionPerformed () method will pass the Method object one by one to Pattern.matcher (), and create a Matcher object by the latter. If the match is successful, Find () will return True so you can use Group (1) to select the first BROP of the entire expression. At this time, there is a definite word in front of the string. So we have to use Qualifier as a C09: showMethods.java. Finally, we set up the initial value of Name and run the event in the init () method. Use this program to see the Swing component is really too simple. Once you know the events supported by the components, you don't have to check the documentation. You just: Remove "Event" in the name of the Event class, plus "listener", which is the name of the interface you want to implement. Implement the above interface and want to capture which event implements its interface. For example, if you are interested in mouse movement, you can go to realize the mousemotionlistener interface mousemoved () method. (You must implement the full range of methods of this interface, but in this case, there will be shortcuts, and you will see it for a while.) Create an object of a Listener. Add an "add" in front of the name of the interface, and then register with the component with this method. For example, addMouseMotionListener (). Here are some methods listener interface: Method ActionListener Listener Interface / Adapter interface defined actionPerformed (ActionEvent) AdjustmentListener adjustmentValueChanged (AdjustmentEvent) ComponentListenerComponentAdapter componentHidden (ComponentEvent) componentShown (ComponentEvent) componentMoved (ComponentEvent) componentResized (ComponentEvent) ContainerListenerContainerAdapter componentAdded (ContainerEvent) componentRemoved (ContainerEvent) FocusListenerFocusAdapter focusGained (FocusEvent) focusLost (FocusEvent) KeyListenerKeyAdapter keyPressed (KeyEvent) keyReleased (KeyEvent) keyTyped (KeyEvent) MouseListenerMouseAdapter mouseClicked (MouseEvent) mouseEntered (MouseEvent) mouseExited (MouseEvent) mousePressed (MouseEvent) mouseReleased (MouseEvent) MouseMotionListenerMouseMotionAdapter mouseDragged (MouseEvent ) mouseMoved (MouseEvent) WindowListenerWindowAdapter windowOpened (WindowEvent) windowClosing (WindowEvent) windowClosed (WindowEvent) windowActivated (WindowEvent) windowDeactivated (WindowEvent) windowIconified (WindowEvent) windowDeiconified (Wi NDOWEVENT) ITEMLISTENER ITEMSTATECHANGED (ITEMEVENT) The reason why this table is not very complete, part is because the event model allows you to create your own events and related Listener. So you often encounter some class libraries in an event type, and your knowledge you have learned in this chapter will help you learn to use these events. Simplified programming with Listener's Adapter can see some of the listener in the table above only one way. The workload of this interface is not big, because the method is completed, the interface is also realized. But if you want to use a number of Listener, things are not so happy. For example, if you want to capture the mouse click (Button will not capture this event for you), you must write a mouseclicked () method. But because MouseListener is an Interface, even if not, you have to implement all of its methods. This is really annoying. In order to solve this problem, some (but not all) multi-method Listener interface provides an adapter. From the above table already lists their names. The adapter provides the default null method for the interface. In this way, you can inherit the adapter, you can override the method according to the needs. For example, this is the most common mouselistener: Class mymouselistener extends mouseadapter {public void mouseclicked (MouseEvent E) {// respond to mouse click ...}} Adapter is used to simplify the creation of Listener. But there is also a shortcoming of this thing of the adapter. Suppose you write a mouseadapter as above: Class mymouselistener extends mouseadapter {public void mouseclicked (mouseEvent e) {// respond to mouse click ...}} It not only doesn't work, but will give you crazy. It can be compiled normally, running does not report an error, but pressing the mouse that is no response. Can you see the problem? The answer is in the name of the method: You write mouseclicked () into mouseclicked (). It is just a little bit of case, it is a new method. Fortunately, this is not a method that will call when the window is turned off, so the worst result is just the expected results. Although there is a variety of inconvenience, the interface ensures that all the methods that should be implemented. Tracking multiple events To prove that event is really excited, as a very interesting experiment, we are ready to create other behaviors that can track JButton (that is, other events except for other events) Applet. Also demonstrate how to use inheritance to customize your own buttons, because the events you are interested in doing this object. To do this, just inherited JButton directly. [82] MyButton is the internal class of Trackevent, so MyButton can access its host window and control the Text Field in the host window. This ability is necessary if you want to make status information into a field of host class. Of course, this solution also has its limitations, MyButton can only be used with Trackevent. Such code is often referred to as "highly coupled": //: C14: Tracnt.java// show events as the happen.// mouseEntered ", e.paramString ());} public void mouseExited (MouseEvent e) {report (" mouseExited ", e.paramString ());} public void mousePressed (MouseEvent e) {report (" mousePressed ", e.paramString ());} public void mouseReleased (MouseEvent e) {report ( "mouseReleased", e.paramString ());}}; MouseMotionListener mml = new MouseMotionListener () {public void mouseDragged (MouseEvent e) {report ( "mouseDragged" , E.ParamString ());} public void mousemoved (MouseEvent E) {report ("mousemoved", E.ParamString ());}}; public mybutton (color color, string label) {super (label); setBackground color); addFocusListener (fl); addKeyListener (kl); addMouseListener (ml); addMouseMotionListener (mml);}} public void init () {Container c = getContentPane (); c.setLayout (new GridLayout (event.length 1 , 2)); for (int i = 0; i Report () requires the name of the event and the parameter string of the event, and then finds JTextField in Hashmap H based on the name of the event, and write the parameter string. This program is very interesting because it makes you intuitive see how the program handles events. The list of Swing Components is in your list of layout managers and event models. Next, learn how to use Swing components. This part is just a general introduction, we are talking about the common SWING components and their characteristics. We intend to make the routines relatively small, so you can move these code to your own program. remember: It is easy to run the routine, as long as you open the HTML page in the source code. (To www.bruceeckel.com) Downloaded with all Swing Components in the JDK document (only a small part here). The naming specification for Swing events is relatively reasonable, so you have to guess how to write and install the event handler is also relatively simple. Use our previous showaddlisteners.java to check the component. If things begin to become complex, congratulations, you have graduated, and you should use the Gui Builder. Buttonswing has included a lot of buttton, including various buttons, CHECK BOX, RADIO Button, and even Menu items (menu item) inherited AbstractButton (given the menu item also involved, (AbstractButton) may still be called "abstractselector" or other What name is better). We will soon see the usage of the menu item, but first let's take a look at Swing buttons: //: C14: Buttons.java// Various Swing Buttons Width = 350 Height = 100> applet> import javax.swing. *; import java.awt. *; import java.aw .event *;. import javax.swing.plaf.basic *;. import javax.swing.border *;. import com.bruceeckel.swing *;. public class Buttons extends JApplet {private JButton jb = new JButton ( "JButton" ); private BasicArrowButton up = new BasicArrowButton (BasicArrowButton.NORTH), down = new BasicArrowButton (BasicArrowButton.SOUTH), right = new BasicArrowButton (BasicArrowButton.EAST), left = new BasicArrowButton (BasicArrowButton.WEST); public void init () { Container CP = getContentPane (); cp.setLayout (new flowLayout ()); cp.add (jb); cp.add (New JToggleButton); cp.add (New JCheckbox ("jcheckbox"); Cp.Add ("jradiobutton"); jPanel JP = new jPanel (); jp.setborder (new title)); jp.add (up); JP.Add (down); JP. Add (left); jp.add (right); cp.add (jp);} public static Void main (String [] args) {console.run (New Buttons (), 350, 100);}} ///: ~ This program first demonstrates the BasicarrowButton of javax.swing.plaf.basic, followed by other shapes Button. When the program is running, you will find that Toggle Button can save whether the state is pressed. The CHECK BOX and RADIO Button behave are identical, as long as you click, you can turn it on or off (they are the derived class of JTogglebutton). BUTTON group If you want Radio Button to run in a "choice one" mode (Translator Note: Original is Exclusive or, the literal means "exclusive logic and"), you must add them to a "Button group ( Button group). But as shown in the following programs, but you can add ButtonGroup as long as it is AbstractButton. In order to avoid the duplication of code, we use reflection to generate a variety of Button groups. Creating a Button group and the JPanel task is done by makebpanel (). It has two parameters, the second is an array of String. MakebPanel () creates the Button determined by the first parameter according to the string in the array, then add it to JPanel: //: c14:. ButtonGroups.java// Uses reflection to create groups // of different types of AbstractButton.// } Public static void main (string [] args) {console.run (new buttonroups (), 500, 300);}} ///: ~ Border head is taken from class, put the path information before putting it up. . We first started AbstractButton with JButton marked with "failed", so that even if you ignore the abnormal information, (once you have a problem,) there will be reactions on the screen. The getConstructor () method returns a constructor object according to the Class array, which is determined by this Class array. Next, the newInstance () method is called. The parameters of this method are an Object array, that is, the parameters that constructor really needed - here is the string in the IDS array. These steps have added difficulties to the original simple task. To make Button to "choose a few choices", you must first create a Button group, then add the button you want to add. When running the program, you will find that all Button has shown the "choice one" effect in addition to jbutton. Iconicon can be used in Jlabel and AbstractButton, including JButton, JCheckbox, JraDiobutton, and JMenuItem. It is very simple to use the syntax for Jlabel (you will be demonstrated immediately). Below this program will use the icon in turn to Button and its school. You can also use your own GIF file, but here is still available on www.bruceeckel.com. If you want to open a file read image, just create an imageicon and pass the name of the file to it. Next, you can use this icon in the program. //: C14: Faces.java// iCon Behavior in jbuttons.// }}}); Cp.add (jb2); public static void main (string [] args) {console.run (New Faces (), 400, 200);}} ///: ~ Many SWING Component Construction Functions You can use icon to make parameters, but you can also add or modify the icon with the seticon () method. In addition, this program also demonstrates that when the button is listened to the event, it is when you press the button, the button, or (without pressing "button (but does not press). JButton (or other AbstractButton) makes it display different icons. You will find that you can use this technique to make a button with animation effect. Tool Tips We added a "Tool Tip" to the button above the program. Almost all classes related to the GUI are inheritance from JComponent, and JComponent also includes a settooltext (String) method. So no matter which component, you can almost use (assuming this is a JComponent's derived class object JC) JC.SetTooltiptext ("My TIP"); to set Tool TIP. As long as the mouse stops on the JComponent for a while, you will jump out of a prompt box, which is the text you set. TEXT FIELDS Let's take a look at what JtextField can do: //: C14: Textfields.java// text Fields and java events .// t1.setEditable (true);}} class B2 implements ActionListener {public void actionPerformed (ActionEvent e) {ucd.setUpperCase (false); t1.setText ( "Inserted by Button 2:" s); ucd.setUpperCase (true) ; t1.setEditable (false);}} public static void main (String [] args) {Console.run (new TextFields (), 375, 125);}} class UpperCaseDocument extends PlainDocument {private boolean upperCase = true; public void setUpperCase (boolean flag) {upperCase = flag;} public void insertString (int offset, String str, AttributeSet attSet) throws BadLocationException {if (upperCase) str = str.toUpperCase (); super.insertString (offset, str, attSet); }}} ///: ~ The reason why JtextField T3 is to prepare a reporting event to JTextField T1 listeners. You will find that only after pressing the "Enter" key, JtextField's listener will react. JtextField T1 has a few Listener. T1 is DocumentListener, which reacts the change of "Document" (here is the content of JtextField). It (t1) copies the text in T1 to T2. In addition, since the Document T1 is the derived type UppercaSedocument type of Plationocument, it will force all characters in the document to capitalize. In addition, it can also detect the backup key, which can automatically delete the operation, adjust the cursor (CARET), which handles the event is exactly the same as your expectations. There is a setBorder () method in Bordersjcomponent, which allows you to enjoy a funny border for a variety of visual components. Below we write a showborder () method to see these borders. This method creates a JPANEL and then put it on the border. We still get the name of the border by RTTI (remove path information), then put it in Jlabel in JPANel: //: c14: borders.java// Different Swing Borders.// //: c14:.. JScrollPanes.java// Controlling the scrollbars in a JScrollPane.// }} Class B3L implements ActionListener {public void actionPerformed (ActionEvent e) {String s = "Replacement"; t2.replaceRange (s, 3, 3 s.length ());}} class B4L implements ActionListener {public void actionPerformed ( ActionEvent E) {t2.insert ("inserted", 10);}} public void init ()} public void init () {Container CP = getContentPane (); cp.setLayout (new flowLayout ()); // Create Borders for Components: border brd = BorderFactory.createMatteborder (1, 1, 1, 1, color.black); t1.setborder (brd); t2.setborder (brd); sp3.setborder (brd); sp4.setborder (BRD); sp5.setborder (BRD) ); Sp6.setBorder (brd); // initialize listener and add components: b1.addactionListener (new b1l ()); cp.add (b1); cp.add (t1); b2.addactionListener (new b2l ()) CP.Add (b2); cp.add (t2); b3.addActionListener (new b3L ()); cp.add (b3); b4.addActionListener (New B4L ()); cp.add (b4); CP .add (sp3); cp.add (sp4); cp.add (sp5); cp.add (sp6); Public static void main (string [] args) {console.run (New Jscrollpanes (), 300, 725);}} ///: ~ Pass different parameters by means of a constructor of Jscrollpane, you can control its scroll bar. Here we also do decoration with a border. A pocket editor does not have much effort, JtextPane has provided a lot of editing features. Below we simply demonstrate this component, pay attention to we ignore the vast majority of its features: //: C14: TextPane.java// The jtextpane control is a little editor.import javax.swing. *; import java.awt. *; import java.awt.event. *; import com.bruceeckel.swing. *; import com.bruceeckel.util *;. public class TextPane extends JFrame {private JButton b = new JButton ( "Add Text"); private JTextPane tp = new JTextPane (); private static Generator sg = new Arrays2.RandStringGenerator (7); Public textpane () {b.addActionListener (new actionListener () {public void actionPerformed (INT i = 1; i <10; i ) tp.setText (tp.gettext () sg.next () "/ n");}}); container cp = getContentPane (); cp.add (new jscrollpane (tp)); cp.add (borderLayout.South, b);} public static void main (String [] args ) {Console.run (New TextPane (), 475, 425);}} ///: ~ The role of the button is randomly generated for some text, then add it to JtextPane. JtextPane means providing a place that allows you to edit text, so you will find it no append () method. Here (frankly, we don't use the feet of JtextPane ". We can only use setText () to get text, modify it, and then put back into JtextPane. As we mentioned earlier, the default layout of Applet is BorderLayout. So if you don't say anything, add components directly to the panel, then it will fill the entire panel. But if you specify its location (North, South, EAST, or West), the control will be stained in this area. Here the button will be placed below the screen. Note that JTextPane's built-in features, such as automatic wrap. In addition, it still has many other features. For details, please refer to the JDK documentation. Check Boxescheck Box allows you to do item-by-item. It consists of a small frame and a label. In general, there will be one 'x' (or any other indicator in the box), otherwise it is empty. In general, when you create JCHECKBOX with a constructor, it is passed to a parameter used as a label. After JCHeckbox is created, you can also read or set it at any time, or read or reset it. No matter whether it is selected or cleared, JCheckbox will trigger an event. The capture method is exactly the same as the button event: uses ActionListener. Let's take an example below. JtexTarea here will record all Check Box events: //: c14: checkboxes.java// using jcheckboxes.// To create a group of associated JRADiobutton, you can add them to ButtonGroup (any number of ButtonGroups are allowed in a form). If you (the second parameter of the constructor), set multiple radio button to true, then only the last one is valid. Let's take a simple example. Note that the method of capturing the Radio Button event is identical to capture other events: //: C14: Radiobuttons.java// using jradiobuttons./ Combo Boxes, like the Radio button, the drop-down list only allows the user to select an element in a set of options. But this approach is more concise, but it can modify the elements in the list without disturbing the customer. (You can also dynamically modify the Radio Button, but this visual effect is too strange). JCOMBOBOX's default behavior is not the same as Windows Combo Box. In Windows, you can choose one from the list of Combo Box, you can also enter it yourself, but in JCOMBOBOX, you must call setITable (). In addition, you can only select one from the list. Let's take an example. Let's add a few options to JCOMBOBOX, and then add an option every button. //: C14: ComboBoxes.java// using drop-down lists .// Jlist can do a number of options; if you have more than more than one option (when you choose to use the mouse, press the "Control" button), then the selected option will always be "highlightted) ", So you can choose any more. If you choose one, then then Shift-Click another, then all options between the two options are selected. To cancel a option, as long as the control-click is OK. //: C14: list.java// T.SetBorder (BRD); // add the first four items to the list for (INT i = 0; i <4; i ) LITEMS.ADDELEMENT (Flavors [Count ]); // add items to the content Pane for Display Cp.Add (T); cp.add (LST); cp.add (b); // register event listener Lst.AddListSelectionListener (LL); B.AddActionListener (BL);} public static void main (String [] args ) {Console.Run (New List (), 250, 375);}} ///: ~ You will find that we give a list of borders. If you just want to put the String array into Jlist, there is a simpler way; that is, the array is transmitted to the JList's constructor as a parameter so that it will automatically create a list. In the above routine, the only reason to use the list model is that the list is manipulated when the program is running. JLIST does not automatically provide a scroll shaft. Of course, as long as it is embedded in jscrollpane, it will automatically set up the scroll axes, and the specific details are taken to care. Tabbed panesjtabbedpane can create a "Tabbed Dialog" with a tab, that is, there is a pair of tabs on the dialog box, you just click on this tab, the dialog box will put this page. display. //: C14: Tabbedpane1.java// DemonStrates the Tabbed Pane.// The Message Boxes graphics interface system usually contains a set of standards that allow you to quickly pass messages to users, or get information from users. For Swing, these message boxes are included in JOPANE. You have a lot of choices (some are quite complicated), but the most commonly used "confirmation dialog", which is started with Static Joptionpane.showMessageDialog () and JOptionpane.showConfirmDialog (). Let's demonstrate some dialog boxes in JOPANE. //: C14: MessageBoxes.java// , "SECOND", "third"}; object val = joptionpane.showinputdialog (Null, "Choose One", "Input", JOPTIONPANE.INFORMATION_MESSAGE, NULL, Selections, Selections [0]); if (Val! = Null) TXT .SETTEXT (VAL.TOSTRING ());}}}; public void init () {Container CP = getContentPane (); cp.setLayout (new flowLayout ()); for (int i = 0; i Menu All components that can contain menus, including Japplets, JFrame, JDialog, and components they are derived, have a setjmenubar () method that requires JMenubar as a parameter (a component can only have a jMenubar). You can join JMenu to jMenubar and join JMenuItem to JMenu. Each JMenuitem can be connected to an ActionListener, when you select the menu item, the event is issued. Different from the system of using resources, Java and Swing require you to assemble the menu with source code. Here is a very simple menu routine: //: c14: Simplemenus.java// JMenuItem is the derived class of AbstractButton, so it has some similar buttons. JMenuItem itself is a menu option that can be placed in a drop-down menu. In addition, JMenuItem has three derived classes: JMenu to hold other JMenuitem (so you can do laminated menus); there is a JCheckBoxMenuItem that can indicate whether the candidate mark (Checkmark) "; and contains a Radio Button's JRADIOBUTTONMENUITEM. Let's take a more complex example, this time we have to use ice cream taste. This example also demonstrates a laminated menu, shortcut, JCheckBoxMenuItem, and other methods that can dynamically change menu: //: C14: Menus.java// Submenus, CheckBox Menu Items, Swapping Menus, //mnemonics (shortcuts) and action commands.// // Refresh the frame}} class ML implements ActionListener {public void actionPerformed (ActionEvent e) {JMenuItem target = (JMenuItem) e.getSource (); String actionCommand = target.getActionCommand (); if (actionCommand.equals ( "Open" )) {String s = t.getText (); boolean chosen = false; for (int i = 0; i Else if ("hide")) T.SetText ("Hide the ice cream!" "is it hidden?" target.getState ());}} public void init () {ml ml = new Ml (); cmil cmil = new cmil (); safty [0] .SetActionCommand ("Guard"); Safety [0] .SETMNEMONIC (KeyEvent.vk_g); Safety [0] .additemlistener (cmil); safty [1] .SetActionCommand ("hide"); Safety [1] .SETMNEMONIC (KeyEvent.vk_h); Safety [1] .additemlistener (cmil); Other [0] .addactionListener (new fool ()); other [1] .addactionListener NEW BARL ()); other [2] .addactionListener (new bazl ()); FL FL = New fl (); for (int i = 0; i Then traverse this array and call the JMenuItem's Add () method one by one. This makes the task that adds and deletes menu items to be less annoying. To demonstrate the dynamically exchanged menu bar during operation, we have created two JMenubar. You will find that JMenuBar is composed of JMenu, while JMenu is composed of JMenuItem, JCHECKBOXMENUITEM, JMENU (it creates submenu). When JMenuBar is assembled, you can use the setjmenubar () method to install it into the current program. Note When you press the button, it uses getjmenubar () to determine the current menu and then replace another menu. Test "Open" should pay attention to spelling and uppercase, but if the "open" does not match, Java does not report. This comparison of such a string is a major cause of initiating programming errors. The program will automatically check or restore the menu item. JCHECKBOXMENUITEM code demonstrates how two methods that determine which menu item that should be ticked. One is a matching string (although it is also used, it is like the above, it is not very safe), the other is the matching event target object. As you can see, the getState () method can return the status of JCheckBoxMenuItem, and setState () can set it. The menu event is not very consistent, which may cause confusion. JMenuitem uses an ActionListener event, while JCheckBoxMenuItem uses the itemListener event. JMenu also supports ActionListener, but usually nothing. In short, you have to prepare a listener for each JMenuitem, JCheckBoxMenuItem or JraDiobuttonMenuItem, but we have stole it to you, connect an itemListener and ActionListener to multiple menu components. Swing supports a mission, or says "shortcut" so you can throw away the mouse with keyboard to select AbstractButton (button, menu item, etc.). To do this, take the JMenuitem for example, you can use it to overload the constructor to pass the identifier of the shortcut as the second parameter to it. However, most AbstractButton did not provide similar constructor, so a relatively general method is to use the setmnemonic () method. In the above routine, we add shortcuts for buttons and multiple menu items, which are automatically displayed on the component. In addition, we also demonstrate usage of setArtionCommand (). It may be somewhat weird, because "action command" is the label on the menu. Why not use the label directly, but use the string to replace it? The problem is international. If you want to modify the source code, let the program run in another locale (modify the source code, there is no doubt that you will bring new errors), just change the label on the menu. So in order to simplify the code for the menu string, you can let "Action command" remain unchanged, so that the label on the menu is not tight. Note that we don't have an action command that checks the menu one by one, so those who don't check, we don't have an action command. Most things are done in the listener. BL is responsible for the switch of JMenubar. ML first finds "Who is in the bell", the idea is to find the source of ActionEvent, then convert it into JMenuItem, then transfer the action command to a cascade IF statement. Although FL wants to handle all the tastes in the Flavor menu, it is still very simple. If your idea is clear enough, this method is still very useful, but usually, you have to prepare a listener for each menu item, just like Fool, Barl and Bazl, so you don't need to write the probe code. And you can also know who is calling that Listener. Although this will increase the number of classes, the code of each class is reduced, and the process of the program is also "anti-staying". You will find that the menu code will become growing and chaotic. Here is the GUI Builder that can make a big manner. Good tools should help you maintain your menu. Pop-up menu To implement JPopupMenu, the most straightforward way is to create an internal class that inherits the MouseAdapter, then add the instance of this internal class to the component to provide pop-up menu: //: C14: Popup.java// Creating popup menus with swing.// Painting a good GUI framework makes a relatively simpler - indeed, Swing is done. All mapping problems face the same difficult point, that is, compared to the drawing function, calculate where to paint things will usually be more difficult, but unfortunately, this calculation is often mixed with the call of the mapping function, so The actual complexity of the function of the function is likely to be simpler than what you think. Long-term short talk, think about how to draw data on the screen. Assuming that we use the Java's built-in Math.sin () function, it is the sinusoidal function to provide data. In order to improve your interest, it also demonstrates the ease of use of the Swing component, and we put a slider at the bottom of the form, use it to dynamically control the number of cycles of the sine wave. Also you will find that if the size of the window changes, the sine wave will automatically adjust its shape according to the size of the new window. Although you can paint on any JComponent, that is, they can act as canvas, but if you want a whiteboard that you can paint, it is best to create a class inherited JPanel. This way you only need to overwrite a method, that is, PaintComponent () is OK. This method is automatically called when the system needs to redraw components (usually, you don't have to worry about this because this is controlled by swing). When calling, swing will pass a Graphics object to this method so you can use this object. In the following example, all information related to mapping is included in the SINDRAW class; SINEWAVE is only responsible for configuring programs and Slider. SINDRAW's setCyCles () method is a hook that allows other objects - here is the number of Slider - control cycles. //: C14: Sinewave.java// Drawing with swing, using a jslider.// adjustCycles.addChangeListener (new ChangeListener () {public void stateChanged (ChangeEvent e) {sines.setCycles (((JSlider) e.getSource ()) getValue ());.}}); cp.add (BorderLayout.SOUTH, adjustCycles } Public static void main (String [] args) {console.run (New Sinewave (), 700, 400);}} ///: All fields and arrays are The use field is sent; Cycles means that the sine wave to display a few cycles, Points means that you want to draw a few points, Sines store the value of the strings, and PTS stores the Y coabs on each point on the JPanel. SetCyCles () method will create an array as needed, then calculate the value of the SINES array item by item. SetCycles () can force call PaintComponent () through the repaint () method, so that the rest of the work will be accepted. When overwriting PaintComponent (), you must first call the same name method of the base class. The next thing to do will be determined by you; usually the way to call Graphics is painted on the JPANel or colored on its pixels. To see how to use these methods, you can check the Java.awt.graphics document (you can go to Java.sun.com to find a JDK document). You will find that most of the code here is doing the calculation; the code that the real control screen output is actually only two lines, setColor () and Drawline (). There will be similar feelings when you write this procedure in the future. Most of the time is to make what the painting is determined, and the real mapping process is very simple. When I wrote this program, most of the time spent on how to display sine waves. After you finish, I found that if you can dynamically change the number of cycles, it should be very good. I know that if you use other programming languages, this difficulty is quite big, so I have some hesitation. But what I can't think of this is the simplest part of this project. I created a JSLider (parameter is the value of Jslider moves to the left side, what is the value, what is the value of the right side, and what is the initial position, but there are other constructor, then put it The bottom side of the japplet. Then I turned over the JDK document and found that it only had a listener AddChangeListener. When the slider changes, it is triggered when it is enough to generate a new value. It has only one way, the name is also very good, called StateChanged (). This method requires a ChangeEvent object so that I can find the source of the event and find that the new value is. Next, as long as the setcycles () with sines can be called into JPanel and redraw graphics. In short, you will find that most swing issues can be solved by similar steps, and usually this step is quite simple, even if you never have used this component. If the problem is very complicated, there are some more complex solutions such as the third party JavaBean or Java 2D API. These contents have exceeded the scope of this book, but if your mapping code is very complicated, it should be checked. The dialog said that the dialog box refers to the window that can be played from other windows. Its role is that the details of the details are dealt with if they do not engage in the original window. The use of the dialog in the GUI programming is wide, but there is not much used in the applet. To create a dialog, you have to inherit JDIALOG first. Like JFrame, JDialog is another Window, which also has a layout manager (BorderLayout by default) or event listener can also be used. It has an important difference with JFrame, which is to close the program when the dialog is closed. On the contrary, you have to use the Dispose () method to release the resources occupied by the dialog window all. Let's take a simple example: //: C14: Dialogs.java// Creating and use Dialog Boxes.// You will find that all pop-ups, including dialogs, including dialog boxes, including "invisible". That is to say, there is a warning in the pop-up window. This is because theoretical malicious code can use this feature to fool the user, let them feel that they are running a local app, then misleading them into their own credit card number, and then passing the web. Applets are always connected to the webpage, so you can only use the browser, but the dialog can be separated from the web page, so it is theoretically this deceptive means is established. So in this way, Applet will not use the dialog box. Let's take a complicated example; first define a special button called TOEBUTTON, then create a dialog (with GridLayout) with the lattice it consists. This button draws a frame at its edge, and displays blank, "x" or "o" according to the status of its situation. When I started, the plaid was blank. When you click on it, it will modify its status according to the "x" or "O" now. However, when you press the button, it will switch between "X" and "O". (This is more step more than Tie-Tac-ToE concept.) In addition, the number of rows and columns of the lattice in this dialog can also be adjusted according to the parameters of the main window. //: C14: Tictactoe.java// Dialog Boxes and create your = TictactoE width = 200 height = 100> applet> import javax.swing. *; import java.awt. *; import java.awt.event *;. import com.bruceeckel.swing *;. public class TicTacToe extends JApplet {private JTextField rows = new JTextField ( "3"), cols = new JTextField ( "3"); private static final int Blank = 0, XX = 1, OO = 2; Class Toedialog Extends JDialog {Private Int Turn = XX; // Start with x's Turn TOEDIALOG (INT CELLSWIDE, INT CELLSHIGH) {setTitle ("The Game Itself"); Container CP = GetContentPane (); cp.setLayout (New GridLayout (Cellswide, CellShigh); for (int i = 0; i } Class ML Extends Mouseadapter {public void mousepressed (mouseEvent E) {if (state == blank) {state = TURN; TURN = (TURN == xx? Oo: xx);} else state = (state == xx? Oo : XX); repaint ();}}}} class BL implements ActionListener {public void actionPerformed (ActionEvent e) {JDialog d = new ToeDialog (Integer.parseInt (rows.getText ()), Integer.parseInt (cols.getText ( )))); D.Setvisible (TRUE);}} public void init () {JPANEL P = new jPanel (); p.setLayout (New GridLayout (2, 2)); P.Add (New Jlabel ("Rows" , Jlabel.center); P.Add (rows); P.Add ("Column", JLabel.center); P.Add (cols); container cp = getContentPane (); cp.add (p) BorderLayout.North; JButton B = New JButton ("Go"); B.AddActionListener (New BL ()); cp.add (b, borderLayout.South);} public static void main (String [] args) { Console.run (New Tictactoe (), 200, 100 );}} ///: ~ Since STATIC can only be used for host classes, there is no more static data or nested classes in the internal class. PainTComponent () is responsible for drawing the boxes around the Panel and "X" or "O". Although it is full of monotonic calculations, it is still concise. MouseListener is responsible for capturing clicks, which first looks at the Panel. If not, it will look at the status of TOEBUTTON, which is to ask where to ask the father window. Based on internal classes, ToeButton can access and modify the TURN of the host class. If the button has already displayed "x" or "o", then switch status. From this code, you can experience the benefits of the IF-Else's ternary expressions in our third chapter. After the state is finished, then refresh Toebutton. TOEDIALOG's constructor is quite simple; add the button to GridLayout according to the parameters you give, and then set each button to 50 pixels. Finally, TictactoE creates two jtextfield (to enter a button and column) and a "Go" button and use this button's ActionListener to complete the entire program. When you press the button, the listener reads the data in JtextField. Since it is a String type, you have to convert them in ints with static integer.parseint () first. File dialogs Some operating systems have built some special dialogs, such as dialog boxes such as font, colors, printers. In fact, all graphics operating systems provide dialogments to open and store files, so in order to simplify the approach, Java packages them into Jfilechooser. Below this program demonstrates two JFilechooser dialogs, one for opening the file, another is used to store files. The vast majority of code is already an old acquaintance, the real interesting thing is concentrated on the two button event listeners: //: c14: filechoosertest.java// Demonstration of File Dialog boxes.import javax.swing. *; import java.awt. *; import java.awt.event. *; import com.bruceeckel.swing. *; public class FileChooserTest extends JFrame {private JTextField filename = new JTextField (), dir = new JTextField (); private JButton open = new JButton ( "Open"), save = new JButton ( "Save"); public FileChooserTest () {JPanel p = NEW JPANEL (); Open.AddActionListener (New OpenL ()); P.Add (Open); Save.AddActionListener (new savel ()); P.ADD (SAVE); Container CP = getContentPane (); cp.add p, borderlayout.south; dir.setedItable (false); filename.setedItable (false); p = new jPanel (); p.setLayout (2, 1)); P.Add (filename); p. add (dir); cp.add (p, BorderLayout.NORTH);} class OpenL implements ActionListener {public void actionPerformed (ActionEvent e) {JFileChooser c = new JFileChooser (); // Demonstrate "Open" dialog: int rVal = c .Showopendialog (Filechooser Test.this); if (rval == jfilechooser.Approve_option) {filename.setText (c.getSelectedFile (). GetName ()); dir.setText (C.GetCurrentDirectory (). Tostring ());} if (rval = = JFileChooser.CANCEL_OPTION) {filename.setText ( "You pressed cancel"); dir.setText ( "");}}} class SaveL implements ActionListener {public void actionPerformed (ActionEvent e) {JFileChooser c = new JFileChooser (); / / DemonStrate "Save" Dialog: int RVAL = C.Showsavedialog (filechoosertest.this); if (rval == jfilechooser.Approve_option) {filename.settext (c.getSelectedFile (). Getname ()); Dir.Settext (C.GetcurrentDirectory (). toString ());} if (rval == jfilechooser.cancel_option) {filename.Settext ("You Pressed Cancel"); Dir.SetText ("");}}} public static Void main (String [] args) {console.run (New Filechoosrtest (), 250, 110);}} ///: Note JFilechooser has many modulations available, more than one filter filter file name Category. To call ShowOpendialog () with the "Open File" dialog box, use the "Save File" dialog box to call showsavedialog (). These two functions will not return before the dialog is turned off. Even if the dialog is closed, the JFilechooser object is still still, so you still read its data. To know the results of the operation, you can use getSelectedFile () and getCurrentDirectory (). If the NULL is returned, the user presses Cancel. The HTML all of the SWING components All components that display files can be displayed in accordance with HTML rules to display HTML text. That is to say, you can easily let Swing components show a very dazzling text. such as: //: c14: htmlbutton.java // putting html text on swing components.// JTabbedpane, JMenuItem, JTooltip, JRADIOBUTTON, and JCHECKBOX support HTML text. Slider and Process Bar Slider (we have been used in SINEWAVE.JAVA) allows users to enter data by moving back and forth, sometimes this approach is still very intuitive (forced to adjust the volume). ProGress Bar displays data in a class ratio, it indicates that the data is "all" or "empty", so the user can have a more comprehensive understanding. To give these two things, my favorite practice is to combat the slider and processes, so when you move Slider, the process strip has changed accordingly: //: c14: progress.java//// JProgressBar is relatively simple, and Jslider's option is more, such as the direction, size scale, etc. of placed. Pay attention to the line of code of the Slider to take a head frame, more simple. Tree JTree usage can be simply below the following line code: Add (New Object [] {"this", "That", "Other"); which shows a most basic tree. JTree's API is very large, it should be one of the Swing Class libraries. Although you can use it to do anything, but if you want to complete the complicated task, you need a certain research and experiment. Fortunately, this class is also provided, that is, a "default" tree component that meets general needs. So most cases you can use this component, only in special circumstances, you need to go deep into the tree. Next examples we use the "default" tree to display a tree in the applet. When you press the button, the currently selected node will give birth to a new subtree (if no node is selected, then the new sub-tree will be added to the root node): //: C14: Trees.java// Simple Swing Tree. Trees Can Be Vastly More Complex.// Test.addActionListener (New ActionListener () {public void actionPerformed (i Controls for JTree are implemented via its model. When MODEL changes, it produces an event that makes JTREE to make the necessary updates to the display of the tree. INIT () extracts this Model with getModel (). When you press the button, it creates a new new "BRANCH". After it finds the node currently selected (if nothing is not selected, use root node), model's InsertNodeInto () method takes over all tasks, including modifying the tree, refresh display, and more. Perhaps the above routine can meet your needs. But the function of the tree is powerful until you think that it can do, you can replace all "default" in the above routines into your own class to achieve new features. But you have to know: Almost every class has a very large interface, so you have to spend a lot of time and energy to understand its internal structure. But the words, its design is still very excellent, and its competitors are often worse. Like the table, Swing's table control is also very complex. When I started, they wanted to use JDBC (JDBC's "Grid" interface that is often used when connecting the database in Thinking In Enterprise Java), so it has extremely flexible, but the cost is complexity. . It allows you to easily create a full-featured spreadsheet program, but this will spend a whole book. But if you understand the basic principle, you can use it to create a relatively simple JTABLE. JTABLE is only responsible for displaying data, and the data itself is controlled by TableModel. So before you create JTABLE, you usually have to create a TableModel first. You can start to implement the TableModel interface from the beginning, but Java provides an AbstractTableModel helping class, inheriting it is relatively simple. //: c14: jtableDemo.java// // Cp.Add (new JScrollpane (Table)); cp.add (borderLayout.South, txt);} public static void main (String [] args) {console.run (New JtableDemo (), 350, 200);}} / //: ~ DataModel's data has an array, but you can also get data from it elsewhere, such as a database. The constructor adds a TableModellListener to DataModel, allowing it to print the array when the table changes. Other methods follow the BEAN's naming norm (use GET and SET, we will say later). These methods need to be used when JTABLE wants to display the data in DataModel. AbstractTableModel provides the default setValueat () and iScelleDitable () method, so you can no longer modify the data. If you want to modify the data, you must override these two methods. Waiting for TableModel, you can handle it to the JTable constructor. It automatically takes over the details of all display refreshes. We still as usual to embide the JTABLE to JScrollPane. Choose Look & Feel so-called "Look & Feel" means that you can simulate the appearance of other operating environment. You can even do something more dazzling, such as dynamically change its appearance during program operation. However, in general, you will only choose one of the following: Select the "cross-platform" appearance (that is, Swing "Metal"), or select the appearance of the current operating system, let the Java program look like this The operating system is customized (most cases, this is almost no choice, so the user is not confused). No matter which one you do, the code is very simple, but you must first execute the code and create a component, because the component is created according to the current Look and Feel, and when the program is running to half, you will change your Look and Feel, it Will not follow you. (This process is very complicated, and it is not practical, so we leave it to swing monograph). In fact, if you think the appearance of the cross-platform ("Metal") is a Swing program, and you want to use it, then you can not do anything - it is the default Look and Feel. But if you choose the current operating system's appearance style, then you can insert the following code. Generally, it is placed in main (), but the latest before adding the first component: try {UIManager.setLookAndFeel (UIManager getSystemLookAndFeelClassName ().);} catch (Exception e) {throw new RuntimeException (e);} You do not have to do anything in the catch inside, because if you choose other look and feel fails, UIManager will Back to the default cross-platform Look and Feel. But this exception is still active when debugging, and at least you can see what it will be seen from catch. Below is a program that uses the command line parameters to select the look and feel, and also see what these components look at different Look and Feels: //: C14: LookandFeel.java// selecting diffreent looks & folds.import javax.swing. *; import java.awt. *; import java.awt.event. *; import java.util. *; import com.bruceeckel .swing. *; public class lookandfeel extends jframe {private string [] choices = {"Eny", "Meeny", "Minnie", "MICKEY", "MOE", "Larry", "Curly"}; private component [ ] Samples = {New JButton ("jbutton"), New Jtextfield ("JTextfield"), New Jlabel ("Jlabel"), New Jcheckbox ("JCheckbox"), New Jradiobutton ("Radio"), New JComboBox (Choices), NEW New jlist (choices),}; public lookandfeel () {super ("Look and Feel"); Container CP = getContentPane (); cp.setLayout (new flowLayout ()); for (int i = 0; i }} Else usagerror (); // Note The Look & FEEL MUST Be set Before // Any Components Are Created. Console.run (New Lookandfeel (), 300, 200);}} ///: ~ You can clearly Use a string to specify the Look and Feel, just like MotiflookandFeel. But only it and "Metal" can be truly used on all platforms; although Java also provides strings for Windows and Macintosh's Look and Feel, these two appearance can only be used on their own platform (when you are here This Look and Feel can be obtained when calling getSystemLookAndfeelclassname on both platforms. If you make a Framework for companies with special requirements for the procedure, you can even create a look and feel. However, this can be a big project, which is difficult to exceed the scope of this book (in fact it even exceeds many Swing exclusive range!). The interaction between the clipboard JFC and the system clipboard is very limited (in java.awt.datatransfer package). You can copy the String object as a text into the clipboard, or you can paste the text in the clipboard into the String object. Of course, the clipboard supports any type of data, as for the data in the clipboard, it is a program that pastes the data. Java enhances the scales of the clipboard API through "Flavor" concept. When the data is added to the clipboard, the Flavor that is associated with this data can be converted to this data (more than one picture can be represented as a string or an image that all have a digital composition, so you will Can know if the data in the clipboard supports the Flavor you are interested in. Let's take an example of cutting, copying, and paste String in Jtextarea. You will find the cut, copy, and paste the shortcuts that we can use. However, if you tried JtextField and Jtextarea in other programs, you will find that they have already supported clipboard. We just wrote the code here. If you want to post the text in the clipboard to components other than JtextComponet, you can borrow the skills. //: c14: cutandpaste.java// using the clipboard.import javax.swing. *; import java.awt. *; import java.awt.event. *; import java.awt.datatransfer. *; import com.bruceeckel .swing *;. public class CutAndPaste extends JFrame {private JMenuBar mb = new JMenuBar (); private JMenu edit = new JMenu ( "Edit"); private JMenuItem cut = new JMenuItem ( "Cut"), copy = new JMenuItem ( " Copy "), paste = new JMenuItem (" Paste "); private JTextArea text = new JTextArea (20, 20); private Clipboard clipbd = getToolkit () getSystemClipboard ();. public CutAndPaste () {cut.addActionListener (new CutL ( )); Copy.addactionListener (new copyl ()); Edit.Add (CUT); edit.add (copy); edd (paSte); Mb.Add (Edit) ; setJMenuBar (mb);. getContentPane () add (text);} class CopyL implements ActionListener {public void actionPerformed (ActionEvent e) {String selection = text.getSelectedText (); if (selection == null) return; StringSelection clipString = new StringSelection (selection); clipbd.setContents (clipString, clipString);}} class CutL implements ActionListener {public void actionPerformed (ActionEvent e) {String selection = text.getSelectedText (); if (selection == null) return; StringSelection clipString = new StringSelection (selection); clipbd.setContents (clipString, clipString); text.replaceRange ( "", text.getSelectionStart (), text.getSelectionEnd ());}} class PasteL implements ActionListener {public void actionPerformed (ActionEvent e) {Transferable Clipdata = clipbd.getContents (CutAndPaste.this); try {. String clipString = (String) clipData getTransferData (DataFlavor.stringFlavor); text.replaceRange (clipString, text.getSelectionStart (), text.getSelectionEnd ());} catch (Exception ex ) {System.err.println ("not string flavor");}}} public static void main (string [] args) {console.run (new cutandpaste (), 300, 200);}} ///: ~ Now create menus and jtextarea should be very easy. Different, here we create a ClipBoard type CLIPBD field with Toolkit. All important things are placed inside Listener. In addition to the last line, CUTL and COPYL are identical. There are two lines here, which is to create StringSerection with String, and call the two lines of setContents () with StringSerection. Just these, String has been put in the clipboard. Pastel uses getContents () to take the data from the clipboard. It returns a relatively unfamiliar Transferable object, in fact, you don't know what it is. There is a way to know what is there, just use the getTransferDataFlavors () method. It will return a DataFlavor array, and these Flavors will tell you which of this object does. You can also pass a Flavor you interested to ask IsDataFlavorsupported () asked it. However, here we have used a very bold solution: assume this object to support String Flavor, directly call GetTransferData (), if it is wrong, abnormally handling self-service. You can expect that future Java will provide more Flavor. You can get more data Flavor support. One of the main purposes of making applets into JAR volume JAR is to optimize the loading of the applet. In the Java 1.0 era, the programmers try to put the applet's code into a class so that when the user downloads Applet, just send a request to the server once. But don't just make the code very hard to read (also difficult to maintain), and .class files are not compressed, so the download speed still has improved potential. JAR solves this problem, which compresses all the .class files in a file for the browser download. Now you can use the correct design and don't worry about it. Class file, and the user's download speed is faster. Tell Tictactoe.java. It looks only one class, but in fact, it contains five internal classes, so there are six categories. Once the compilation is successful, you can use the following command to compress it into a JAR file: JAR CF Tictactoe.jar * .class This assumes that all .class files in the current directory are compiled by Tictactoe.java (otherwise there will be more things in the volume). Next you have to create an HTML page, here you want to mark the JAR file with the Archive tag. Here is the most basic applet mark: Since I have Java Plugin, the steps to issue Applet have become easier and more standardized, and Applet also has a simpler way of deploying applications. The applet has become very simple, and there is also a standard Java tool. When Plugin hasn't come yet, you have to sign the .jar file with the netscape user using Netscape users, use Microsoft's tool to sign the .cab file for Internet Explorer users, and then prepare a set of tags in the HTML file. . The user must also install the certificate in the browser so applet can get trust. Plugin not only provides a standardized way of signing and deploying Applet, but also automatically installs the certificate, which is convenient for users. Imagine such an applet, it is accessible to the client's file system and reads and writes several files. This is very similar to Filechoosertest.java, just this is an applet, so if you want to open the JFilechooser dialog, it must be a signature JAR file. Otherwise showopndialog () will throw a securityException. //: c14: signedapplet: FileAccessApplet.java// Demonstration of File dialog boxes.package c14.signedapplet; import javax.swing *; import java.awt *; import java.awt.event *; import java.io... . *; import com.bruceeckel.swing *;. public class FileAccessApplet extends JApplet {private JTextField filename = new JTextField (), dir = new JTextField (); private JButton open = new JButton ( "Open"), save = new JButton ("Save"); private JeditorPane EP = New JeditorPane (); private jscrollpane jsp = new jscrollpane (); private file file; public void infit () {jPanel P = new jPanel (); open.addActionListener (new OpenL () ); P.Add (open); new savel ()); p.Add (Save); Container CP = getContentPane (); jsp.getViewPort (). Add (ep); cp.add (JSP, BorderLayout.center; cp.add (p, borderlayout.south); Dir.setedItTable (false); EP.SetContentType ("text / html"); filename.setedItTable (false); p = New jPanel (); p.setlayout (New Gridlayo UT (2, 1)); P.Add (filename); P.Add (Dir); cp.add (p, borderlayout.north);} Class Openl Implements ActionListener {Public Void ActionPerformed (ActionEvent E) {JFilechooser C = new JFileChooser (); c.setFileFilter (new TextFileFilter ()); // Demonstrate "Open" dialog: int rVal = c.showOpenDialog (FileAccessApplet.this); if (rVal == JFileChooser.APPROVE_OPTION) {file = c.getSelectedFile (); Filename.settext (file.getname ()); dir.setText (C.GetcurrentDirectory (). TOSTRING ()); try {system.out.println ("URL IS" file.tourl ()); EP .SETPAGE (File.tourl ()); // ep.repaint ();} catch (ioexception ie) {throw new runtimeException (}}} if (rval == jfilechooser.cancel_option) {filename.settext ("You Pressed Cancel"); Dir.Settext (" ");} else {save.setEnabled (true);}}} class SaveL implements ActionListener {public void actionPerformed (ActionEvent e) {JFileChooser c = new JFileChooser (file); c.setSelectedFile (file); // Demonstrate" Save "dialog: int rVal = c.showSaveDialog (FileAccessApplet.this); if (rVal == JFileChooser.APPROVE_OPTION) {filename.setText (c.getSelectedFile () getName ().); dir.setText (c.getCurrentDirectory (). TOSTRING ()); trywriter fw = new filewriter; ep.write (fw);} catch (ioexception ie) {throw new runtimeException (}}}} (rval == jfilechooser.cancel_option) {filename .SETTEXT ("You Pressed Cancel"); Dir.Settext (""); .}}} Public class TextFileFilter extends javax.swing.filechooser.FileFilter {public boolean accept (File f) {return f.getName () endsWith ( "txt.") || f.isDirectory ();} public String getDescription ( ) {RETURN "text files";}}} public static void main (String [] args) {console.run (new fileaccessapplet (), 500, 500);}} ///: ~ This seems to be A very ordinary applet. But although it can run on the client, it is not possible to turn the file. To sign him, you must first make it a JAR file (see the JAR Tools in this chapter), then sign this file. With a jar file, you have to sign your certificate or key. If it is a big company, then you can apply for the "Signing Authority" of VeriSign or Thawte, which will send you a certificate. The certificate is used to sign the code, so that the user can be sure that you are really the provider of this code he downloaded, and after you issued, this code is not tampered with. The essence of electronic signatures is a string of two-way number. When someone wants to check the signature, the certification center that gives you a certificate will testify for you. The certificate issued by the Certification Center is to pay, and it will be updated regularly. For this question, we can sign yourself for yourself. This certificate will exist in files (often referred to as Keychain). You can use the following command: KeyTool -List access the default file. If the default file does not exist, then you have to build one first, or tell it which file it goes. Maybe you should try the "cacerts" file. KeyTool -List -File {java.home} / lib / security / cacerts where java.home represents the directory where JRE is located. You can also send yourself a certificate with KeyTool for testing. If there is already a Java's "bin" directory in the PATH environment variable, then this command is: KeyTool -Genkey -Alaias It will prompt you to enter (KeyStore) password. The default is "changeit" (reminds you what to do). Then name, department, unit, city, state, and country. This information will be placed in the certificate. Finally it will give you a password to the certificate. If you really care about security, you can give it a separate password. By default, the password of the certificate is the password of the "KeyStore", which is already enough. The above information can also be used with a compilation tool like Ant using the command line. If you don't give parameters, use the keytool command directly to the command line, then print all the options all. You may want to use the -valid option to see how long the certificate is valid. If you want to confirm that the certificate is saved in the cacerts file, use KeyTool -List -KeyStore The certificate you just got is issued by yourself, so the certification center will not pay off. If you use this certificate to sign a JAR file, you will see a warning window there, and it is highly recommended that they don't use this program. Unless you go to buy a cost-effective certificate, you will have to bear with your users. Tag JAR file To use Java's Jarsigner standard tool, the command is as follows: Jarsigner -keystore Now this JAR file brings the signature of your certificate, and the user can know that it is not tampered with it after issuance (including modification, addition or deletion, etc.). Next, you have to worry about the "Archive" property of the applet tag of the HTML file, JAR's file name is here. If the browser uses Java's Plugin, the applet's tag is more complicated, but you can create a simple point, just like this: Now when the user downloads Applet, the browser will remind them that it is now loaded is a signature applet, and ask him to trust this issuer. As we mentioned earlier, the certificate used does not have high credibility, so it will give a warning. If the customer trusted, Applet can access the entire customer system, so it is nothingord of ordinary programs. The source code of this book already contains a full-compiled profile and Ant script, you can download it on www.bruceeckel.com. Although JNLP and Java Web Start is strongly signed, it can even be effectively replaced, but it is still running on a web browser. This not only enables the client to increase the overhead of the browser, but often make the user interface very monotonous and confusing. The browser has its own menus and toolbars, and they are pressing the top of the applet. Java Network Launch Protocol (JNLP) can solve this problem without sacrificing Applet. You can download and install separate JNLP applications on the client. It can be launched with the command line, desktop icon, or application manager distributed with JNLP. The program can even start from the site that was originally downloaded. When the JNLP program runs, it will download the resource from the Internet and automatically check the version (if the user connects to the Internet). That is to say, it also has the advantage of applet and Application. Like Applet, the client must pay attention to security issues when treating JNLP applications. JNLP app is an easy-to-download, web-based application, so it may be maliciously utilized. In view of this, JNLP applications should be placed in the sandbox as applet. Like Applet, it can be deployed with a signature JAR file. At this time, the user can choose whether it is trust the issuer. The difference between Applet is, even if there is no signature, it can still access certain resources of the client system through the JNLP API (this requires the user to recognize these requests when the program is running). JNLP is an agreement rather than the product, so it can be implemented first. Java Web Start is known as Jaws is SUN, which can be downloaded for free, JNLP's official model implementation. You only need to download and install, if you want to do it, don't forget to put the JAR file in the classpath. To deploy JNLP applications on the site, make sure that the server can recognize the MIME type of Application / X-Java-JnLP-File. If you use the latest version of the Tomcat server (http://jakarta.apache.org/tomcat), it should have been configured with you. Otherwise to check the user manual of the server. It is not difficult to create JNLP applications. Create a standard application first, then pack it with JAR, and finally prepare a boot file. The startup file is a very simple XML file, which is responsible for delivering information about downloading and installing the app to the client. If you decide to deploy software with a JAR file without signature, you have to use JNLP API to access resources on the client system. Below is a variant of the Jfilechooser dialog program, but this time we use JNLP services to open it so you can put the program into a JAR package without signature, then use JNLP to deploy. //: C14: JNLP: JNLPFILECHOOOSER.JAVA / / OPENING FILES ON A local Machine with jnlp.// {Depends: javaws.jar} package c14.jnlp; import javax.swing. *; import java.awt. *; import java.awt. *; import java.aw java.awt.event *;. import java.io *;. import javax.jnlp *;. public class JnlpFileChooser extends JFrame {private JTextField filename = new JTextField (); private JButton open = new JButton ( "Open"), save = new JButton ( "Save"); private JEditorPane ep = new JEditorPane (); private JScrollPane jsp = new JScrollPane (); private fileContents fileContents; public JnlpFileChooser () {JPanel p = new JPanel (); open.addActionListener (new OpenL ()); P.Add (open); new savel ()); p.Add (Save); Container CP = getContentPane (); jsp.getViewPort (). Add (EP); cp.add JSP, BorderLayout.center; cp.add (p, borderLayout.South); filename.seteditable (false); p = new jPanel (); p.setlayout (new gridLayout (2, 1)); p.Add (filename ); Cp.add (p, borderlayout.north); ep.setContentType ("text"); save.setEnabled (false);} class OpenL implements ActionListener {public void actionPerformed (ActionEvent e) {FileOpenService fs = null; try {fs = (FileOpenService) ServiceManager.lookup ( "javax.jnlp.FileOpenService");} catch (UnavailableServiceException Use) {throw new runtimeException (use);} if (fs! = null) {Try {filecontents = fs.openfiledialog (".", new string [] {"txt", "*"}); if (filecontents = = null; filename.settext (filecontents.getname ()); ep.read (filecontents.getinputstream (), null; } Catch (Exception exc) {throw new RuntimeException (exc);} save.setEnabled (true);}}} class SaveL implements ActionListener {public void actionPerformed (ActionEvent e) {FileSaveService fs = null; try {fs = (FileSaveService) ServiceManager.lookup ( "javax.jnlp.FileSaveService");} catch (UnavailableServiceException use) {throw new RuntimeException (use); "."} if (! fs = null) {try {fileContents = fs.saveFileDialog (, new String [] {"txt"}, new byterrayinputstream (EP.GETTEXT (). getBytes ()), filecontents.getname ()); if (filecontents == null) return; filename. settext (filecontents.getname ());} Catch (Exception Exc) {throw new runtimeException (exc);}}}} public static void main (string [] args) {jnlpfilechooser fc = new jnlpfilechooser (); fc.setsize (400, 300); fc.setVisib Le (TRUE);}} ///: ~ Note, FileOpenService and FileCloseService are classes in javax.jnlp, which does not mention the JFilechooser dialog in the end of the head until the end. To use these two services, not only use serviceManager.lookup () to request requests, but also to access client resources with objects returned by this method. Here we use JNLP's FileContent interface to read and write the client's file system. Any attempts to access these resources directly, thanks to create a File or FileReader object, will cause the program to throw a securityException, and the result is like in the unqualified Applet. If you don't want to be bound by JNLP, use these classes directly, you must use the signature JAR file (see the previous section, sign the JAR file). Now we have already made a JNLP program, the next task is to put the class in the jar file, and then write a startup file. Below the startup file of the above program: XML Version = "1.0" encoding = "UTF-8"?> The SPEC attribute of the JNLP element tells the client system, which version of JNLP is required. The CodeBase property tells the client which directory to find the startup file and resources. Usually it should be a HTTP URL pointing to the web server, but here, we refer to this machine's directory. The HREF property represents the name of the file. There are multiple sub-elements that provide information-related information in the Information tag. They are used by the management console for Java Web Start or other similar programs. These procedures install the JNLP app to the client, let the user launched by the command line, shortcut or other method. The resource tag is similar to the Applet tag in the HTML file. J2SE child elements indicate the J2SE version of the program run, and JAR child elements tell the client Class file which jar file is hit. In addition, the JAR element has a DOWNLOAD attribute whose value can be "eager" or "lazy", which is to tell JNLP whether it should be downloaded this JAR and start running the program. The Application-DESC property tells the client system, which is the executable class, which is where the port of the JAR file is. The JNLP tag also has a very useful child element, that is, the security tag that is not used here. Let's take a look at what the security tag is: Now .jnlp file is also written, the next is to add super link in the web page. This page should be a download page. In addition to complex formats and details, on the page, don't forget to add this:
Press Me Now! "); Public void init () {b.addActionListener (new activityListener () {public void actionPerformed (ActionEvent E) {getContentPane (). Add (new Jlabel (" " " kapow! ")); // force a re-layout to include the new label: validate ();}}); container cp = getContentPane (); CP. SetLayout (New flowLayout ()); cp.add (b);} public static void main (string [] args) {console.run (New HTMLButton (), 200, 500);}} ///: ~ Text must The beginning of "", you can mark with ordinary HTML. Note that it doesn't force you to turn off the tag. ActionListener adds a new one to the form and also shows the JLabel for HTML text. But this Label is not added in init (), so you must call ContaLidate () methods, forced it to re-print it for the component (so the new label is displayed).