Java 如何将图标转换为图像
我正在尝试使用以下代码将图标(Java 如何将图标转换为图像,java,image,swing,awt,Java,Image,Swing,Awt,我正在尝试使用以下代码将图标(javax.swing.Icon)转换为图像(java.awt.Image): private Image iconToImage(Icon icon) { if(icon instanceof ImageIcon) { return ((ImageIcon) icon).getImage(); } else { BufferedImage image = new BufferedImage(i
javax.swing.Icon
)转换为图像(java.awt.Image
):
private Image iconToImage(Icon icon)
{
if(icon instanceof ImageIcon)
{
return ((ImageIcon) icon).getImage();
}
else
{
BufferedImage image = new BufferedImage(icon.getIconWidth(), icon.getIconHeight(), BufferedImage.TYPE_INT_RGB);
icon.paintIcon(null, image.getGraphics(), 0, 0);
return image;
}
}
问题是,paintIcon
函数在image.getGraphics()上抛出一个NullPointerException
对于记录,图标
值是默认的复选框
图标(通过UIManager.getIcon(“CheckBox.icon”)
获取)
以下是引发的异常的详细信息:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at com.sun.java.swing.plaf.windows.WindowsIconFactory$CheckBoxIcon.paintIcon(WindowsIconFactory.java:306)
at utils.WarningRenderer.iconToImage(WarningRenderer.java:50)
at utils.WarningRenderer.<init>(WarningRenderer.java:38)
at deliveryexpress.DeliveryExpressView.setWarnings(DeliveryExpressView.java:278)
at deliveryexpress.DeliveryExpressView.updateLists(DeliveryExpressView.java:218)
at deliveryexpress.DeliveryExpressView.access$1100(DeliveryExpressView.java:47)
at deliveryexpress.DeliveryExpressView$5.addCheck(DeliveryExpressView.java:183)
at org.japura.gui.model.DefaultListCheckModel.fireCheckListModelListeners(Unknown Source)
at org.japura.gui.model.DefaultListCheckModel.fireAddCheckListModelListeners(Unknown Source)
at org.japura.gui.model.DefaultListCheckModel.addCheck(Unknown Source)
at org.japura.gui.CheckList$1.mouseClicked(Unknown Source)
at java.awt.AWTEventMulticaster.mouseClicked(AWTEventMulticaster.java:253)
at java.awt.Component.processMouseEvent(Component.java:6292)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3267)
at java.awt.Component.processEvent(Component.java:6054)
at java.awt.Container.processEvent(Container.java:2041)
at java.awt.Component.dispatchEventImpl(Component.java:4652)
at java.awt.Container.dispatchEventImpl(Container.java:2099)
at java.awt.Component.dispatchEvent(Component.java:4482)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4577)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4247)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4168)
at java.awt.Container.dispatchEventImpl(Container.java:2085)
at java.awt.Window.dispatchEventImpl(Window.java:2478)
at java.awt.Component.dispatchEvent(Component.java:4482)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:644)
at java.awt.EventQueue.access$000(EventQueue.java:85)
at java.awt.EventQueue$1.run(EventQueue.java:603)
at java.awt.EventQueue$1.run(EventQueue.java:601)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:98)
at java.awt.EventQueue$2.run(EventQueue.java:617)
at java.awt.EventQueue$2.run(EventQueue.java:615)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:614)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
线程“AWT-EventQueue-0”java.lang.NullPointerException中的异常
位于com.sun.java.swing.plaf.windows.WindowsIconFactory$CheckBoxIcon.paintIcon(WindowsIconFactory.java:306)
位于utils.WarningRenderer.iconToImage(WarningRenderer.java:50)
在utils.WarningRenderer.(WarningRenderer.java:38)
在deliveryexpress.DeliveryExpressView.setWarnings(DeliveryExpressView.java:278)
位于deliveryexpress.DeliveryExpressView.UpdateList(DeliveryExpressView.java:218)
在deliveryexpress.DeliveryExpressView.access$1100(DeliveryExpressView.java:47)
deliveryexpress.DeliveryExpressView$5.addCheck(DeliveryExpressView.java:183)
位于org.japura.gui.model.DefaultListCheckModel.fireCheckListModelListeners(未知源)
位于org.japura.gui.model.DefaultListCheckModel.fireAddCheckListModelListeners(未知源)
位于org.japura.gui.model.DefaultListCheckModel.addCheck(未知源)
在org.japura.gui.CheckList$1.mouseClicked(未知来源)
在java.awt.AWTEventMulticaster.mouseClicked(AWTEventMulticaster.java:253)
位于java.awt.Component.ProcessMouseeEvent(Component.java:6292)
位于javax.swing.JComponent.ProcessMouseeEvent(JComponent.java:3267)
位于java.awt.Component.processEvent(Component.java:6054)
位于java.awt.Container.processEvent(Container.java:2041)
位于java.awt.Component.dispatchEventImpl(Component.java:4652)
位于java.awt.Container.dispatchEventImpl(Container.java:2099)
位于java.awt.Component.dispatchEvent(Component.java:4482)
位于java.awt.LightweightDispatcher.RetargetMouseeEvent(Container.java:4577)
位于java.awt.LightweightDispatcher.ProcessMouseeEvent(Container.java:4247)
位于java.awt.LightweightDispatcher.dispatchEvent(Container.java:4168)
位于java.awt.Container.dispatchEventImpl(Container.java:2085)
位于java.awt.Window.dispatchEventImpl(Window.java:2478)
位于java.awt.Component.dispatchEvent(Component.java:4482)
位于java.awt.EventQueue.dispatchEventImpl(EventQueue.java:644)
在java.awt.EventQueue.access$000(EventQueue.java:85)
在java.awt.EventQueue$1.run处(EventQueue.java:603)
在java.awt.EventQueue$1.run处(EventQueue.java:601)
位于java.security.AccessController.doPrivileged(本机方法)
位于java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
位于java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:98)
在java.awt.EventQueue$2.run(EventQueue.java:617)
在java.awt.EventQueue$2.run(EventQueue.java:615)
位于java.security.AccessController.doPrivileged(本机方法)
位于java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
位于java.awt.EventQueue.dispatchEvent(EventQueue.java:614)
位于java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
位于java.awt.EventDispatchThread.PumpeEventsforFilter(EventDispatchThread.java:184)
位于java.awt.EventDispatchThread.PumpeEventsforHierarchy(EventDispatchThread.java:174)
位于java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
位于java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
在java.awt.EventDispatchThread.run处(EventDispatchThread.java:122)
如果你需要更多的细节,请告诉我,我会编辑我的帖子来添加它们
谢谢 试试这个:
icon.paintIcon(new JCheckBox(), image.getGraphics(), 0, 0);
但我无法确切解释为什么它需要一个JCheckBox
。也许图标会有所不同?NullPointerException
来自MetalIconFactory
中复选框.icon“
的此行:
刚刚发现了一个代码片段,如果您想更频繁地包装那些行为不端的LAF提供的图标,它可能会有所帮助:
/**
* 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());
}
}
试试这个:
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;
}
}
这是一个完整的示例,其中我们获取laf提供的图标,将其转换为图像,并将其用于Windows系统托盘上的
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);
}
}
}
仅供参考:依赖于状态的图标绘制与windowsCheckBoxIcon中的类似。这些图标实现非常糟糕,因为它们假设给定的组件是JCheckBox类型。根据合同,paintIcon必须处理任意组件类型,包括完全没有完美的问题,所有必要的详细信息:-)一小时前已经评论过,再次做:您认为这将如何帮助解决异常的原因,即laf提供的图标不处理空组件。。。这个错误的答案怎么又出现了?@kleopatra,可能是因为它工作得很好,如我的测试用例所示。所以你很幸运使用了OptionPane.warningIcon;-)对checkbox.icon(metal-/windowsLAF)尝试同样的方法,这是要解决的问题…很高兴知道,@kleopatra。其他一些人也出现了同样的问题(CheckBoxMenuItem),但大多数人都没有问题。我给你一个+1;-)@RealHowTo您测试了多少个LAF?试试Windows经典。谢谢,它成功了!它不包括alpha,但我会尝试自己解决这个问题:p@oliholz可能遗漏了一些东西,但是创建一个支持alpha类型的BuffereImage(比如类型_INT_ARGB)有什么错呢?
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;
}
}
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);
}
}
}