我使用的是netbeans平台的OptionsPanelController
,
from https://platform.netbeans.org/tutorials/nbm-options.html this tutorial.
我的问题是,通过使用此面板,Ok button
在默认情况下被聚焦。
如何让它默认不聚焦
注释:
由于它是一个netbeans平台应用程序,我从netbeans IDE打开Tools->Options
,在该对话框中,Ok按钮也默认集中
在netbeans源代码中的私有包和最终类中以这种方式进行硬编码,因此可以完成,但需要修改netbeans源代码并更改代码以依赖于您自己的netbeans版本,或者使用反射或java字节码注入来覆盖现有行为。
需要修改的类有:org.netbeans.api.options.OptionsDisplyer和org.netbeans.api.options.OptionsDisplayerImpl
更具体地说,方法OptionsDialogImpl.showOptionsDialog(…)创建一个DialogDisplayer对象,该对象的默认选择值设置为DialogDescriptor。OK_OPTION,这将导致在打开Tools->Options窗口时选择OK按钮。
你唯一的解决方法/hack是:选项1)构建您自己的netbeans版本,根据需要更改硬编码行为。你需要从netbeans源代码克隆和构建;详见:http://wiki.netbeans.org/WorkingWithNetBeansSources#Try_NetBeans_buildSimply
一旦您签出/克隆源代码,您将希望在OptionsDisplayerImpl.java中编辑约204行,以替换输入参数DialogDescriptor。OK_OPTION,与您的首选按钮,说DialogDescriptor.CANCEL_OPTION。您需要编辑的行如下所示:
descriptor = new DialogDescriptor(optionsPanel,title,modal,options,DialogDescriptor.OK_OPTION,DialogDescriptor.DEFAULT_ALIGN, null, null, false);
选项2)使用java反射来访问和更改默认选择按钮的值,或者用覆盖默认行为的自定义实现替换私有字段。
示例代码:
OptionsDisplayer displayer = OptionsDisplayer.getDefault();
Object impl = getField(displayer, "impl");
if(impl != null){
WeakReference<DialogDescriptor> descriptorRef = (WeakReference<DialogDescriptor>)getField(impl, "descriptorRef");
if(descriptorRef != null){
DialogDescriptor descriptor = descriptorRef.get();
//change default initial selected butten from "OK" to "CANCEL"
descriptor.setValue(DialogDescriptor.CANCEL_OPTION); //change default initial selected butten from "OK" to "CANCEL"
}
}
/**
* Java reflection utility method to get the Object for a given field regardless of whether it is private or not, by it's given field name.
* @param obj The Object that contains the desired field.
* @param fieldName The name of the field
* @return The Object with the given fieldName found in Object 'obj'. Returns null if no such field exists.
*/
public static Object getField(Object obj, String fieldName) {
Class tmpClass = obj.getClass();
do {
try {
Field f = tmpClass.getDeclaredField(fieldName);
if(f != null){
f.setAccessible(true);
return f.get(obj);
}
} catch (NoSuchFieldException e) {
tmpClass = tmpClass.getSuperclass();
} catch (IllegalArgumentException | IllegalAccessException ex) {
ex.printStackTrace();
return null;
}
} while (tmpClass != null);
return null; //null if not found
}
选项3)更多的java黑魔法,拦截在类加载器上加载的字节码,并在将其加载到JVM之前对其进行更改。例如,使用字节码操作库,如AspectJ, Javassist, ASM或CGLib