CATEGORII DOCUMENTE |
Asp | Autocad | C | Dot net | Excel | Fox pro | Html | Java |
Linux | Mathcad | Photoshop | Php | Sql | Visual studio | Windows | Xml |
[SE1]After working your way through this chapter and seeing the huge changes that have occurred within the AWT (although, if you can remember back that far, Sun claimed Java was a "stable" language when it first appeared), you might still have the feeling that it's not quite done. Sure, there's now a good event model, and JavaBeans is an excellent component-reuse design. But the GUI components still seem rather minimal, primitive, and awkward.
That's where Swing comes in. The Swing library appeared after Java 1.1 so you might naturally assume that it's part of Java 1.2. However, it is designed to work with Java 1.1 as an add-on. This way, you don't have to wait for your platform to support Java 1.2 in order to enjoy a good UI component library. Your users might actually need to download the Swing library if it isn't part of their Java 1.1 support, and this could cause a few snags. But it works.
Swing contains all the components that you've been missing throughout the rest of this chapter: those you expect to see in a modern UI, everything from buttons that contain pictures to trees and grids. It's a big library, but it's designed to have appropriate complexity for the task at hand - if something is simple, you don't have to write much code but as you try to do more your code becomes increasingly complex. This means an easy entry point, but you've got the power if you need it.
Swing has great depth. This section does not attempt to be comprehensive, but instead introduces the power and simplicity of Swing to get you started using the library. Please be aware that what you see here is intended to be simple. If you need to do more, then Swing can probably give you what you want if you're willing to do the research by hunting through the online documentation from Sun.
When you begin to use the Swing library, you'll see that it's a huge step forward. Swing components are Beans (and thus use the Java 1.1 event model), so they can be used in any development environment that supports Beans. Swing provides a full set of UI components. For speed, all the components are lightweight (no "peer" components are used), and Swing is written entirely in Java for portability.
Much of what you'll like about Swing could be called "orthogonality of use;" that is, once you pick up the general ideas about the library you can apply them everywhere. Primarily because of the Beans naming conventions, much of the time I was writing these examples I could guess at the method names and get it right the first time, without looking anything up. This is certainly the hallmark of a good library design. In addition, you can generally plug components into other components and things will work correctly.
Keyboard navigation is automatic - you can use a Swing application without the mouse, but you don't have to do any extra programming (the old AWT required some ugly code to achieve keyboard navigation). Scrolling support is effortless - you simply wrap your component in a JScrollPane as you add it to your form. Other features such as tool tips typically require a single line of code to implement.
Swing also supports something called "pluggable look and feel," which means that the appearance of the UI can be dynamically changed to suit the expectations of users working under different platforms and operating systems. It's even possible to invent your own look and feel.
If you've struggled long and hard to build your UI using Java 1.1, you don't want to throw it away to convert to Swing. Fortunately, the library is designed to allow easy conversion - in many cases you can simply put a 'J' in front of the class names of each of your old AWT components. Here's an example that should have a familiar flavor to it:
//: JButtonDemo.java
// Looks like Java 1.1 but with J's added
package c13.swing;
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import com.sun.java.swing.*;
public class JButtonDemo extends Applet
};
b1.addActionListener(al);
add(b1);
b2.addActionListener(al);
add(b2);
add(t);
}
public static void main(String args[])
});
frame.getContentPane().add(
applet, BorderLayout.CENTER);
frame.setSize(300,100);
applet.init();
applet.start();
frame.setVisible(true);
}
} ///:~
There's a new import statement, but everything else looks like the Java 1.1 AWT with the addition of some J's. Also, you don't just add( ) something to a Swing JFrame, but you must get the "content pane" first, as seen above. But you can easily get many of the benefits of Swing with a simple conversion.
Because of the package statement, you'll have to invoke this program by saying:
java c13.swing.JbuttonDemo
All of the programs in this section will require a similar form to run them.
Although the programs that are both applets and applications can be valuable, if used everywhere they become distracting and waste paper. Instead, a display framework will be used for the Swing examples in the rest of this section:
//: Show.java
// Tool for displaying Swing demos
package c13.swing;
import java.awt.*;
import java.awt.event.*;
import com.sun.java.swing.*;
public class Show
});
frame.getContentPane().add(
jp, BorderLayout.CENTER);
frame.setSize(width, height);
frame.setVisible(true);
}
} ///:~
Classes that want to display themselves should inherit from JPanel and then add any visual components to themselves. Finally, they create a main( ) containing the line:
Show.inFrame(new MyClass(), 500, 300);
in which the last two arguments are the display width and height.
Note that the title for the JFrame is produced using RTTI.
Almost all of the classes that you'll be using to create your user interfaces are derived from JComponent, which contains a method called setToolTipText(String). So, for virtually anything you place on your form, all you need to do is say (for an object jc of any JComponent-derived class):
jc.setToolTipText('My tip');
and when the mouse stays over that JComponent for a predetermined period of time, a tiny box containing your text will pop up next to the mouse.
JComponent also contains a method called setBorder( ), which allows you to place various interesting borders on any visible component. The following example demonstrates a number of the different borders that are available, using a method called showBorder( ) that creates a JPanel and puts on the border in each case. Also, it uses RTTI to find the name of the border that you're using (stripping off all the path information), then puts that name in a JLabel in the middle of the panel:
//: Borders.java
// Different Swing borders
package c13.swing;
import java.awt.*;
import java.awt.event.*;
import com.sun.java.swing.*;
import com.sun.java.swing.border.*;
public class Borders extends JPanel
public Borders()
public static void main(String args[])
} ///:~
Most of the examples in this section use TitledBorder, but you can see that the rest of the borders are as easy to use. You can also create your own borders and put them inside buttons, labels, etc. - anything derived from JComponent.
Swing adds a number of different types of buttons, and it also changes the organization of the selection components: all buttons, checkboxes, radio buttons, and even menu items are inherited from AbstractButton (which, since menu items are included, would probably have been better named "AbstractChooser" or something equally general). You'll see the use of menu items shortly, but the following example shows the various types of buttons available:
//: Buttons.java
// Various Swing buttons
package c13.swing;
import java.awt.*;
import java.awt.event.*;
import com.sun.java.swing.*;
import com.sun.java.swing.basic.*;
import com.sun.java.swing.border.*;
public class Buttons extends JPanel );
public Buttons()
});
down.addActionListener(new ActionListener()
});
JPanel jp = new JPanel();
jp.add(spin);
jp.add(up);
jp.add(down);
jp.setBorder(new TitledBorder('Spinner'));
add(jp);
left.addActionListener(new ActionListener()
});
right.addActionListener(new ActionListener()
});
jp = new JPanel();
jp.add(stringSpin);
jp.add(left);
jp.add(right);
jp.setBorder(
new TitledBorder('StringSpinner'));
add(jp);
}
public static void main(String args[])
} ///:~
The JButton looks like the AWT button, but there's more you can do to it (like add images, as you'll see later). In com.sun.java.swing.basic, there is a BasicArrowButton that is convenient, but what to test it on? There are two types of "spinners" that just beg to be used with arrow buttons: Spinner, which changes an int value, and StringSpinner, which moves through an array of String (even automatically wrapping when it reaches the end of the array). The ActionListeners attached to the arrow buttons shows how relatively obvious it is to use these spinners: you just get and set values, using method names you would expect since they're Beans.
When you run the example, you'll see that the toggle button holds its last position, in or out. But the check boxes and radio buttons behave identically to each other, just clicking on or off (they are inherited from JToggleButton).
If you want radio buttons to behave in an "exclusive or" fashion, you must add them to a button group, in a similar but less awkward way as the old AWT. But as the example below demonstrates, any AbstractButton can be added to a ButtonGroup.
To avoid repeating a lot of code, this example uses reflection to generate the groups of different types of buttons. This is seen in makeBPanel, which creates a button group and a JPanel, and for each String in the array that's the second argument to makeBPanel( ), it adds an object of the class represented by the first argument:
//: ButtonGroups.java
// Uses reflection to create groups of different
// types of AbstractButton.
package c13.swing;
import java.awt.*;
import java.awt.event.*;
import com.sun.java.swing.*;
import com.sun.java.swing.border.*;
import java.lang.reflect.*;
public class ButtonGroups extends JPanel ;
static JPanel
makeBPanel(Class bClass, String[] ids) );
// Create a new object:
ab = (AbstractButton)ctor.newInstance(
new Object[]);
} catch(Exception ex)
bg.add(ab);
jp.add(ab);
}
return jp;
}
public ButtonGroups()
public static void main(String args[])
} ///:~
The title for the border is taken from the name of the class, stripping off all the path information. The AbstractButton is initialized to a JButton that has the label "Failed" so if you ignore the exception message, you'll still see the problem on screen. The getConstructor( ) method produces a Constructor object that takes the array of arguments of the types in the Class array passed to getConstructor( ). Then all you do is call newInstance( ), passing it an array of Object containing your actual arguments - in this case, just the String from the ids array.
This adds a little complexity to what is a simple process. To get "exclusive or" behavior with buttons, you create a button group and add each button for which you want that behavior to the group. When you run the program, you'll see that all the buttons except JButton exhibit this "exclusive or" behavior.
You can use an Icon inside a JLabel or anything that inherits from AbstractButton (including JButton, JCheckbox, JradioButton, and the different kinds of JMenuItem). Using Icons with JLabels is quite straightforward (you'll see an example later). The following example explores all the additional ways you can use Icons with buttons and their descendants.
You can use any gif files you want, but the ones used in this example are part of the book's code distribution, available at www.BruceEckel.com. To open a file and bring in the image, simply create an ImageIcon and hand it the file name. From then on, you can use the resulting Icon in your program.
//: Faces.java
// Icon behavior in JButtons
package c13.swing;
import java.awt.*;
import java.awt.event.*;
import com.sun.java.swing.*;
public class Faces extends JPanel ;
JButton
jb = new JButton('JButton', faces[3]),
jb2 = new JButton('Disable');
boolean mad = false;
public Faces() else
jb.setVerticalAlignment(JButton.TOP);
jb.setHorizontalAlignment(JButton.LEFT);
}
});
jb.setRolloverEnabled(true);
jb.setRolloverIcon(faces[1]);
jb.setPressedIcon(faces[2]);
jb.setDisabledIcon(faces[4]);
jb.setToolTipText('Yow!');
add(jb);
jb2.addActionListener(new ActionListener() else
}
});
add(jb2);
}
public static void main(String args[])
} ///:~
An Icon can be used in many constructors, but you can also use setIcon( ) to add or change an Icon. This example also shows how a JButton (or any AbstractButton) can set the various different sorts of icons that appear when things happen to that button: when it's pressed, disabled, or "rolled over" (the mouse moves over it without clicking). You'll see that this gives the button a rather animated feel.
Note that a tool tip is also added to the button.
Menus are much improved and more flexible in Swing - for example, you can use them just about anywhere, including panels and applets. The syntax for using them is much the same as it was in the old AWT, and this preserves the same problem present in the old AWT: you must hard-code your menus and there isn't any support for menus as resources (which, among other things, would make them easier to change for other languages). In addition, menu code gets long-winded and sometimes messy. The following approach takes a step in the direction of solving this problem by putting all the information about each menu into a two-dimensional array of Object (that way you can put anything you want into the array). This array is organized so that the first row represents the menu name, and the remaining rows represent the menu items and their characteristics. You'll notice the rows of the array do not have to be uniform from one to the next - as long as your code knows where everything should be, each row can be completely different.
//: Menus.java
// A menu-building system; also demonstrates
// icons in labels and menu items.
package c13.swing;
import java.awt.*;
import java.awt.event.*;
import com.sun.java.swing.*;
public class Menus extends JPanel };
static final MType
mi = new MType(1), //
cb = new MType(2), // Checkbox menu item
rb = new MType(3); // Radio button menu item
JTextField t = new JTextField(10);
JLabel l = new JLabel('Icon Selected',
Faces.faces[0], JLabel.CENTER);
ActionListener a1 = new ActionListener()
};
ActionListener a2 = new ActionListener()
};
// Store menu data as 'resources':
public Object[][] fileMenu = ,
// Name type accel listener enabled
,
,
,
,
, // Separator
,
};
public Object[][] editMenu = ,
// Name type accel listener enabled
,
,
,
, // Separator
,
};
public Object[][] helpMenu = ,
// Name type accel listener enabled
,
,
, // Separator
,
};
public Object[][] optionMenu = ,
// Name type accel listener enabled
,
,
};
public Object[][] faceMenu = ,
// Optinal last element is icon
,
,
,
,
,
};
public Object[] menuBar = ;
static public JMenuBar
createMenuBar(Object[] menuBarData)
static ButtonGroup bgroup;
static public JMenu
createMenu(Object[][] menuData)
return menu;
}
static public JMenuItem
createMenuItem(Object[] data)
m.setText((String)data[0]);
m.setKeyAccelerator(
((Character)data[2]).charValue());
m.addActionListener(
(ActionListener)data[3]);
m.setEnabled(
((Boolean)data[4]).booleanValue());
if(data.length == 6)
m.setIcon((Icon)data[5]);
return m;
}
Menus()
public static void main(String args[])
} ///:~
The goal is to allow the programmer to simply create tables to represent each menu, rather than typing lines of code to build the menus. Each table produces one menu, and the first row in the table contains the menu name and its keyboard accelerator. The remaining rows contain the data for each menu item: the string to be placed on the menu item, what type of menu item it is, its keyboard accelerator, the actionlistener that is fired when this menu item is selected, and whether this menu item is enabled. If a row starts with null it is treated as a separator.
To prevent wasteful and tedious multiple creations of Boolean objects and type flags, these are created as static final values at the beginning of the class: bT and bF to represent Booleans and different objects of the dummy class MType to describe normal menu items (mi), checkbox menu items (cb), and radio button menu items (rb). Remember that an array of Object may hold only Object handles and not primitive values.
This example also shows how JLabels and JMenuItems (and their descendants) may hold Icons. An Icon is placed into the JLabel via its constructor and changed when the corresponding menu item is selected.
The menuBar array contains the handles to all the file menus in the order that you want them to appear on the menu bar. You pass this array to createMenuBar( ), which breaks it up into individual arrays of menu data, passing each to createMenu( ). This method, in turn, takes the first line of the menu data and creates a JMenu from it, then calls createMenuItem( ) for each of the remaining lines of menu data. Finally, createMenuItem( ) parses each line of menu data and determines the type of menu and its attributes, and creates that menu item appropriately. In the end, as you can see in the Menus( ) constructor, to create a menu from these tables say createMenuBar(menuBar) and everything is handled recursively.
This example does not take care of building cascading menus, but you should have enough of the concept that you can add that capability if you need it.
The implementation of JPopupMenu seems a bit strange: you must call enableEvents( ) and select for mouse events instead of using an event listener. That is, it's possible to add a mouse listener but the MouseEvent that comes through doesn't return true from isPopupTrigger( ) - it doesn't know that it should trigger a popup menu. In addition, when I tried the listener approach it behaved strangely, possibly from recursive click handling. In any event, the following example produces the desired popup behavior:
//: Popup.java
// Creating popup menus with Swing
package c13.swing;
import java.awt.*;
import java.awt.event.*;
import com.sun.java.swing.*;
public class Popup extends JPanel
};
JMenuItem m = new JMenuItem('Hither');
m.addActionListener(al);
popup.add(m);
m = new JMenuItem('Yon');
m.addActionListener(al);
popup.add(m);
m = new JMenuItem('Afar');
m.addActionListener(al);
popup.add(m);
popup.addSeparator();
m = new JMenuItem('Stay Here');
m.addActionListener(al);
popup.add(m);
enableEvents(AWTEvent.MOUSE_EVENT_MASK);
}
protected void processMouseEvent(MouseEvent e)
public static void main(String args[])
} ///:~
The same ActionListener is added to each JMenuItem, so that it fetches the text from the menu label and inserts it into the JTextField.
List boxes and combo boxes in Swing work much as they do in the old AWT, but they also have increased functionality if you need it. In addition, some conveniences have been added. For example, the JList has a constructor that takes an array of Strings to display (oddly enough this same feature is not available in JComboBox). Here's a simple example that shows the basic use of each:
//: ListCombo.java
// List boxes & Combo boxes
package c13.swing;
import java.awt.*;
import java.awt.event.*;
import com.sun.java.swing.*;
public class ListCombo extends JPanel
public static void main(String args[])
} ///:~
Something else that seems a bit odd at first is that JLists do not automatically provide scrolling, even though that's something you always expect. Adding support for scrolling turns out to be quite easy, as shown above - you simply wrap the JList in a JScrollPane and all the details are automatically managed for you.
A slider allows the user to input data by moving a point back and forth, which is intuitive in some situations (volume controls, for example). A progress bar displays data in a relative fashion from "full" to "empty" so the user gets a perspective. My favorite example for these is to simply hook the slider to the progress bar so when you move the slider the progress bar changes accordingly:
//: Progress.java
// Using progress bars and sliders
package c13.swing;
import java.awt.*;
import java.awt.event.*;
import com.sun.java.swing.*;
import com.sun.java.swing.event.*;
import com.sun.java.swing.border.*;
public class Progress extends JPanel
});
add(sb);
}
public static void main(String args[])
} ///:~
The JProgressBar is fairly straightforward, but the JSlider has a lot of options, such as the orientation and major and minor tick marks. Notice how straightforward it is to add a titled border.
Using a JTree can be as simple as saying:
add(new JTree(
new Object[] ));
This displays a primitive tree. The API for trees is vast, however - certainly one of the largest in Swing. It appears that you can do just about anything with trees, but more sophisticated tasks might require quite a bit of research and experimentation.
Fortunately, there is a middle ground provided in the library: the "default" tree components, which generally do what you need. So most of the time you can use these components, and only in special cases will you need to delve in and understand trees more deeply.
The following example uses the "default" tree components to display a tree in an applet. When you press the button, a new subtree is added under the currently-selected node (if no node is selected, the root node is used):
//: Trees.java
// Simple Swing tree example. Trees can be made
// vastly more complex than this.
package c13.swing;
import java.awt.*;
import java.awt.event.*;
import com.sun.java.swing.*;
import com.sun.java.swing.tree.*;
// Takes an array of Strings and makes the first
// element a node and the rest leaves:
class Branch
public DefaultMutableTreeNode node()
}
public class Trees extends JPanel ,
,
,
,
,
,
};
static int i = 0;
DefaultMutableTreeNode root, child, chosen;
JTree tree;
DefaultTreeModel model;
public Trees()
}
});
// Change the button's colors:
test.setBackground(Color.blue);
test.setForeground(Color.white);
JPanel p = new JPanel();
p.add(test);
add(p, BorderLayout.SOUTH);
}
public static void main(String args[])
} ///:~
The first class, Branch, is a tool to take an array of String and build a DefaultMutableTreeNode with the first String as the root and the rest of the Strings in the array as leaves. Then node( ) can be called to produce the root of this "branch."
The Trees class contains a two-dimensional array of Strings from which Branches can be made and a static int i to count through this array. The DefaultMutableTreeNode objects hold the nodes, but the physical representation on screen is controlled by the JTree and its associated model, the DefaultTreeModel. Note that when the JTree is added to the applet, it is wrapped in a JScrollPane - this is all it takes to provide automatic scrolling.
The JTree is controlled through its model. When you make a change to the model, the model generates an event that causes the JTree to perform any necessary updates to the visible representation of the tree. In init( ), the model is captured by calling getModel( ). When the button is pressed, a new "branch" is created. Then the currently selected component is found (or the root if nothing is selected) and the model's insertNodeInto( ) method does all the work of changing the tree and causing it to be updated.
Most of the time an example like the one above will give you what you need in a tree. However, trees have the power to do just about anything you can imagine - everywhere you see the word "default" in the example above, you can substitute your own class to get different behavior. But beware: almost all of these classes have a large interface, so you could spend a lot of time struggling to understand the intricacies of trees.
Like trees, tables in Swing are vast and powerful. They are primarily intended to be the popular "grid" interface to databases via Java Database Connectivity (JDBC, discussed in Chapter 15) and thus they have a tremendous amount of flexibility, which you pay for in complexity. There's easily enough here to be the basis of a full-blown spreadsheet and could probably justify an entire book. However, it is also possible to create a relatively simple JTable if you understand the basics.
The JTable controls how the data is displayed, but the TableModel controls the data itself. So to create a JTable you'll typically create a TableModel first. You can fully implement the TableModel interface, but it's usually simpler to inherit from the helper class AbstractTableModel:
//: Table.java
// Simple demonstration of JTable
package c13.swing;
import java.awt.*;
import java.awt.event.*;
import com.sun.java.swing.*;
import com.sun.java.swing.table.*;
import com.sun.java.swing.event.*;
// The TableModel controls all the data:
class DataModel extends AbstractTableModel ,
,
,
};
// Prints data when table changes:
class TML implements TableModelListener
}
}
DataModel()
public int getColumnCount()
public int getRowCount()
public Object getValueAt(int row, int col)
public void
setValueAt(Object val, int row, int col)
public boolean
isCellEditable(int row, int col)
};
public class Table extends JPanel
public static void main(String args[])
} ///:~
DataModel contains an array of data, but you could also get the data from some other source such as a database. The constructor adds a TableModelListener which prints the array every time the table is changed. The rest of the methods follow the Beans naming convention, and are used by JTable when it wants to present the information in DataModel. AbstractTableModel provides default methods for setValueAt( ) and isCellEditable( ) that prevent changes to the data, so if you want to be able to edit the data, you must override these methods.
Once you have a TableModel, you only need to hand it to the JTable constructor. All the details of displaying, editing and updating will be taken care of for you. Notice that this example also puts the JTable in a JScrollPane, which requires a special JTable method.
Earlier in this chapter you were introduced to the positively medieval CardLayout, and saw how you had to manage all the switching of the ugly cards yourself. Someone actually thought this was a good design. Fortunately, Swing remedies this by providing JTabbedPane, which handles all the tabs, the switching, and everything. The contrast between CardLayout and JTabbedPane is breathtaking.
The following example is quite fun because it takes advantage of the design of the previous examples. They are all built as descendants of JPanel, so this example will place each one of the previous examples in its own pane on a JTabbedPane. You'll notice that the use of RTTI makes the example quite small and elegant:
//: Tabbed.java
// Using tabbed panes
package c13.swing;
import java.awt.*;
import com.sun.java.swing.*;
import com.sun.java.swing.border.*;
public class Tabbed extends JPanel ,
,
,
,
,
,
,
,
,
,
};
static JPanel makePanel(Class c) catch(Exception e)
sp.setBorder(new TitledBorder(title));
return sp;
}
public Tabbed()
public static void main(String args[])
} ///:~
Again, you can see the theme of an array used for configuration: the first element is the String to be placed on the tab and the second is the JPanel class that will be displayed inside of the corresponding pane. In the Tabbed( ) constructor, you can see the two important JTabbedPane methods that are used: addTab( ) to put a new pane in, and setSelectedIndex( ) to choose the pane to start with. (One in the middle is chosen just to show that you don't have to start with the first pane.)
When you call addTab( ) you supply it with the String for the tab and any Component (that is, an AWT Component, not just a JComponent, which is derived from the AWT Component). The Component will be displayed in the pane. Once you do this, no further management is necessary - the JTabbedPane takes care of everything else for you (as it should).
The makePanel( ) method takes the Class object of the class you want to create and uses newInstance( ) to create one, casting it to a JPanel (of course, this assumes that any class you want to add must inherit from JPanel, but that's been the structure used for the examples in this section). It adds a TitledBorder that contains the name of the class and returns the result as a JPanel to be used in addTab( ).
When you run the program you'll see that the JTabbedPane automatically stacks the tabs if there are too many of them to fit on one row.
Windowing environments commonly contain a standard set of message boxes that allow you to quickly post information to the user or to capture information from the user. In Swing, these message boxes are contained in JOptionPane. You have many different possibilities (some quite sophisticated), but the ones you'll most commonly use are probably the message dialog and confirmation dialog, invoked using the static JOptionPane.showMessageDialog( ) and JOptionPane. showConfirmDialog( ).
This section was meant only to give you an introduction to the power of Swing and to get you started so you could see how relatively simple it is to feel your way through the libraries. What you've seen so far will probably suffice for a good portion of your UI design needs. However, there's a lot more to Swing - it's intended to be a fully-powered UI design tool kit. If you don't see what you need here, delve into the online documentation from Sun and search the Web. There's probably a way to accomplish just about everything you can imagine.
Some of the topics that were not covered in this section include:
v More specific components such as JColorChooser, JFileChooser, JPasswordField, JHTMLPane (which performs simple HTML formatting and display), and JTextPane (a text editor that supports formatting, word wrap, and
images). These are fairly straightforward to use.
v The new event types for Swing. In many ways, these are like exceptions:
the type is what's important, and the name can be used to infer just about
everything else about them.
v New layout managers: Springs & Struts (a la
Smalltalk) and BoxLayout.
v Splitter control: a divider
style splitter bar that allows you to dynamically manipulate the position of
other components.
v JLayeredPane and JInternalFrame, used together to create child frame windows inside
parent frame windows, to produce multiple-document
interface (MDI)
applications.
v Pluggable look and feel, so you can write a single program that can
dynamically adapt to behave as expected under different platforms and operating
systems.
v Custom cursors.
v Dockable floating toolbars
with the JToolbar API.
v Double-buffering and Automatic repaint batching for smoother screen
redraws.
v Built-in "undo"
support.
v Drag and drop support.
At the time this section was written, the Swing library had been pronounced "frozen" by Sun, so this code should compile and run without problems as long as you've downloaded and installed the Swing library. (You should be able to compile one of Sun's included demonstration programs to test your installation.) If you do encounter difficulties, check www.BruceEckel.com for updated code.
[SE1] I suggest placing the superscript after Swing in "Introduction to Swing."
Politica de confidentialitate | Termeni si conditii de utilizare |
Vizualizari: 907
Importanta:
Termeni si conditii de utilizare | Contact
© SCRIGROUP 2024 . All rights reserved