Customizing Components in Java
An Introduction |
Prof. David Bernstein |
Computer Science Department |
bernstdh@jmu.edu |
DefaultMetalTheme
package lookandfeel; import java.awt.*; import javax.swing.*; import javax.swing.plaf.*; import javax.swing.plaf.metal.*; /** * A theme for the Java Look-And-Feel that is in JMU * colors. */ public class JMUTheme extends DefaultMetalTheme { private ColorUIResource gold = new ColorUIResource(194,161, 77); private ColorUIResource darkGold = new ColorUIResource(143,118, 50); private ColorUIResource lightGold = new ColorUIResource(214,192,135); private ColorUIResource paleGold = new ColorUIResource(252,246,228); private ColorUIResource purple = new ColorUIResource( 69, 0,132); private ColorUIResource palePurple = new ColorUIResource(214,168,255); /** * The color to use for white areas * (e.g., the background of a JTextArea) */ public ColorUIResource getWhite() { return paleGold; } /** * The color to use for things like the border of tool tips */ protected ColorUIResource getPrimary1() { return purple; } /** * The color to use for things like the border of text highlighting */ protected ColorUIResource getPrimary2() { return purple; } /** * The color to use for things like text highlighting and the background * of tool tips */ protected ColorUIResource getPrimary3() { return palePurple; } /** * The color to use for things like the light line in etched borders */ protected ColorUIResource getSecondary1() { return lightGold; } /** * The color to use for things like buttons (when pressed) */ protected ColorUIResource getSecondary2() { return darkGold; } /** * The color to use for things like component backgrounds */ protected ColorUIResource getSecondary3() { return gold; } /** * The font to use for conrol text */ public FontUIResource getControlTextFont() { return new FontUIResource("Serif", Font.BOLD, 14); } /** * The font to use for menu text */ public FontUIResource getMenuTextFont() { return new FontUIResource("Serif", Font.BOLD, 14); } /** * The font to use for sub text */ public FontUIResource getSubTextFont() { return new FontUIResource("Serif", Font.PLAIN, 12); } /** * The font to use for system text (e.g., in tool tips) */ public FontUIResource getSystemTextFont() { return new FontUIResource("Sans Serif", Font.PLAIN, 10); } /** * The font to use for user text (e.g., in text components) */ public FontUIResource getUserTextFont() { return new FontUIResource("Serif", Font.PLAIN, 14); } /** * The font to use for window title text */ public FontUIResource getWindowTitleTextFont() { return new FontUIResource("Serif", Font.PLAIN, 16); } }
setCurrentTheme
method in
the MetalLookAndFeel
classpackage lookandfeel; import java.awt.*; import java.io.*; import javax.swing.*; import javax.swing.border.*; import javax.swing.plaf.metal.*; import gui.*; /** * An example that illustrates the use of themes * * @version 1.0 * @author Prof. David Bernstein, James Madison University */ public class ThemeDemo { /** * The entry point */ public static void main(String[] args) { CloseableFrame f; JComponent contentPane; JListEditor jle; JMUTheme theme; f = new CloseableFrame(); // Set the theme theme = new JMUTheme(); MetalLookAndFeel.setCurrentTheme(theme); // Re-load the look-and-feel try { UIManager.setLookAndFeel( "javax.swing.plaf.metal.MetalLookAndFeel"); } catch (ClassNotFoundException cnfe) { System.out.println("Couldn't set look and feel"); } catch (InstantiationException ie) { System.out.println("Couldn't set look and feel"); } catch (IllegalAccessException ie) { System.out.println("Couldn't set look and feel"); } catch (UnsupportedLookAndFeelException ie) { System.out.println("Couldn't set look and feel"); } contentPane = (JComponent)(f.getContentPane()); contentPane.setLayout(new BorderLayout()); jle = new JListEditor(); contentPane.add(jle, BorderLayout.CENTER); SwingUtilities.updateComponentTreeUI(f); f.setSize(400,300); f.setVisible(true); } }
PropertyChangeEvent
is dispatched to
all registered PropertyChangeListeners
JTree.lineStyle
:
JScrollBar.isFreeStanding
:
Boolean.FALSE
indicates that sides will
have an etched borders, Boolean.TRUE
indicates that only the top and left edges will have
etched borders)JSlider.isFilled
:
Boolean.TRUE
) or not
(Boolean.FALSE
)JToolBar.isRollover
:
Boolean.TRUE
etched border is displayed
only when the mouse is within its bounds and no border otherwise.
If Boolean.FALSE
, an etched border
is always displayedJInternalFrame.isPalette
:
Boolean.TRUE
, a thin border is used;
if Boolean.FALSE
, a thicker border is usedJComponent
creates a view, its
updateUI
method is calledLookAndFeel
class that are
used to "install" the view, the installBorder
and
installColorsAndFont
methodsupdateUI
method it
is possible to swap borders, colors, and fonts
between components
JTextArea
look like a JLabel
package gui; import java.awt.*; import javax.swing.*; /** * A component that contains text. This component is slightly * more versatile than a JLabel because it wraps at word * boundaries. * * @version 1.0 * @author Prof. David Bernstein */ public class WrappingLabel extends JTextArea { /** * Default constructor */ public WrappingLabel() { this(""); } /** * Explicit Value Constructor * * @param text The text on the label */ public WrappingLabel(String text) { super(text); // Set the wrapping behavior setLineWrap(true); setWrapStyleWord(true); // Make this TextComponent behave like a Lavel setEditable(false); setHighlighter(null); } /** * Reloads the pluggable UI. */ public void updateUI() { super.updateUI(); // Change the border (to the one used by Label objects) LookAndFeel.installBorder(this, "Label.border"); // Change the background color, foreground color, // and font (to those used by Label objects) LookAndFeel.installColorsAndFont(this, "Label.background", "Label.foreground", "Label.font" ); } }
import java.util.*; import javax.swing.*; /** * Show the name-value pairs associated with views * * @author Prof. David Benrstein, James Madison University * @version 1.0 */ public class ShowUIDefaults { /** * The entry point */ public static void main(String[] args) { Enumeration e; int i; String[] keys; UIDefaults defaults; defaults = UIManager.getDefaults(); keys = new String[defaults.size()]; e = defaults.keys(); i = 0; while (e.hasMoreElements()) { keys[i] = e.nextElement().toString(); i++; } Arrays.sort(keys); for (i=0; i < keys.length; i++) { System.out.println(keys[i]+"\t"+defaults.get(keys[i])); } } }
UIManager
class has a static method
named addAuxiliaryLookAndFeel
that allows you to
add to a multiplexing viewComponentUI
) and an extension of
LookAndFeel
that adds the
view to the "defaults"
package lookandfeel; import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.plaf.*; /** * A view for a JButton with (limited) audio * * @author Prof. David Benrstein, James Madison University * @version 1.0 */ public class AudioButtonUI extends ComponentUI implements MouseListener { private static AudioButtonUI instance = new AudioButtonUI(); private static Toolkit toolkit = Toolkit.getDefaultToolkit(); /** * Create the view (required) */ public static ComponentUI createUI(JComponent c) { return instance; } /** * Install the view on the given JComponent * * @param c The JComponent */ public void installUI(JComponent c) { c.addMouseListener(instance); } /** * Handle mouseClicked events (required by MouseListener) * * @param evt The MouseEvent */ public void mouseClicked(MouseEvent evt) { } /** * Handle mouseEntered events (required by MouseListener) * * @param evt The MouseEvent */ public void mouseEntered(MouseEvent evt) { Component source; source = (Component)(evt.getSource()); if (source.isEnabled()) toolkit.beep(); } /** * Handle mouseExited events (required by MouseListener) * * @param evt The MouseEvent */ public void mouseExited(MouseEvent evt) { } /** * Handle mousePressed events (required by MouseListener) * * @param evt The MouseEvent */ public void mousePressed(MouseEvent evt) { } /** * Handle mouseReleased events (required by MouseListener) * * @param evt The MouseEvent */ public void mouseReleased(MouseEvent evt) { } /** * Uninstall the view from the given JComponent * * @param c The JComponent */ public void uninstallUI(JComponent c) { c.removeMouseListener(instance); } /** * Update this component * * Specifically, do nothing. (The default implementation * will clear the component's background.) */ public void update(Graphics g, JComponent c) { } }
package lookandfeel; import java.awt.*; import javax.swing.*; import javax.swing.plaf.metal.*; /** * A LookAndFeel with (limited) audio * * @author Prof. David Benrstein, James Madison University * @version 1.0 */ public class AudioLookAndFeel extends MetalLookAndFeel { private static final String description = "A LookAndFeel with audio"; private static final String id = "edu.jmu.cs.bernstdh.AudioLF"; private static final String name = "Audio LookAndFeel"; /** * Get the UI Defaults for this LookAndFeel */ public UIDefaults getDefaults() { Object[] nvPair = {"ButtonUI","lookandfeel.AudioButtonUI"}; UIDefaults defaults; // Get the "normal" defaults defaults = super.getDefaults(); // Add the new default and fire a PropertyChangeEvent defaults.putDefaults(nvPair); return defaults; } /** * Get the long description */ public String getDescription() { return description; } /** * Get the String identifier */ public String getID() { return id; } /** * Get the name */ public String getName() { return name; } /** * Is this LF native to the OS? */ public boolean isNativeLookAndFeel() { return false; } /** * Is this LF supported on this OS? */ public boolean isSupportedLookAndFeel() { return true; } }
package lookandfeel; import java.applet.*; import java.awt.*; import java.io.*; import javax.swing.*; import javax.swing.border.*; import javax.swing.plaf.metal.*; import gui.*; /** * An example that illustrates the AudioLookAndFeel * * @version 1.0 * @author Prof. David Bernstein, James Madison University */ public class AudioLFDemo { /** * The entry point */ public static void main(String[] args) { AudioLookAndFeel audioLF; CloseableFrame f; JComponent contentPane; JListEditor jle; audioLF = new AudioLookAndFeel(); UIManager.addAuxiliaryLookAndFeel(audioLF); f = new CloseableFrame(); contentPane = (JComponent)(f.getContentPane()); contentPane.setLayout(new BorderLayout()); jle = new JListEditor(); contentPane.add(jle, BorderLayout.CENTER); f.setSize(400,300); f.setVisible(true); } }
package lookandfeel; import java.awt.*; import java.awt.geom.*; import javax.swing.*; import javax.swing.plaf.*; import javax.swing.plaf.basic.*; import javax.swing.plaf.metal.*; /** * A slider that uses the JMU Cupola for its "thumb" * * @author Prof. David Benrstein, James Madison University * @version 1.0 */ public class JMUSliderUI extends BasicSliderUI { private BoundedRangeModel model; private Image cupola; /** * Explicit Value Constructor */ public JMUSliderUI(JSlider slider) { super(slider); ImageIcon icon; this.slider = slider; this.model = slider.getModel(); icon = new ImageIcon("cupola_tiny.gif"); cupola = icon.getImage(); System.out.println("JMUSliderUI Constructor"); } /** * Create the view */ public static ComponentUI createUI(JComponent c) { // Return a new UI delegate since it may not // be stateless. This may be changed later. return new JMUSliderUI((JSlider)c); } /** * Paint the "thumb" of the slider * * @param g The RenderingEngine */ public void paintThumb(Graphics g) { Graphics2D g2; g2 = (Graphics2D)g; g.drawImage(cupola, thumbRect.x, thumbRect.y, null); } }
package lookandfeel; import java.awt.*; import javax.swing.*; import javax.swing.plaf.*; import javax.swing.plaf.metal.*; /** * A (partial) LookAndFeel that uses JMU visuals * * @author Prof. David Benrstein, James Madison University * @version 1.0 */ public class JMULookAndFeel extends MetalLookAndFeel { private static final String description = "A LookAndFeel for JMU"; private static final String id = "edu.jmu.cs.bernstdh.JMULF"; private static final String name = "JMU LookAndFeel"; /** * Get the long description */ public String getDescription() { return description; } /** * Get the String identifier */ public String getID() { return id; } /** * Get the name */ public String getName() { return name; } /** * Initialize the defaults */ protected void initClassDefaults(UIDefaults table) { String packageName; super.initClassDefaults(table); packageName = "lookandfeel"; table.put("SliderUI", packageName+".JMUSliderUI"); } }