How can I convert an Icon to an Image

前端 未结 3 979
隐瞒了意图╮
隐瞒了意图╮ 2020-12-10 10:30

I\'m trying to convert an Icon (javax.swing.Icon) to an Image (java.awt.Image) using this code:

private Image iconToImage(Icon icon         


        
相关标签:
3条回答
  • 2020-12-10 11:10

    Try this:

    icon.paintIcon(new JCheckBox(), image.getGraphics(), 0, 0);
    

    I can't exactly explain why it needs a JCheckBox though. Perhaps it varies for the icon? The NullPointerException was from this line in MetalIconFactory for "CheckBox.icon":

    ButtonModel model = ((JCheckBox)c).getModel();
    
    0 讨论(0)
  • 2020-12-10 11:15

    Try this :

    static Image iconToImage(Icon icon) {
       if (icon instanceof ImageIcon) {
          return ((ImageIcon)icon).getImage();
       } 
       else {
          int w = icon.getIconWidth();
          int h = icon.getIconHeight();
          GraphicsEnvironment ge = 
            GraphicsEnvironment.getLocalGraphicsEnvironment();
          GraphicsDevice gd = ge.getDefaultScreenDevice();
          GraphicsConfiguration gc = gd.getDefaultConfiguration();
          BufferedImage image = gc.createCompatibleImage(w, h);
          Graphics2D g = image.createGraphics();
          icon.paintIcon(null, g, 0, 0);
          g.dispose();
          return image;
       }
     }
    

    A complete example where we take a laf-provided icon, convert it to an Image and use it for on the Windows System Tray.

    import java.awt.*;
    import java.awt.image.*;
    import java.awt.event.*;
    import javax.swing.*;
    
    public class SysTrayDemo {
        protected static TrayIcon trayIcon;
        private static PopupMenu createTrayMenu() {
            ActionListener exitListener = new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    System.out.println("Bye from the tray");
                    System.exit(0);
                }
            };
    
            ActionListener executeListener = new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    JOptionPane.showMessageDialog
                       (null, "Popup from the action on the systray!",
                        "User action", JOptionPane.INFORMATION_MESSAGE);
                    trayIcon.displayMessage
                       ("Done", "You can do it again if you want!", 
                        TrayIcon.MessageType.INFO);
                }
            };
    
            PopupMenu menu = new PopupMenu();
            MenuItem execItem = new MenuItem("Action...");
            execItem.addActionListener(executeListener);
            menu.add(execItem);
    
            MenuItem exitItem = new MenuItem("Exit");
            exitItem.addActionListener(exitListener);
            menu.add(exitItem);
            return menu;
        }
    
        /**
         * using a built-in icon
         * we need to convert the icon to an Image
         */
        private static TrayIcon createTrayIconFromBuiltInIcon() {
            Icon icon = UIManager.getIcon("OptionPane.warningIcon");
            PopupMenu popup = createTrayMenu();
            Image image = iconToImage(icon);
            TrayIcon ti = new TrayIcon(image, "Java System Tray Demo", popup);
            ti.setImageAutoSize(true);
            return ti;
        }
    
        static Image iconToImage(Icon icon) {
              if (icon instanceof ImageIcon) {
                  return ((ImageIcon)icon).getImage();
              } else {
                  int w = icon.getIconWidth();
                  int h = icon.getIconHeight();
                  GraphicsEnvironment ge = 
                    GraphicsEnvironment.getLocalGraphicsEnvironment();
                  GraphicsDevice gd = ge.getDefaultScreenDevice();
                  GraphicsConfiguration gc = gd.getDefaultConfiguration();
                  BufferedImage image = gc.createCompatibleImage(w, h);
                  Graphics2D g = image.createGraphics();
                  icon.paintIcon(null, g, 0, 0);
                  g.dispose();
                  return image;
              }
          }
    
        public static void main(String[] args) throws Exception {
            if (!SystemTray.isSupported()) {
                System.out.println
                   ("System tray not supported on this platform");
                System.exit(1);
            }
    
            try {
                SystemTray sysTray = SystemTray.getSystemTray();
                trayIcon = createTrayIconFromBuiltInIcon();
                sysTray.add(trayIcon);
                trayIcon.displayMessage("Ready",
                    "Tray icon started and tready", TrayIcon.MessageType.INFO);
            }
            catch (AWTException e) {
                System.out.println("Unable to add icon to the system tray");
                System.exit(1);
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-10 11:24

    Just found a code snippet which might help if you want to wrap those misbehaving LAF provided icons more often:

    /**
     * Some ui-icons misbehave in that they unconditionally class-cast to the 
     * component type they are mostly painted on. Consequently they blow up if 
     * we are trying to paint them anywhere else (f.i. in a renderer).  
     * 
     * This Icon is an adaption of a cool trick by Darryl Burke/Rob Camick found at
     * http://tips4java.wordpress.com/2008/12/18/icon-table-cell-renderer/#comment-120
     * 
     * The base idea is to instantiate a component of the type expected by the icon, 
     * let it paint into the graphics of a bufferedImage and create an ImageIcon from it.
     * In subsequent calls the ImageIcon is used. 
     * 
     */
    public static class SafeIcon implements Icon {
    
        private Icon wrappee;
        private Icon standIn;
    
        public SafeIcon(Icon wrappee) {
            this.wrappee = wrappee;
        }
    
        @Override
        public int getIconHeight() {
            return wrappee.getIconHeight();
        }
    
        @Override
        public int getIconWidth() {
            return wrappee.getIconWidth();
        }
    
        @Override
        public void paintIcon(Component c, Graphics g, int x, int y) {
            if (standIn == this) {
                paintFallback(c, g, x, y);
            } else if (standIn != null) {
                standIn.paintIcon(c, g, x, y);
            } else {
                try {
                   wrappee.paintIcon(c, g, x, y); 
                } catch (ClassCastException e) {
                    createStandIn(e, x, y);
                    standIn.paintIcon(c, g, x, y);
                }
            }
        }
    
        /**
         * @param e
         */
        private void createStandIn(ClassCastException e, int x, int y) {
            try {
                Class<?> clazz = getClass(e);
                JComponent standInComponent = getSubstitute(clazz);
                standIn = createImageIcon(standInComponent, x, y);
            } catch (Exception e1) {
                // something went wrong - fallback to this painting
                standIn = this;
            } 
        }
    
        private Icon createImageIcon(JComponent standInComponent, int x, int y) {
            BufferedImage image = new BufferedImage(getIconWidth(),
                    getIconHeight(), BufferedImage.TYPE_INT_ARGB);
              Graphics g = image.createGraphics();
              try {
                  wrappee.paintIcon(standInComponent, g, 0, 0);
                  return new ImageIcon(image);
              } finally {
                  g.dispose();
              }
        }
    
        /**
         * @param clazz
         * @throws IllegalAccessException 
         */
        private JComponent getSubstitute(Class<?> clazz) throws IllegalAccessException {
            JComponent standInComponent;
            try {
                standInComponent = (JComponent) clazz.newInstance();
            } catch (InstantiationException e) {
                standInComponent = new AbstractButton() {
    
                };
                ((AbstractButton) standInComponent).setModel(new DefaultButtonModel());
            } 
            return standInComponent;
        }
    
        private Class<?> getClass(ClassCastException e) throws ClassNotFoundException {
            String className = e.getMessage();
            className = className.substring(className.lastIndexOf(" ") + 1);
            return Class.forName(className);
    
        }
    
        private void paintFallback(Component c, Graphics g, int x, int y) {
            g.drawRect(x, y, getIconWidth(), getIconHeight());
            g.drawLine(x, y, x + getIconWidth(), y + getIconHeight());
            g.drawLine(x + getIconWidth(), y, x, y + getIconHeight());
        }
    
    }
    

    To use in your snippet, simply pass in an arbitrary component:

        icon = new SafeIcon(icon);
        BufferedImage image = new BufferedImage(icon.getIconWidth(), icon.getIconHeight(), BufferedImage.TYPE_INT_RGB);
        icon.paintIcon(new JPanel(), image.getGraphics(), 0, 0);
    
    0 讨论(0)
提交回复
热议问题