Solved

Subclassing question...

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

Accepted Solution

by:
imladris earned 50 total points
Comment Utility
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
Comment Utility
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
Comment Utility
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
How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

 

Author Comment

by:bjg
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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

Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

Join & Write a Comment

After being asked a question last year, I went into one of my moods where I did some research and code just for the fun and learning of it all.  Subsequently, from this journey, I put together this article on "Range Searching Using Visual Basic.NET …
Java functions are among the best things for programmers to work with as Java sites can be very easy to read and prepare. Java especially simplifies many processes in the coding industry as it helps integrate many forms of technology and different d…
Viewers will learn about arithmetic and Boolean expressions in Java and the logical operators used to create Boolean expressions. We will cover the symbols used for arithmetic expressions and define each logical operator and how to use them in Boole…
The viewer will learn how to implement Singleton Design Pattern in Java.

762 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

Need Help in Real-Time?

Connect with top rated Experts

6 Experts available now in Live!

Get 1:1 Help Now