问题
I'm using Flamingo Ribbon Bar in a NetBeans project, and I'm having a major issue with it: sometimes (I'm sorry I can't be more specific since I really can't figure out how to consistently replicate it) I get the following exception:
Java.lang.IllegalArgumentException: No interpolator found for java.lang.Float:java.lang.Float
at org.pushingpixels.trident.TimelinePropertyBuilder.getFieldInfo(TimelinePropertyBuilder.java:257)
at org.pushingpixels.trident.Timeline.addPropertyToInterpolate(Timeline.java:353)
at org.pushingpixels.trident.Timeline.addPropertyToInterpolate(Timeline.java:363)
at org.pushingpixels.flamingo.internal.ui.ribbon.BasicRibbonBandUI.installUI(BasicRibbonBandUI.java:168)
at javax.swing.JComponent.setUI(Unknown Source)
at org.pushingpixels.flamingo.api.ribbon.AbstractRibbonBand.setUI(AbstractRibbonBand.java:232)
at org.pushingpixels.flamingo.api.ribbon.AbstractRibbonBand.updateUI(AbstractRibbonBand.java:245)
at org.pushingpixels.flamingo.api.ribbon.AbstractRibbonBand.<init>(AbstractRibbonBand.java:205)
at org.pushingpixels.flamingo.api.ribbon.JRibbonBand.<init>(JRibbonBand.java:169)
at com.pinkmatter.modules.flamingo.RibbonComponentFactory.createRibbonBand(RibbonComponentFactory.java:216)
at com.pinkmatter.modules.flamingo.RibbonComponentFactory.createRibbonBands(RibbonComponentFactory.java:207)
at com.pinkmatter.modules.flamingo.RibbonComponentFactory.createRibbonTask(RibbonComponentFactory.java:195)
at com.pinkmatter.modules.flamingo.LayerRibbonComponentProvider.addTaskPanes(LayerRibbonComponentProvider.java:101)
at com.pinkmatter.modules.flamingo.LayerRibbonComponentProvider.createRibbon(LayerRibbonComponentProvider.java:56)
at com.pinkmatter.modules.flamingo.Installer$2.run(Installer.java:69)
[catch] at org.netbeans.core.windows.WindowManagerImpl$Exclusive$1.run(WindowManagerImpl.java:1563)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$200(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
with the ribbon bar not initializing (and thus my software being unusable). Sometimes, If I close it and restart it, it starts correctly, some other times not. I'm not having the slightest idea of what's happening; somewhere I read something about a wrong classloader being used but I can't really find that link now... Can anyone please help? Of course I can provide more details if needed
Thanks
回答1:
Although the accepted answer could have done the job, this is not the correct approach. Basically, the above is a workaround for a problem that shouldn't be/isn't there in the first place. Because of many source and binaries transfers of the trident
library, it has happened so that a very important file's been left behind. Thus spreading the bug like a virus.
The file is called trident-plugin.properties and, flabbergastingly, there are stored the location of the available interpolators.
So, the obvious fix would be to add this file to the affected package in the META-INF directory.
For quick reference, here are the contents of it:
UIToolkitHandler=org.pushingpixels.trident.swing.SwingToolkitHandler
PropertyInterpolatorSource=org.pushingpixels.trident.swing.AWTPropertyInterpolators
UIToolkitHandler=org.pushingpixels.trident.swt.SWTToolkitHandler
PropertyInterpolatorSource=org.pushingpixels.trident.swt.SWTPropertyInterpolators
UIToolkitHandler=org.pushingpixels.trident.android.AndroidToolkitHandler
PropertyInterpolatorSource=org.pushingpixels.trident.android.AndroidPropertyInterpolators
PropertyInterpolatorSource=org.pushingpixels.trident.interpolator.CorePropertyInterpolators
回答2:
As said in other comment, I found a solution (and I'm sorry I didn't provide it earlier).
Basically, the problem is that a wrong class loader is used to find the interpolator. So I made sure that the instantiation is always made with the System class loader. In order to do this, I modified two files:
In com.pinkmatter.modules.flamingo.RibbonComponentFactory.getOrCreateActionItem()
:
private static ActionItem getOrCreateActionItem(Lookup.Item<Object> item, String name,
Map<String, ActionItem> actionMap,
Map<String, FileObject> foMap) {
ActionItem actionItem = actionMap.get(name);
if (actionItem == null) {
ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader();
try {
// Some ribbon resources use Trident which looks for resources not
// found by the org.netbeans.MainImpl$BootClassLoader. So we
// switch to the org.netbeans.ModuleManager$SystemClassLoader.
ClassLoader systemClassLoader = Lookup.getDefault().lookup(ClassLoader.class);
Thread.currentThread().setContextClassLoader(systemClassLoader);
if (Action.class.isAssignableFrom(item.getType())) {
// Create an Action from an instance defined in the file object
Action instance = (Action) item.getInstance();
if (instance != null) {
actionItem = ActionItem.leaf((Action) instance);
}
} else if (JSeparator.class.isAssignableFrom(item.getType())) {
// Create a Separator
actionItem = ActionItem.separator();
actionItem.setText(foMap.get(name).getName());
} else if (JComponent.class.isAssignableFrom(item.getType())) {
// Create a Ribbon component from an instance defined in the file object
JComponent instance = (JComponent) item.getInstance();
if (instance != null) {
actionItem = ActionItem.component((JComponent) instance);
}
}
}
finally {
// Restore the original classloader
Thread.currentThread().setContextClassLoader(originalClassLoader);
}
} else {
System.out.println(MessageFormat.format("WARNING: Unknown item: {0}", item.getType()));
}
if (actionItem != null) {
addProperties(actionItem, foMap.get(name));
actionMap.put(name, actionItem);
}
return actionItem;
}
The same in method com.pinkmatter.modules.flamingo.RibbonComponentFactory.createRibbonBand()
:
public AbstractRibbonBand createRibbonBand(ActionItem item) {
//TODO icon
JRibbonBand band = null;
ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader();
ClassLoader systemClassLoader = Lookup.getDefault().lookup(ClassLoader.class);
Thread.currentThread().setContextClassLoader(systemClassLoader);
try {
String text = item.getValue("displayName") == null ? item.getText() : item.getValue("displayName").toString();
band = new JRibbonBand(text, ResizableIcons.empty(), getDefaultAction(item));
for (ActionItem child : item.getChildren()) {
if (child.isSeparator()) {
band.startGroup();
} else if (child.getValue(ActionItem.DEFAULT_ACTION) != Boolean.TRUE) {
addRibbonBandAction(band, child);
}
}
band.setResizePolicies(Arrays.<RibbonBandResizePolicy>asList(
new Mid2Mid(band.getControlPanel())));
} finally {
Thread.currentThread().setContextClassLoader(originalClassLoader);
}
return band;
}
With these two changes I did not have any issue about the interpolator anymore. Hope this helps.
来源:https://stackoverflow.com/questions/26054610/flamingo-ribbon-java-lang-illegalargumentexception-no-interpolator-found-for-j