Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

Subclassing question...

Posted on 1998-03-12
7
Medium Priority
?
220 Views
Last Modified: 2011-09-20
null
0
Comment
Question by:bjg
  • 4
  • 3
7 Comments
 
LVL 16

Accepted Solution

by:
imladris earned 100 total points
ID: 1233517
The first thing the multilinebutton does is call multilinelabel's paint method. Shortly AFTER, it calls setBackground. This will "cover" the string.

0
 

Author Comment

by:bjg
ID: 1233518
I also added update(Graphics g) inside the MultiLineLabel.  The problem is that when I process any of the mouseEvents, it seems to just keep repainting or something.  It's hard to explain, but if you want, I could send you the code, and you can test it and see what it is doing.  If this is ok, please send me your email address...
0
 

Author Comment

by:bjg
ID: 1233519
MultiLineLabel.java


import java.awt.*;
import java.util.StringTokenizer;

public class MultiLineLabel extends Canvas
{
      //Alignment Constants
          public static final int LEFT = 0, CENTER = 1, RIGHT = 2;

      protected String             m_label;
      protected int             m_alignment;

         protected int             m_marginWidth = 10;
          protected int             m_marginHeight = 10;
          protected int             m_numLines;
          protected String[]             m_lines;
          protected int[]             m_lineWidths;
          protected int             m_maxWidth;
          protected int             m_lineHeight;
          protected int             m_lineAscent;
          protected boolean             m_measured = false;

      /*** Two versions of the constructor ***/
          public MultiLineLabel(String label, int alignment)
      {
            this.m_label = label;
              this.m_alignment = alignment;
              processLabel();        
          }
   
          public MultiLineLabel(String label)
      {
            this(label, LEFT);
          }
   
      /*** Public Accessor Methods ***/
          public void setLabel(String label)
      {
            this.m_label = label;
              processLabel();
              m_measured = false;
              repaint();
          }
   
          public void setFont(Font f)
      {
            super.setFont(f);
            m_measured = false;
            repaint();
          }
   
          public void setForeground(Color c)
      {
            super.setForeground(c);
              repaint();
          }

      public void setBackground(Color c)
      {      
            super.setBackground(c);
            repaint();
      }
   
          public void setAlignment(int a)
      {
            m_alignment = a;
              repaint();
          }
   
          public String getLabel()
      {
              return m_label;
          }
   
          public int getAlignment()
      {
            return m_alignment;
          }
   
          public Dimension getPreferredSize()
      {
            if (!m_measured)
                  measure();
              return new Dimension(m_maxWidth + 2*m_marginWidth,
                             m_numLines * m_lineHeight + 2*m_marginHeight);
          }
   
          public Dimension getMinimumSize()
      {
            return getPreferredSize();
          }

      public void update(Graphics g)
      {
            System.out.println("in MultiLineLabel().update()");
            paint(g);
      }
   
      /*** Paint the graphics ***/
          public void paint(Graphics g)
      {
            int x, y;
              Dimension size = this.getSize();  
              if (!m_measured)
                  measure();
              y = m_lineAscent + (size.height - m_numLines * m_lineHeight)/2;
              for (int i = 0; i < m_numLines; i++, y += m_lineHeight)
            {
                  switch(m_alignment)
                  {
                            default:
                            case LEFT:      
                              x = m_marginWidth;
                              break;
                            case CENTER:    
                              x = (size.width - m_lineWidths[i])/2;
                              break;
                            case RIGHT:    
                              x = size.width - m_marginWidth - m_lineWidths[i];
                              break;
                  }
                  g.drawString(m_lines[i], x, y);
              }
          }
   
      /***
            This protected method parses through the label and checks
            for new line characters ('\n').  It also stores each line,
            the number of lines, and each line's width.
      ***/      
          protected void processLabel()
      {
            StringTokenizer t = new StringTokenizer(m_label, "\n");
              m_numLines = t.countTokens();
              m_lines = new String[m_numLines];
              m_lineWidths = new int[m_numLines];
              for (int i = 0; i < m_numLines; i++)
                  m_lines[i] = t.nextToken();
          }
   
      /***
            This protected method measures each line to determine the maximum
            width and height of the label.
      ***/
          protected void measure()
      {
            FontMetrics fm = this.getToolkit().getFontMetrics(this.getFont());
              m_lineHeight = fm.getHeight();
              m_lineAscent = fm.getAscent();
              m_maxWidth = 0;
              for (int i = 0; i < m_numLines; i++)
            {
                  m_lineWidths[i] = fm.stringWidth(m_lines[i]);
                  if (m_lineWidths[i] > m_maxWidth)
                        m_maxWidth = m_lineWidths[i];
              }
              m_measured = true;
          }
}
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 

Author Comment

by:bjg
ID: 1233520
Actually, MultiLineButton is called KeyButton

KeyButton.java

import java.awt.*;
import java.awt.event.*;
import java.util.*;

public class KeyButton extends MultiLineLabel
{
          private boolean pressed = true;
          private boolean isOn = false;

      private int width, height;
        private ActionListener actionListener;
          private String actionCommand;

           private Font m_font = new Font("SansSerif", Font.PLAIN, 9);

          private int keyvalue;

          public KeyButton(String label, ActionListener listener, int width,
                        int height, int alignment, int keyvalue)
      {
            super(label, alignment);

            this.width = width;
            this.height = height;
            this.keyvalue = keyvalue;
            this.actionListener = listener;
            this.actionCommand = String.valueOf(keyvalue);
            this.setFont(m_font);
            enableEvents(AWTEvent.MOUSE_EVENT_MASK);
          }

          public KeyButton(String label, ActionListener listener, int width,
                        int height, int keyvalue)
      {
            this(label, listener, width, height, CENTER, keyvalue);
          }
   
          public KeyButton(String label, ActionListener listener, int keyvalue)
      {
            this(label, listener, 30, 30, CENTER, keyvalue);
          }

      public int getKeyValue()
          {
            return keyvalue;
      }

      public void setKeyValue(int newval)
      {
            keyvalue = newval;
      }
   
          public void setKeyOn(boolean yesno)
          {
            isOn = yesno;
            repaint();
          }

          public boolean isKeyOn()
          {
            return isOn;
          }      
   
          public Dimension getPreferredSize()
      {
            if (!super.m_measured) super.measure();
                  return new Dimension(width,height);
          }
   
          public Dimension getMinimumSize()
      {
            return getPreferredSize();
          }

      public void update(Graphics g)
      {
            System.out.println("in KeyButton().update()");
            paint(g);
      }
   
          public void paint(Graphics g)
      {
            super.paint(g);

            int x, y;
              Dimension size = this.getSize();  

            if (isOn)
                  super.setBackground(Color.green);
              else
                  super.setBackground(Color.lightGray);

              if(pressed)
            {
                  //Make the button look like it is pressed.
                    g.setColor(Color.black);
                    g.drawRect(0,0,size.width-1, size.height-1);
              } else
            {
                  //Make the button look like it is raised.
                  g.setColor(Color.darkGray);
                    g.drawRect(0,0,size.width-1, size.height-1);
                  g.drawRect(0,0,size.width-2, size.height-2);
                    g.setColor(Color.white);
                    g.drawRect(1,1,size.width, size.height);
                  g.drawRect(2,2,size.width-2, size.height-2);
              }
          }
   
          public void addActionListener(ActionListener listener)
          {
                actionListener = AWTEventMulticaster.add(actionListener, listener);
            enableEvents(AWTEvent.MOUSE_EVENT_MASK);
          }

      public void removeActionListener(ActionListener listener)
      {
            actionListener = AWTEventMulticaster.remove(actionListener, listener);
         }

      public void setActionCommand(String command)
      {
            actionCommand = command;
      }

      public String getActionCommand()
      {
            return actionCommand;
      }

          public void processMouseEvent(MouseEvent e)
      {
            switch(e.getID())
            {
                      case MouseEvent.MOUSE_PRESSED:
                        pressed = true;
                        this.repaint();
                        break;
                      case MouseEvent.MOUSE_RELEASED:
                        if(actionListener != null)
                        {
                                 actionListener.actionPerformed(new ActionEvent(
                                     this, ActionEvent.ACTION_PERFORMED, actionCommand));
                        }
                        if (pressed)
                                  pressed = false;
                            this.repaint();
                        break;
                      case MouseEvent.MOUSE_ENTERED:
                            if (pressed)
                              pressed = false;
                        this.repaint();
                        break;
                      case MouseEvent.MOUSE_EXITED:
                        if (!pressed)
                                  pressed = true;
                        this.repaint();
                        break;
             }
             super.processMouseEvent(e);
         }
}



0
 
LVL 16

Expert Comment

by:imladris
ID: 1233521
Sorry, I appear to have been a bit too quick off the mark. I thought the setBackground call would floodfill the component with the specified colour. But closer inspection indicates that it is the update method that does that with a fillRect call. And you have correctly overridden the update method.

As for the repeating, the paint method in KeyButton is calling super.setBackground. And the setBackground method in Multilinelabel is calling repaint, which will (shortly) cause paint to be called again etc. etc.

setBackground and -Foreground should not call repaint. In fact there is no apparent need for them to be overridden at all. A call to setBackground will eventually bubble up the inheritance hierarchy far enough for the right thing to occur quite on its own.

0
 

Author Comment

by:bjg
ID: 1233522
Well, I took out the overridden setForeground and setBackground methods, and that has helped a little, but I am still having the problem where when I call mouseEntered() and I want the button to be raised, and then call mouseExited() and want the button to be sunken, it is not processing correctly.  The button's state initially is set to pressed, which makes the button appear pressed or sunken.  When the mouse enters over the button, the button's state is set to not pressed and I repaint(), and when the mouse exits the button, it's state is set to pressed and I repaint again.  Same goes true for mousePressed and mouseReleased.  But once I perform any of these actions, the button stays in the not pressed state.  Why is this happening?
0
 
LVL 16

Expert Comment

by:imladris
ID: 1233523
Sorry, I don't see the answer to that one. Your logic seems reasonably enough. When MOUSE_EXITED occurs the pressed variable will always be made true, and then a repaint is requested. This should cause paint to be executed with the press variable still in the true state. The only thing I can suggest here is to emit a print trail (with System.out.println or some such thing) to verify the execution path and variable states.

0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

INTRODUCTION Working with files is a moderately common task in Java.  For most projects hard coding the file names, using parameters in configuration files, or using command-line arguments is sufficient.   However, when your application has vi…
Introduction This article is the second of three articles that explain why and how the Experts Exchange QA Team does test automation for our web site. This article covers the basic installation and configuration of the test automation tools used by…
Viewers will learn about the different types of variables in Java and how to declare them. Decide the type of variable desired: Put the keyword corresponding to the type of variable in front of the variable name: Use the equal sign to assign a v…
Viewers will learn one way to get user input in Java. Introduce the Scanner object: Declare the variable that stores the user input: An example prompting the user for input: Methods you need to invoke in order to properly get  user input:
Suggested Courses

877 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question