Listing 6.1 Swing Design of a Component Called MyButton (TMyButton.java) // Application program that implements MyButton component. import javax.swing.*;import java.awt.*;import java.awt.event.*;class TMyButton extends JFrame { public TMyButton() { // 1. Assign a name to the frame, get the content pane of the // frame, and assign white color to the background of the // frame. super("My Button Frame"); Container contentPane = this.getContentPane(); contentPane.setBackground(Color.white); // 2. Assign an oval shaped look-and-feel to the buttons. // In reality, only the look is altered; the feel is not changed! // The default look-and-feel is rectangular and has the // program identifier "Default". // MyUIManager.setLookAndFeel("Default"); MyUIManager.setLookAndFeel("Oval"); // 3. Create a Play button object and set an action command. // Also register an action listener. MyButton playButton = new MyButton(); playButton.setText("Play"); playButton.setActionCommand("playbutton"); playButton.addActionListener(new ButtonListener()); // 4. Create a Stop button object and set an action command. // Also register an action listener. MyButton stopButton = new MyButton("Stop"); stopButton.setActionCommand("stopbutton"); stopButton.addActionListener(new ButtonListener()); // 5. Set the frame to the grid layout and add the Play and // Stop buttons. contentPane.setLayout(new GridLayout(1,2)); contentPane.add(playButton); contentPane.add(stopButton); // 6. Add the window listener to close the frame // and display it with the specified size. addWindowListener(new WindowEventHandler()); setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); setSize(300, 75); // width=300, height=75 show(); // Display the frame } // 7. Listener class to close the parent frame. class WindowEventHandler extends WindowAdapter { public void windowClosing(WindowEvent evt) { dispose(); System.exit(0); } } // 8. Action listener that receives events whenever the Play // or Stop button is clicked. class ButtonListener implements ActionListener { public void actionPerformed(ActionEvent evt) { MyButton button = (MyButton) evt.getSource(); if (button.getActionCommand().equals("playbutton")) { System.out.println("You clicked the Play button."); } else if (button.getActionCommand().equals("stopbutton")) { System.out.println("You clicked the Stop button."); } } } // 9. The main method. static public void main(String[] args) { new TMyButton(); } } // File Name: MyButton.java // 10.The component called MyButton that is built by using Swing design. import javax.swing.*;import javax.swing.plaf.*;import java.awt.*;import java.awt.event.*; // 11. The component class MyButton is a subclass of JComponent.class MyButton extends JComponent { MyButtonModel model = null; String text = ""; Font font = null; FontMetrics fontMetrics = null; int border = 10; boolean buttonPressed = false; // 12. MyButton constructor without any arguments. public MyButton() { this(null); } // 13. MyButton constructor that takes the text label argument. public MyButton(String text) { // Assign the data model to the component. setModel(new DefaultMyButtonModel()); // Initialize the text label. this.text = text; // Obtain the default font. font = getFont(); // If there is no default font, assign a new font. if (font == null) { font = new Font("SanSerif", Font.BOLD, 14); } // Retrieve the font metrics of the font. fontMetrics = getFontMetrics(font); // Register a mouse listener. addMouseListener(new ButtonMouseListener()); // Update the view of the button. updateUI(); } // 14. Method definition of update. public void updateUI() { // Assign proper look-and-feel for the view depending on the // specified look-and-feel. if (MyUIManager.getLookAndFeel().equals("Default")) { super.setUI(new MyButtonUI()); } else if (MyUIManager.getLookAndFeel().equals("Oval")) { super.setUI(new MyButtonOvalUI()); } } // 15. This class is the UI delegate. It has been defined as an // inner class to simplify the program. This class provides the default // view of the button. class MyButtonUI extends ComponentUI { // 16. Constructor. public MyButtonUI() { repaint(); // Call repaint for further actions. } // 17. Retrieve the minimum size of the component. public Dimension getMinimumSize() { int w = fontMetrics.stringWidth(text); int h = fontMetrics.getHeight(); return new Dimension(w+2*border, h+2*border); } // 18. Retrieve the preferred size of the component. public Dimension getPreferredSize() { return getMinimumSize(); } // 19. Retrieve the maximum size of the component. public Dimension getMaximumSize() { return new Dimension(Short.MAX_VALUE, Short.MAX_VALUE); } // 20. The update method definition. public void update(Graphics g, JComponent c) { if (c.isOpaque()) { g.setColor(c.getBackground()); g.fillRect(0,0,getWidth(), getHeight()); } paint(g, c); } // 21. The paint method definition. public void paint(Graphics g, JComponent c) { g.setFont(font); if (buttonPressed == false) { buttonView(g, Color.lightGray, Color.black); } else { buttonView(g, Color.gray, Color.white); } } // 22. The buttonView method definition. public void buttonView(Graphics g, Color background, Color foreground) { g.setColor(background); g.fill3DRect(0,0, getSize().width, getSize().height, true); g.setColor(foreground); int x = (getSize().width-fontMetrics.stringWidth(text))/2; int y = (getSize().height+fontMetrics.getHeight() -fontMetrics.getDescent())/2; g.drawString(text, x, y); } } // 23. Implementation of oval shaped look-and-feel for MyButton. // This view of the button is used as an alternative to its default view. class MyButtonOvalUI extends ComponentUI { // 24. Constructor. public MyButtonOvalUI() { repaint(); } // 25. Retrieve the minimum size of the component. public Dimension getMinimumSize() { int w = fontMetrics.stringWidth(text); int h = fontMetrics.getHeight(); return new Dimension(w+2*border, h+2*border); } // 26. Retrieve the preferred size of the component. public Dimension getPreferredSize() { return getMinimumSize(); } // 27. Retrieve the maximum size of the component. public Dimension getMaximumSize() { return new Dimension(Short.MAX_VALUE, Short.MAX_VALUE); } // 28. The update method definition. public void update(Graphics g, JComponent c) { if (c.isOpaque()) { g.setColor(c.getBackground()); g.fillRect(0,0,getWidth(), getHeight()); } paint(g, c); } // 29. The paint method definition. public void paint(Graphics g, JComponent c) { g.setFont(font); if (buttonPressed == false) { buttonView(g, Color.gray, Color.white); } else { buttonView(g, Color.lightGray, Color.black); } } // 30. The button view definition. public void buttonView(Graphics g, Color background, Color foreground) { g.setColor(background); g.fillOval(0,0, getSize().width, getSize().height); g.setColor(foreground); int x = (getSize().width-fontMetrics.stringWidth(text))/2; int y = (getSize().height+fontMetrics.getHeight() -fontMetrics.getDescent())/2; g.drawString(text, x, y); } } // 31. When the user presses or releases the mouse over a button, // the functionality from the implementation methods from this // mouse listener class are executed. class ButtonMouseListener extends MouseAdapter { public void mousePressed(MouseEvent evt) { requestFocus(); buttonPressed = true; ((MyButton) evt.getSource()).repaint(); } public void mouseReleased(MouseEvent evt) { buttonPressed = false; ((MyButton) evt.getSource()).repaint(); ActionEvent actionEvent = new ActionEvent( MyButton.this, ActionEvent.ACTION_PERFORMED, MyButton.this.getActionCommand()); processEvent(actionEvent); } } //Supports the action listener. ActionListener actionListener; // 32. Method to register an action listener with the button. public void addActionListener(ActionListener l) { actionListener = AWTEventMulticaster.add(actionListener, l); } // 33. To figure out the action events. protected void processEvent(AWTEvent evt) { if (evt instanceof ActionEvent) { processActionEvent((ActionEvent) evt); } else { super.processEvent(evt); } } // 34. To process the action events. protected void processActionEvent(ActionEvent evt) { if (actionListener != null) { // Execute the action performed from the listener class. actionListener.actionPerformed(evt); } } // 35. Method to assign the button model. public void setModel(MyButtonModel model) { this.model = model; } // 36. Retrieve the action model. public MyButtonModel getModel() { return model; } // 37. Assign the text label to the button. public void setText(String text) { this.text = text; invalidate(); repaint(); } // 38. Retrieve the text label of the button. public String getText() { return text; } // 39. To assign the action command. public void setActionCommand(String actionCommand) { getModel().setActionCommand(actionCommand); } // 40. To retrieve the action command. public String getActionCommand() { String ac = getModel().getActionCommand(); if (ac == null) { ac = getText(); } return ac; } } // 41. Define a simple button model interface. interface MyButtonModel { public void setActionCommand(String actionCommand); public String getActionCommand(); } // 42. Define the default button model class that implements the // MyButtonModel interface. class DefaultMyButtonModel implements MyButtonModel { protected String actionCommand = null; // 43. Assign an action command. public void setActionCommand(String actionCommand) { this.actionCommand = actionCommand; } // 44. Retrieve the action command that has been assigned. public String getActionCommand() { return actionCommand; } } // File Name: MyUIManager.java. // 45. The class MyUIManager. This class figures out the look-and-feel to be // assigned to a button object. The class contains static method that can // be invoked from the application class to assign the look-and-feel. class MyUIManager { // Store the look-and-feel string. static String lfType = "Default"; // 46. Assign a new look-and-feel. static public void setLookAndFeel(String type) { lfType = type; } // 47. Retrieve the current look-and-feel. static public String getLookAndFeel() { return lfType; } }