Easy Java User Interface Programming

Source: Internet
Author: User

Buoy is a free User Interface (UI) Toolkit built on Swing. It provides convenience and simplicity for UI developers. In this article, the author uses a simple fractal user interface program to introduce what Buoy can do and why it does so.

I was surprised at the complexity of the Swing interface when I tried to build a simple user interface in Java for the first time. Honestly, I want to leave. Recently, a friend told me that his rendering program Art of transition Sion (see references) is based on a different Toolkit: Buoy. One of the reasons to recommend it is that its interface is more friendly. When he mentioned it for the first time, I thought he was talking about "BUI", and it was intentionally similar to the GUI name. Here B stands for better (better), but Buoy is not the abbreviation.

Buoy is free of charge. In fact, it is a public thing. It is not released with a reasonable degree of openness. In fact, it is not controlled by any license. This means that Buoy can be used in any project written in Java that can run Buoy, without the need to consider licensing issues. This toolkit is easy to modify and expand because it provides complete source code. This article is based on the Buoy 1.3 release and requires readers to have a basic understanding of Swing, although not familiar with it, to deal with the past.

Sample program

The first application I tried to build with Swing ended in failure. To see the comparison between the toolkit, I decided to use Buoy to build the same program. The code examples in this article are all from the Buoy version of the program. The program generates some fragment. Specifically, it is the fragment of iteration. The basic idea is simple: Define a series of line segments on the plane, from (0, 0) to (1, 0), and locate any unit line. After drawing these sections, draw the same set of deformation lines and use this section as the unit vector. It is easier to do than to say, as shown in figure 1.

Figure 1. fragment in the fragment Editor

The interface of this program is quite simple. It has some interface widgets, a canvas that draws beautiful images on the canvas, and supports mouse control of images. In fact, all you have to do is to manipulate the points that constitute the original curve, and the original curve will be drawn iteratively. The interface also has a minimal menu; it can open and close files, close the window, or save the current image as a PNG file. Although simple, this interface provides a reasonable example of a Buoy widget and a considerable number of experience for the event processing system.

The actual core code of the program-the fragment generator-has been written, which turns this example into a good test program. Of course, during the update process, I also found and fixed some bugs.
The release package contains the source Code of the sample program, compiled class files, and Buoy JAR files (click the Code icon at the top or bottom of this article to download factal.tar ). The package also contains a directory named frac, which contains some sample fragges. If you use a UNIX-style machine with a Java compiler in the path, you only need to run make to run it. Otherwise, you need to set the classpath to include the directory where the JAR file of the current path and Buoy is located, and then run the FractalViewer class. On Windows, the correct command line should be java-classpath.; Buoy. jar FractalViewer.

  Sed-e s/J/B/g

The first in-depth study of code may make the impression that converting Swing code into Buoy code is as simple as converting the letter J in the UI element name to B. For example, the FractalViewer class no longer extends JFrame; it now extends BFrame. The name of the main widget can also be inferred from this. The Spinner and slider have the same name as before, but they only change to a letter. MenuBar (menu bar) is still composed of Menus (Menus), and Menus contain MenuItems.

Some name conversions are slightly different. In the place where Swing references BorderLayout, Buoy has BorderContainer. In general, Buoy name conversion is quite uniform, although it is not always the same as Swing name. One obvious difference is that Buoy almost combines the concept of container and layout manager; each container type knows how to layout itself. This greatly simplifies the design. For example, the LabelWidget class used in the fractal generator is a BorderContainer; in Swing, this may be a JPanel with the BorderLayout layout manager.

However, there are many similarities between the two. This is very helpful for adapting to new things. More importantly, Buoy is built on Swing. This means that, in general, if you need to do something that cannot be easily completed with Bouy, you can pass the Buoy object to the Swing object it wraps. In this case, if you want to access a Swing object without a Buoy pair, you can simply wrap it in an AWTWidget object, which provides a very thin package through it, not only does Buoy own widgets, but all the widgets can access the Buoy widget API. For example, if you find that GridBagLayout is required, you may need to do so.

For example, the FractalPanel class is an AWTWidget. In early design, it is a subclass of JPanel, but in fact I don't need the JPanel code. Instead, I constructed the FractalCanvas class for packaging custom classes, which is a subclass of a common Canvas class. By turning it into an AWTWidget, you can use the efficient event processing mechanism of Buoy on it.

The event processing code is very simple. When you press the mouse button, Buoy sends a new MousePressedEvent event to the mousePressed () function through the magic of addEventLink. I ignore the question of which button to press. I only want to hold down shift and click normally. Select the nearest point, and press shift to center the display again. Then, if you move the mouse, the MouseDraggedEvent event will be sent every time the Buoy notices the movement. FractalPanel generates its own events when processing these events.

  PointChangedEvent

For more details, see PointChangedEvent. This is an experimental class. If you don't like it, you can only blame God. The idea of this class is: let a class represent changes in the state point. The editor tracks the "current" point, that is, the point currently being edited by the editor widget. You can use these widgets or click a new vertex in the fragment panel to select the closest vertex.

I come to the conclusion that there are about three types of point-to-point events in the code that need to be sent from one class to another.

One is to change the feature of a certain POINT: the POINT event type. If it is sent by the editor, it tells the fragment to change the points on the prototype line and asks to redraw the line. If it is sent by fragment, it indicates the feature of the point just selected by the editor.

Next is to select a point. You can select by index or location. Therefore, if only the index or location is provided, the constructor considers that the intention is to fill in other values. In a special case, vertex index-1 is used to indicate the unselected vertex. Therefore, you must use-2 to indicate that the editor is searching for the vertex at the specified position. This may not be nice, but it works.

It means that the Fractal Class responds to the SELECT event. If a vertex is selected successfully, a new PointChangedEvent event of the POINT type is returned, as shown in Listing 1.

List 1. Use events to answer events
case PointChangedEvent.SELECT:
if (e.getIndex() >= -1)
selectPoint(e.getIndex());
else
selectPoint(e.getPoint());
// just in case they dont know
event(new FractalChangedEvent(FractalChangedEvent.SIZE, size));
if (selectedPoint >= 0 && selectedPoint < size)
event(new PointChangedEvent(selectedPoint, points[selectedPoint]));
else
event(new PointChangedEvent(selectedPoint, null));
event(new FractalChangedEvent(FractalChangedEvent.REDRAW));
break;


Finally, moving a vertex is a special case. If you do not need to change other properties (such as color) of a vertex, you must process the position. This is the MOVE event type. In terms of effect, it works very much like the POINT event type, but it does not need the event generator (usually the FractalPanel class) to care about the attributes that it does not know at all.

The INSERT and DELETE event types are only partially related and may belong to the FractalChangedEvent event.

  Event Processing

As we have already seen, event processing is the most obvious difference between Buoy and Swing. Event processing provides a lot of flexibility. Buoy has a rich set of events and allows you to select events you are interested in and send events from any widget to other objects. For example, if you want to capture mouse events in Swing, the MouseListener interface must be implemented for the event capturing class. This interface has five functions to implement, even if they are furnishings. You must also use the function name provided by the interface. Worse, the function must be a public part of the listener interface, or make it public as part of the public interface, you can also create an internal class that does nothing but wraps the event interceptor code.

In Buoy, each widget is EventSource. This means you can listen for events from every widget. What types of events? All types are supported. The key function is addEventLink (). This allows you to specify classes, listeners, and optional methods. Whenever EventSource assigns an event of this class or its subclass, the listener receives the event, either through a method called processEvent () or by calling addEventLink () the method name. The provided functions cannot accept parameters or objects of classes compatible with the specified event type. The parent class and interface can.

This is a convenient setting. Different events can be routed to different functions or the same functions. For example, MousePressedEvent and MouseReleasedEvent are processed separately. In the example program, there are different threads for pressing, releasing, and dragging the mouse, as shown in Listing 2. Note that this is far beyond what Swing MouseListener can do. If you use Swing programming, You need to implement the MouseListener and MouseMotionListener interfaces.

List 2. Select only events of interest
this.addEventLink(MousePressedEvent.class, this, "mousePressed");
this.addEventLink(MouseRele

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.