Java Swing phần 10 pdf

94 296 2
Java Swing phần 10 pdf

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

Java Swing - O’Reilly - 892 - JScrollBar. isFreeStanding Set to Boolean.FALSE by the Metal L&F for any scrollbars used by JScrollPanes. This setting just indicates that the scrollbar should be displayed flush against its borders. Normally, there is a small space around the scrollbar. Typically, you won't have reason to change this particular value. JSlider. isFilled Can be set to Boolean.TRUE to cause the slider's "track" to be filled on one side to clearly differentiate the space on either side of the "thumb." JToolBar. isRollover Can be set to Boolean.TRUE to cause the border on each of the toolbar's buttons to be replaced with a special rollover border. This border is the same as the button's default border, except that it is only painted when the cursor is over the button, meaning that at any given time, at most one button in the toolbar will have a border. Netscape users will recognize this feature from the toolbars in Navigator. JTree. lineStyle This property can be set to "Angled" or "None" (or the default, "Horizontal") to change the way the tree structure is drawn. By default, horizontal lines are drawn to separate branches of the tree. Setting this property to "Angled" causes short angled lines to be drawn between the nodes. As you might guess, setting it to "None" turns off both features. 26.4.5 Replacement of Individual UI Delegates Say you're using a L&F that you're basically happy with, but there are a few components you wish had a slightly different appearance. If the changes you want to make can't be done by simply changing resource values, one option is to implement your own custom UI delegates for the components you want to change and then tell the UIManager to use your new classes instead of the L&F defaults. 26.4.5.1 Modifying a Scrollbar We'll show how this can be done with a very simple example. We've decided to toss aside the nice, clean consistent design of the Metal L&F by changing the way the "thumb" of the scrollbar is displayed. To keep the code as simple as possible, we're going to change the thumb from the Metal style with textured bumps to a simple solid black box. We do not recommend making such random changes to existing L&Fs. In this particular example, we're breaking something the designers of the Metal L&F worked very hard to achieve— consistency. Keep in mind that this is an example that shows you how to do something. We'll leave it to you to have the good taste to know when to do it. To do this, we need to create our own implementation of the ScrollBarUI class. Rather than starting from scratch, we'll extend MetalScrollBarUI and change only the methods we want to reimplement. In this case, we find that there's a method called paintThumb() that's responsible for rendering the thumb of the scrollbar. This, along with createUI(), are the only methods we're going to reimplement. Here's the source code for our new scrollbar UI delegate. Java Swing - O’Reilly - 893 - // MyMetalScrollBarUI.java // import java.awt.*; import javax.swing.*; import javax.swing.plaf.*; import javax.swing.plaf.metal.*; // A simple extension of MetalScrollBarUI that draws the,thumb as a solid // black rectangle. public class MyMetalScrollBarUI extends MetalScrollBarUI { // Create our own scrollbar UI! public static ComponentUI createUI(JComponent c ) { return new MyMetalScrollBarUI(); } // This method paints the scroll thumb. We've just taken the // MetalScrollBarUI code and stripped out all the // interesting painting code, replacing it with code that paints a // black box. protected void paintThumb(Graphics g, JComponent c, Rectangle thumbBounds) { if (!c.isEnabled()) { return; } g.translate( thumbBounds.x, thumbBounds.y ); if ( scrollbar.getOrientation() == JScrollBar.VERTICAL ) { if ( !isFreeStanding ) { thumbBounds.width += 2; } g.setColor( Color.black ); g.fillRect( 0, 0, thumbBounds.width - 2, thumbBounds.height - 1 ); if ( !isFreeStanding ) { thumbBounds.width -= 2; } } else { // HORIZONTAL if ( !isFreeStanding ) { thumbBounds.height += 2; } g.setColor( Color.black ); g.fillRect( 0, 0, thumbBounds.width - 1, thumbBounds.height - 2 ); if ( !isFreeStanding ) { thumbBounds.height -= 2; } } g.translate( -thumbBounds.x, -thumbBounds.y ); } } Pretty simple stuff. The first thing we did was define a new createUI() method. Recall that this is the method JComponent calls when it is assigned a new UI delegate. All we do is return a new instance of our modified scrollbar delegate. The second method in our class is basically just a stripped-down version of MetalScrollBarUI's paintThumb() method. In our implementation, we've removed all the code that created a nice clean thumb, complete with shading and texture bumps, replacing it with single calls to Graphics.fillRect(). Since we've extended MetalScrollBarUI, our new scrollbar delegate will look just like the Metal scrollbar, except for the solid black thumb. Java Swing - O’Reilly - 894 - The only thing left to do is tell the UIManager to use our custom scrollbar delegate instead of the L&F default. You can probably guess that this is simple. Here's what we do: UIManager.put("ScrollBarUI", "MyMetalScrollBarUI"); Due to a change in the JDK1.2 class loading scheme, this example does not work properly with JKD1.2 beta4 (it works fine with JDK1.1). To run this example, execute the oldjava interpreter instead of java. This problem should be cleared up in the next release of JDK1.2. Once we make this call, any new scrollbars that get created will use our custom UI delegate, instead of the previously installed MetalScrollBarUI. Here's a little test program that proves that this works: // MetalModExample.java // import javax.swing.*; import java.awt.*; import java.io.*; public class MetalModExample { public static void main(String[] args) { JComponent before = makeExamplePane(); // Replace the MetalScrollBarUI with our own! UIManager.put("ScrollBarUI", "MyMetalScrollBarUI"); JComponent after = makeExamplePane(); JFrame f = new JFrame(); f.addWindowListener(new BasicWindowMonitor()); Container c = f.getContentPane(); c.setLayout(new GridLayout(2, 1, 0, 1)); c.add(before); c.add(after); f.setSize(450, 400); f.setVisible(true); } // Create a scroll pane with a text area in it. public static JComponent makeExamplePane() { JTextArea text = new JTextArea(); try { text.read(new FileReader("MetalModExample.java"), null); } catch (IOException ex) {} JScrollPane scroll = new JScrollPane(text); return scroll; } } We create two JScrollPanes, which use JScrollBars. The first one is created with the default scrollbar delegate. Then, we tell the UIManager to use our new UI delegate and create a second JScrollPane. Figure 26.11 shows the different scrollbars created by this example. Figure 26.11. Standard and customized Metal scrollbars Java Swing - O’Reilly - 895 - In this section, we've seen how easy it is to replace a single UI delegate. If you're creating a custom application, and you want to change specific components, this is a nice, easy way to make the changes. However, if you develop a set of custom delegates that you're particularly happy with, you might want to consider rolling them into your own custom L&F, so you don't have to install each delegate in every program you write. The next section explores your options for creating a custom L&F. 26.5 Creation of a Custom L&F Everything we've covered in this chapter up to this point has been useful background information for the ultimate application customization strategy—creating your own look-and-feel. As you might guess, this is not something you'll do in an afternoon. However, thanks to the improvements made in the L&F framework (as of the JDK 1.2 beta 4 release), it's not as difficult as you might think. You'll likely find that the most difficult part is coming up with graphical design for each component. There are basically three different strategies for creating a new L&F: • Start from ground zero by extending LookAndFeel and extending each of the UI delegates defined in javax.swing.plaf. • Extend the BasicLookAndFeel and each of the abstract UI delegates defined in javax.swing.plaf.basic. • Extend an existing L&F, like MetalLookAndFeel, and change only selected components. The first option gives you complete control over how everything works. It also requires a lot of effort. Unless you are implementing an L&F that is fundamentally different from the traditional desktop L&Fs, or you have some strong desire to implement your own L&F framework from scratch, we strongly recommend that you do not use this approach. The next option is the most logical if you want to create a completely new L&F. This is the approach we'll focus on in this section. The BasicLookAndFeel has been designed (well, actually it's been significantly re-designed as of JDK 1.2 beta 4) as an abstract framework for creating new L&Fs. Each of the Swing L&Fs extends Basic. The beauty of using this approach is that the Java Swing - O’Reilly - 896 - majority of the programming logic is handled by the framework—all you really have to worry about is how the different components should look. The third option makes sense if you want to use an existing L&F, but just want to make a few tweaks to certain components. If you go with this approach, you need to be careful not to do things that will be confusing to your users. Remember, people expect existing L&Fs to behave in certain familiar ways. 26.5.1 The PlainLookAndFeel We'll discuss the process of creating a custom L&F by way of example. In this section, we'll define bits and pieces of an L&F called PlainLookAndFeel. The goal of this L&F is to be as simple as possible. We won't be doing anything fancy with colors, shading, or painting—this book is long enough without filling pages with fancy paint() implementations. Instead, we'll focus on how to create an L&F. All of our painting will be done in black, white, and gray, and we'll use simple, single-width lines. It won't be pretty, but we hope it will be educational. 26.5.2 Creating the LookAndFeel Class The logical first step in the implementation of a custom L&F is the creation of the LookAndFeel class itself. As we've said, the BasicLookAndFeel serves as a nice starting point. At a minimum, you'll need to implement the five abstract methods defined in the LookAndFeel base class (none of which is implemented in BasicLookAndFeel). Here's a look at the beginning's of our custom L&F class: // PlainLookAndFeel.java // package plain; import java.awt.*; import javax.swing.*; import javax.swing.border.*; import javax.swing.plaf.*; import javax.swing.plaf.basic.*; public class PlainLookAndFeel extends BasicLookAndFeel { public String getDescription() { return "The Plain Look and Feel"; } public String getID() { return "Plain"; } public String getName() { return "Plain"; } public boolean isNativeLookAndFeel() { return false; } public boolean isSupportedLookAndFeel() { return true; } // . . . } At this point, we've got an L&F that will actually compile. Let's go a little further and make it useful. The next major step is to define the defaults for the L&F. This is similar to what we did earlier when we defined a few custom resources for an application. The difference is that now we will be defining a complete set of resources for an entirely new L&F that can be used across many applications. The installation of defaults is handled by getDefaults() which has been broken down into three additional methods in BasicLookAndFeel. Due to a change in the JDK1.2 class loading scheme, the use of custom L&Fs does not work properly with JDK1.2 beta4 (it works fine with JDK1.1). To use the code shown in this section, execute the oldjava interpreter instead of java. This problem should be cleared up in the next JDK1.2 release. Java Swing - O’Reilly - 897 - BasicLookAndFeel.getDefaults() creates a UIDefaults table and calls the following three methods (in this order): protected void initClassDefaults(UIDefaults table) protected void initSystemColorDefaults(UIDefaults table) protected void initComponentDefaults(UIDefaults table) Let's look at these three steps in detail. 26.5.2.1 Defining Class Defaults Defining class defaults is the process of enumerating the names of the classes your L&F will use for each of the UI delegates. One nice feature of the BasicLookAndFeel is that it defines concrete implementations of all of the UI-delegate classes. One big benefit is that you can test your new L&F as you're creating it, without having to specify every single delegate class. Instead, just define the ones you want to test and use the basic implementations for the others. Those that you define (since they're stored in a simple Hashtable) will override any values previously defined by BasicLookAndFeel. A typical implementation of this method looks something like this: protected void initClassDefaults(UIDefaults table) { super.initClassDefaults(table); // install the "basic" delegates String plainPkg = "plain."; Object[] classes = { "ProgressBarUI", plainPkg + "PlainProgressBarUI", "SliderUI", plainPkg + "PlainSliderUI", "TreeUI", plainPkg + "PlainTreeUI", // . . . etc }; table.putDefaults(classes); } The first line calls the BasicLookAndFeel implementation, which installs each of the basic UI delegates. Next, we create a string containing the package name for our L&F classes. This will be used in constructing the class names of each of our UI delegates. We then create an array of UIClassID to UI-delegate class name mappings. The items in this array should alternate between class IDs [7] and class names. Include such a mapping for each UI delegate your L&F implements. [7] The UIClassID property for all Swing components can be formed by dropping the J from the class name and adding UI at the end. JButton's UIClassID is ButtonUI, JTree's is TreeUI, etc. 26.5.2.2 Defining L&F Colors The next set of defaults typically defined are the color resources used by the L&F. You have a lot of flexibility here in terms of how you handle colors. As we saw earlier in the chapter, the Metal L&F defines all colors in terms of a color "theme," allowing the colors used by the L&F to be easily customized. This feature is specific to Metal, but you can implement a similar feature in your own L&F. Colors are typically defined according to the colors specified in the java.awt.SystemColor class. These are the colors used by the BasicLookAndFeel, so if you are going to default any of the painting routines to Basic, it's important to define values for the system colors. Even if you are Java Swing - O’Reilly - 898 - going to handle every bit of painting in your custom L&F, it's still a good idea, though it is not required, to use the familiar color names. BasicLookAndFeel adds another protected method called loadSystemColors(). For non-native L&Fs, this simply maps an array of color name/color value pairs into resource keys and ColorUIResource values. For example, a pair of entries in the array might be: "control", "#FFFFFF" This would result in a resource called "control" being added, with a value of the color white. The conversion from #FFFFFF to Color.white is done by the java.awt.Color.decode() method (which uses java.lang.Integer.decode()). This method takes a string representation of a color and converts it to a valid Color object. In this case, the # character indicates that we are specifying a hexadecimal (base-16) number. (You can also use the familiar 0x notation.) The first two characters (one byte) represent the red component of the color. The next two represent green, and the last two represent blue. In this example, all values are FF (255 decimal), which maps to the color white. Using loadSystemColors() allows you to define the color values for your L&F by creating an array of key/value pairs, like the pair we just looked at. This array is then passed to loadSystemColors(), along with the UIDefaults table. Here's a sample implementation of initSystemColorDefaults(): protected void initSystemColorDefaults(UIDefaults table) { String[] colors = { "desktop", "#C0C0C0", "activeCaption", "#FFFFFF", "activeCaptionText", "#000000", "activeCaptionBorder", "#000000" // more of the same . . . }; loadSystemColors(table, colors, false); } Table 26.9 shows the 26 color keys defined by SystemColor and used by the BasicLookAndFeel. Table 26.9, Standard System Color Properties System Color Property Description desktop Color of the desktop background activeCaption Color of the titlebar (captions) when the frame is active activeCaptionText Color of the titlebar text when the frame is active activeCaptionBorder Color of the titlebar border when the frame is active inactiveCaption Color of the titlebar (captions) when the frame is inactive inactiveCaptionText Color of the titlebar text when the frame is inactive inactiveCaptionBorder Color of the titlebar border when the frame is inactive window Color of the interior of the window windowBorder Color of the window border windowText Color of the window text menu Background color of menus menuText Color of the text in menu items text Background color of editable text textText Color of editable text textHighlight Background color of editable text when highlighted Java Swing - O’Reilly - 899 - textHighlightText Color of editable text when highlighted textInactiveText Color of normally editable text that has been disabled. control Standard color for controls such as buttons or scrollbar thumbs controlText Color for text inside controls controlHighlight Highlight color for controls controlLtHighlight Lighter highlight color for the controls controlShadow Shadow color for controls controlDkShadow Darker shadow color for the controls scrollbar Color to use for the background area of a scrollbar (where the thumb slides) info Background color for informational text infoText Color for informational text 26.5.2.3 Defining Component Defaults The last method called by BasicLookAndFeel.getDefaults() is initComponentDefaults(). This is where you define all of the colors, icons, borders, and other resources used by each of the individual component delegates. The BasicLookAndFeel implementation of this method defines over 300 different resource values for 40 delegate classes. We've cataloged this long list of resources, along with the type of value expected for each, in Appendix A. The good news is that you don't have to redefine all 300+ resource values in your custom L&F, though you certainly can if you want. Many of the resources are colors and are defined in terms of the system colors we've already defined. For example, the Button.background resource defaults to the value defined for "control" while Button.foreground defaults to "controlText". As long as you've defined values for the system colors and you're happy with the mappings to these system colors defined by the BasicLookAndFeel, you can get by with little or no changes to the component-level color resources. The amount of customization done in this method is really up to you. If you like the resource choices made by the BasicLookAndFeel, use them. If you want your own custom defaults, you can change them. There are a few useful steps used by the Swing L&Fs that will make the implementation of this method easier to understand. We'll discuss these in the following. Define Fonts Chances are there's a fixed set of fonts your L&F will use throughout its delegates. It's a good idea to define these up-front, so you're not creating duplicate font resources throughout the method. Recall from earlier in the chapter that resources defined by the L&F should implement the UIResource interface, so we'll create our fonts as FontUIResource objects. You might choose to define a few fonts like this: FontUIResource sansSerifPlain10 = new FontUIResource("SansSerif", Font.PLAIN, 10); FontUIResource monospacedPlain10 = new FontUIResource("Monospaced", Font.PLAIN, 10); Define Colors If you plan to use colors not defined by the system colors, and you're not using a flexible color strategy like Metal's themes, remember to define these colors as ColorUIResources. For example: ColorUIResource green = new ColorUIResource(Color.green); ColorUIResource veryLightGray = new ColorUIResource(240, 240, 240); Java Swing - O’Reilly - 900 - Define Insets Several of the resource values are defined as java.awt.Insets. Again, it's convenient to define these values up-front. For example: InsetsUIResource zeroInsets = new InsetsUIResource(0,0,0,0); InsetsUIResource bigInsets = new InsetsUIResource(10,10,10,10); Define Borders If you're going to use the standard Swing borders for your components, recall that you can obtain singleton resource borders from the BorderUIResource class. For example: Border etchedBorder = BorderUIResource.getEtchedBorderUIResource(); Border blackLineBorder = BorderUIResource.getBlackLineBorderUIResource(); This works great for defining simple borders. However, it's often useful to define dynamic borders that change based on the state of the component they are bordering. For example, when a button is pressed, it often draws its border differently than when it is in the default raised position. The Basic L&F provides a class called BasicBorders that includes inner classes for several common dynamic borders. We'll cover this class at the end of the chapter. Define Icons Several components define a variety of Icon resources. There are two distinct types of icons you'll want to define: static and dynamic. Static icons are usually (though not always) ImageIcons, loaded from small GIF files. They are used for things like tree nodes and JOptionPane dialogs. It's generally a good idea to define static icons using the UIDefaults.LazyValue class (discussed earlier in the chapter) to avoid loading the images in applications that don't use the components they are associated with. The easiest strategy is just to use LookAndFeel.makeIcon() method, which returns LazyValue objects, to load an icon from the location of your L&F classes. For example, to load an image called warning.gif from the icons directory directly under the directory containing your L&F classes, you would use the following code: Object warningIcon = LookAndFeel.makeIcon(getClass(), "icons/warning.gif"); Table 26.10 summarizes the default icons loaded by BasicLookAndFeel. If you use the default resource values for these icons, be sure to supply an image for each of the icons (in the icons subdirectory). No default image files are defined. Table 26.10, Image Icons Defined by BasicLookAndFeel Resource Name Filename FileChooser.detailsViewIcon DetailsView.gif FileChooser.homeFolderIcon HomeFolder.gif FileChooser.listViewIcon ListView.gif FileChooser.newFolderIcon NewFolder.gif FileChooser.upFolderIcon UpFolder.gif FileView.computerIcon Computer.gif FileView.directoryIcon Directory.gif FileView.fileIcon File.gif FileView.floppyDriveIcon FloppyDrive.gif Java Swing - O’Reilly - 901 - FileView.hardDriveIcon HardDrive.gif InternalFrame.icon JavaCup.gif OptionPane.errorIcon Error.gif OptionPane.informationIcon Inform.gif OptionPane.questionIcon Question.gif OptionPane.warningIcon Warn.gif Tree.closedIcon TreeClosed.gif Tree.leafIcon TreeLeaf.gif Tree.openIcon TreeOpen.gif It's more challenging to define icons that change based on the state of a component. The most obvious examples of dynamic icons are radio buttons and checkboxes. These icons paint themselves differently depending on whether or not they are selected and, typically, whether or not they are currently being pressed. We'll look at a strategy for implementing dynamic icons in a few pages. Define Other Resources A variety of other resources, including Dimensions and Integer values can also be defined as component resources. Remember, you can refer to Appendix A for a complete list. Create Defaults Array Now that you've defined all the common resources that might be shared by multiple components, it's time to put together an array of key/value pairs for the resources you want to define. This array is typically handled just like the others we've seen up to this point— entries in the array alternate between resource keys and values. Since there are potentially a very large number of resources being defined here, it's a good idea to group resources by component. Here's part of our PlainLookAndFeel defaults array definition: Object[] defaults = { "Button.border", buttonBorder, "Button.margin", new InsetsUIResource(2, 2, 2, 2), "Button.font", sansSerifPlain10, "RadioButton.icon", radioButtonIcon, "RadioButton.pressed", table.get("controlLtHighlight"), "RadioButton.font", sansSerifPlain10, "CheckBox.icon", checkBoxIcon, "CheckBox.pressed", table.get("controlLtHighlight"), "CheckBox.font", sansSerifPlain10, "Slider.foreground", table.get("controlText") }; Note that you aren't limited to the resources listed in Appendix A. In Table 26.10, we've added two custom resources called RadioButton.pressed and CheckBox.pressed which we'll use as background colors when the button is being pressed. Two Little Details We've covered almost everything you have to think about when implementing initComponentDefaults(). There are two last important steps (one at the beginning and [...]... implemented the radio button icon: // PlainIconFactory .java // package plain; import import import import java. awt.*; javax .swing. *; javax .swing. plaf.*; java. io.Serializable; public class PlainIconFactory implements Serializable { private static Icon radioButtonIcon; private static Icon checkBoxIcon; // implemention trimmed from example - 902 - Java Swing - O’Reilly // Provide access to the single RadioButtonIcon... default borders provided by Basic, or even to use the simple borders defined by the swing. border package Here's the PlainBorders class in which we define a single inner class for handling button borders: // PlainBorders .java // package plain; import import import import java. awt.*; javax .swing. *; javax .swing. border.*; javax .swing. plaf.*; public class PlainBorders { // An inner class for JButton borders... as an argument, but since BasicSliderUI just ignores it anyway, we just pass a null Here's the beginning of our PlainSliderUI class: // PlainSliderUI .java // package plain; import java. awt.*; import javax .swing. *; import javax .swing. plaf.*; import javax .swing. plaf.basic.*; public class PlainSliderUI extends BasicSliderUI { // public PlainSliderUI() { super(null); // basic ignores the parameter anyway... ClockLabel // ClockLabel .java // An extension of the JLabel class that listens to events from // a Timer object to update itself with the current date & time // import java. util.*; import java. awt.event.*; import javax .swing. *; public class ClockLabel extends JLabel implements ActionListener { public ClockLabel() { - 919 - Java Swing - O’Reilly } } super("" + new Date()); Timer t = new Timer (100 0, this); t.start();... setText("" + new Date()); } And here's the application that displays the ClockLabel object: // ClockTest .java // A demonstration framework for the Timer driven ClockLabel class // import javax .swing. *; import java. awt.*; public class ClockTest extends JFrame { public ClockTest() { super("Timer Demo"); setSize(300, 100 ); addWindowListener(new BasicWindowMonitor()); } } ClockLabel clock = new ClockLabel(); getContentPane().add(clock,... null is returned 27.1.2 The SwingConstants Interface This interface defines the location constants shown in Table 0-1 that are used throughout the Swing package Quite often, this interface is implemented by a component so that the constants appear as regular parts of the class for ease of use (The JLabel and SwingUtilities classes are examples of such classes.) Table 27.1, SwingConstants Constants Constant... combine pending events into one single event (to help listeners keep up) For example, if the timer fires a tick every 10 milliseconds, but the application is busy and has not handled events for 100 milliseconds, 10 action events are queued up for delivery If coalesce is false, all 10 of these will be delivered in rapid succession If coalesce is true (the default) only one event will be fired The logTimers... Certain Swing components are typically rendered with some type of border around them The javax .swing. border package defines a number of static borders that you can use However, it's often desirable to create your own custom borders as part of your L&F Also, certain borders (just like certain icons) should be painted differently depending on the state of the object they are being painted around The Swing. .. invokeAndWait() methods, check out Chapter 28 27.1.1.1 Constructor public SwingUtilities() The constructor for SwingUtilities is public, but all of the public methods are static, so you will not need to create an instance 27.1.1.2 Class Methods public static Rectangle[] computeDifference(Rectangle rectA, Rectangle rectB) - 913 - Java Swing - O’Reilly Returns the regions in rectA that do not overlap with... lightWeightPopupEnabled property is true, all -Java tooltips will be used A false value indicates native tooltips should be used Table 27.3, ToolTipManager Properties Property Data Type - 920 - get is set bound Default Value Java Swing - O’Reilly dismissDelay enabled initialDelay lightWeightPopupEnabled[1] reshowDelay [1] int boolean int boolean int 4000 true 750 true 500 Deprecated as of Swing 1.1/JDK1.2 beta4 27.1.4.2 . scrollbar UI delegate. Java Swing - O’Reilly - 893 - // MyMetalScrollBarUI .java // import java. awt.*; import javax .swing. *; import javax .swing. plaf.*; import javax .swing. plaf.metal.*; . class: // PlainLookAndFeel .java // package plain; import java. awt.*; import javax .swing. *; import javax .swing. border.*; import javax .swing. plaf.*; import javax .swing. plaf.basic.*; public. our PlainSliderUI class: // PlainSliderUI .java // package plain; import java. awt.*; import javax .swing. *; import javax .swing. plaf.*; import javax .swing. plaf.basic.*; public class PlainSliderUI

Ngày đăng: 12/08/2014, 19:21

Từ khóa liên quan

Tài liệu cùng người dùng

Tài liệu liên quan