状況依存のヘルプを必要とする Java デスクトップ アプリケーションがあります。たとえば、私の Validator アプリケーションは入力を SQL ステートメントとして取得し、入力内容に基づいて状況依存のヘルプを表示する必要があります。
1 つの使用例として、ユーザーが「update」と入力してから Ctrl+Space を押すと、テーブル名のリストが状況依存ヘルプとして表示される必要があります。
どうすればいいですか?
状況依存のヘルプを必要とする Java デスクトップ アプリケーションがあります。たとえば、私の Validator アプリケーションは入力を SQL ステートメントとして取得し、入力内容に基づいて状況依存のヘルプを表示する必要があります。
1 つの使用例として、ユーザーが「update」と入力してから Ctrl+Space を押すと、テーブル名のリストが状況依存ヘルプとして表示される必要があります。
どうすればいいですか?
あなたの質問を完全に理解しているかどうかわかりません。あなたはスイングでこれをやっていると思います。検索を入力しているときに Google が持っているようなホバーのようなものをお探しですか?
私がそれについてお手伝いできるかどうかはわかりませんが、リフレクションを使用して属性の値に基づいてオブジェクトを検索語と照合するために使用した方法を次に示します。必要のないものかもしれませんが、念のためお譲りしたいと思います。それが役に立てば幸い!
/**
* Returns true if any attribute in the item matches the given constraints
*
* @param object the object you want to match
* @param klass the class to get the fields from (in most cases you'll just call object.getClass())
* @param iterations how many inherited levels you want to check fields for
* @param match the String to match fields against
* @param ignoreField fieldNames you wish to ignore, you can give as many as you like, you can also give an
* array of strings
* @return whether the given object contained fields which matched the given string
*/
public static boolean matches(Object object, Class klass, int iterations, String match, String... ignoreField) {
if (iterations < 0) {
return false;
}
boolean checkMatch = false;
try {
checkMatch = matchFields(klass.getDeclaredFields(), object, match, ignoreField);
} catch (IllegalArgumentException ex) {
Logger.getLogger(OtherHelper.class.getName()).log(Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
Logger.getLogger(OtherHelper.class.getName()).log(Level.SEVERE, null, ex);
}
if (checkMatch) {
return true;
} else {
Class<? extends Object> supersSuperclass = (Class<? extends Object>) klass.getSuperclass();
if (supersSuperclass != Object.class) {
boolean matches = matches(object, supersSuperclass, (iterations - 1), match, ignoreField);
if (matches) {
return true;
} else {
return false;
}
} else {
return false;
}
}
}
/**
* Calls matchField(field, bo, match) on each field in the given field array.
*
* @param fields the fields array to get the fields from
* @param object the object to get the field values from
* @param match the text to match fields to
* @param ignoreField any number of fieldNames which are to be ignored.
* @return true on first true field match
* @throws IllegalArgumentException
* @throws IllegalArgumentException
* @throws IllegalAccessException
*/
private static boolean matchFields(Field[] fields, Object object, String match, String... ignoreField) throws IllegalArgumentException, IllegalArgumentException, IllegalAccessException {
List<String> ignoreFieldsList = Arrays.asList(ignoreField);
for (Field field : fields) {
if (!ignoreFieldsList.contains(field.getName())) {
if (matchField(field, object, match)) {
return true;
}
}
}
return false;
}
/**
* Gets the value of the field and matches the string version of it with the given match
*
* @param field the field to match
* @param object the object to get the field value from
* @param match the match to match the field value to.
* @return
* @throws IllegalArgumentException
* @throws IllegalArgumentException
* @throws IllegalAccessException
*/
private static boolean matchField(Field field, Object object, String match) throws IllegalArgumentException, IllegalArgumentException, IllegalAccessException {
field.setAccessible(true);
if (field.get(object) == null) {
return false;
}
Class<?> type = field.getType();
String value = null;
if (type == Date.class) {
SimpleDateFormat sdf = new SimpleDateFormat("MMM d, yyyy");
Date date = (Date) field.get(object);
value = sdf.format(date);
} else if (type == String.class || isPrimitive(type)) {
value = field.get(object).toString();
}
if (value != null
&& Pattern.compile(Pattern.quote(match), Pattern.CASE_INSENSITIVE).matcher(value).find()) {
return true;
} else {
return false;
}
}
/**
* Checks first whether it is primitive and then whether it's wrapper is a primitive wrapper. Returns true
* if either is true
*
* @param c
* @return whether it's a primitive type itself or it's a wrapper for a primitive type
*/
public static boolean isPrimitive(Class c) {
if (c.isPrimitive()) {
return true;
} else if (c == Byte.class
|| c == Short.class
|| c == Integer.class
|| c == Long.class
|| c == Float.class
|| c == Double.class
|| c == Boolean.class
|| c == Character.class) {
return true;
} else {
return false;
}
}
Eclipse RCP アプリケーションを作成し、Eclipse エディターを拡張します。
Eclipse を使用すると、エディターを作成してそれにコンテンツ アシストを追加するのは非常に簡単です。
このFAQを見てください。