7 Replies Latest reply: Mar 7, 2007 5:41 PM by 807606 RSS

    How to convert a String to an Icon

    807606
      Hello,

      I'm trying to figure out how to convert a String (specifically one letter) to an Icon for a JTree. The program I am working on uses .png files for the icons at the moment, with each .png being a single uppercase letter. However, recent discussion has us wanting to change to something more dynamic, since we anticipate needing new letters in the near future.

      My task is to modify the current codebase so that the Icons used to identify nodes in the tree are created from a Font within code, rather than reading in .png files. I have done some experimenting with creating a Label with just that String, setting the font and trying to extract the image using calls like createImage(int width, int height) and so on, but so far to no avail.


      If I could figure out how to at least convert the String to an image, I could probably make it work (since I can play around with creating an ImageIcon with that image). Thanks in advance for any help.


      Allan
        • 1. Re: How to convert a String to an Icon
          807606
          I don't know if I'd bother going the Image route. Interface Icon is dead simple:
          public interface Icon {
              int getIconWidth();
              int getIconHeight();
              void paintIcon(Component c, Graphics g,  int x, int y);
          }
          Try implementing that directly in your own class.
          • 2. Re: How to convert a String to an Icon
            807606
            Since you'll be creating them dynamically instead of loading a static set of files, you'll want to cache the ImageIcons after you create them so you don't end up regenerating the same image hundreds of times for one letter. When you need a letter, first try to get it from a hashmap cache. If it's not in the map, then create it and add it to the map. That way you create each letter once and save it.
            • 3. Re: How to convert a String to an Icon
              807606
              Don't forget to hand out dukes to the winners...
              • 4. Re: How to convert a String to an Icon
                807606
                Thanks DrLaszloJamf, I never thought of using my own Icon interface!

                If I use the Icon interface, would I just make some call to say, drawString (or something) to draw the character? My experience with GUIs is unfortunately limited (most of my work is involved with the backend, but I need to tweak some GUI support), so I appreciate the response!

                Allan
                • 5. Re: How to convert a String to an Icon
                  807606
                  Here is some quick and dirty code:
                  import java.awt.*;
                  import javax.swing.*;
                  
                  public class BasicIcon implements Icon {
                      private String text;
                  
                      public BasicIcon(String text) {
                          this.text = text;
                      }
                  
                      public int getIconWidth() {
                          return 16;
                      }
                  
                      public int getIconHeight() {
                          return 16;
                      }
                  
                      public void paintIcon(Component c, Graphics g,  int x, int y) {
                          Color old = g.getColor();
                          g.setColor(c.getForeground());
                          g.drawString(text, x, y+13);
                          g.setColor(old);
                      }
                  
                      public static void main(String[] args) {
                          JPanel cp = new JPanel();
                          for (char ch = 'A'; ch < 'F'; ++ch) {
                              cp.add(new JButton("letter " + ch, new BasicIcon(String.valueOf(ch))));
                          }
                  
                          JFrame f = new JFrame("BasicIcon");
                          f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                          f.setContentPane(cp);
                          f.pack();
                          f.setLocationRelativeTo(null);
                          f.setVisible(true);
                      }
                  }
                  One thing that could be improved is the vertical positioning of the letter in the Icon.
                  The x,y values passed into paintIcon are the upper-left hand corner of the icon,
                  but the y value needed by drawString is the position of the String's baseline.
                  To do it right, use one of Font's getLineMetrics methods and play around with ascent.
                  • 6. Re: How to convert a String to an Icon
                    807606
                    Thanks DrLaszloJamf, I never thought of using my own
                    Icon interface!

                    If I use the Icon interface, would I just make some
                    call to say, drawString (or something) to draw the
                    character? My experience with GUIs is unfortunately
                    limited (most of my work is involved with the
                    backend, but I need to tweak some GUI support), so I
                    appreciate the response!

                    Allan
                    Yes. Though you should look at the documentation for Icon and Graphics.drawString(String, int, int) considering the x and y in each don't represent the same thing. In one it is the top left corner, in the other it's the baseline. Hint: use Graphics.getFontMetrics() to find information like the line height using the current font.
                    • 7. Re: How to convert a String to an Icon
                      807606
                      Thanks for the code. I had started on something similar.

                      The only thing left to really work on is changing the font of the string before it gets painted, which it looks like I can do from Graphics.


                      Thanks again for all your help DrLaszloJamf.



                      EDIT: Excellent, this seems to be working. Now to just fine tune it. Thanks again to everyone for their contributions.

                      Message was edited by:
                      alanschu