JBR API v0.0.2

Added file dialog customization via JBR API & fixed bugs in windows common item dialog

with fix for JBR-5300 Change source code and test files to use GPL license

(cherry picked from commit 45c562e366)
This commit is contained in:
Nikita Gubarkov
2021-12-13 02:26:35 +03:00
committed by jbrbot
parent d5035a2b75
commit 6d60057254
12 changed files with 329 additions and 73 deletions

View File

@@ -53,10 +53,13 @@ import java.io.File;
import java.io.FilenameFilter;
import java.util.List;
import com.jetbrains.desktop.JBRFileDialog;
import sun.awt.AWTAccessor;
import sun.java2d.pipe.Region;
import sun.util.logging.PlatformLogger;
import static com.jetbrains.desktop.JBRFileDialog.*;
class CFileDialog implements FileDialogPeer {
private static final PlatformLogger log = PlatformLogger.getLogger("sun.lwawt.macosx.CFileDialog");
@@ -67,8 +70,16 @@ class CFileDialog implements FileDialogPeer {
public void run() {
try {
boolean navigateApps = !Boolean.getBoolean("apple.awt.use-file-dialog-packages");
boolean chooseDirectories = Boolean.getBoolean("apple.awt.fileDialogForDirectories");
boolean chooseFiles = Boolean.getBoolean("apple.awt.fileDialogForFiles");
JBRFileDialog jbrDialog = JBRFileDialog.get(target);
boolean createDirectories = (jbrDialog.getHints() & CREATE_DIRECTORIES_HINT) != 0;
boolean chooseDirectories = (jbrDialog.getHints() & SELECT_DIRECTORIES_HINT) != 0;
boolean chooseFiles = (jbrDialog.getHints() & SELECT_FILES_HINT) != 0;
if (!chooseDirectories && !chooseFiles) { // Fallback to default
boolean dir = Boolean.getBoolean("apple.awt.fileDialogForDirectories");
chooseFiles = !dir;
chooseDirectories = dir;
}
int dialogMode = target.getMode();
String title = target.getTitle();
@@ -82,6 +93,7 @@ class CFileDialog implements FileDialogPeer {
navigateApps,
chooseDirectories,
chooseFiles,
createDirectories,
target.getFilenameFilter() != null,
target.getDirectory(),
target.getFile());
@@ -176,7 +188,8 @@ class CFileDialog implements FileDialogPeer {
private native String[] nativeRunFileDialog(String title, int mode,
boolean multipleMode, boolean shouldNavigateApps,
boolean canChooseDirectories, boolean canChooseFiles,
boolean hasFilenameFilter, String directory, String file);
boolean canCreateDirectories, boolean hasFilenameFilter,
String directory, String file);
@Override
public void setDirectory(String dir) {

View File

@@ -54,9 +54,12 @@
// Can the dialog choose directories ?
BOOL fChooseDirectories;
// Can the dialog choose directories ?
// Can the dialog choose files ?
BOOL fChooseFiles;
// Can the dialog create directories ?
BOOL fCreateDirectories;
// Contains the absolute paths of the selected files as URLs
NSArray *fURLs;
}
@@ -72,6 +75,7 @@
shouldNavigate:(BOOL)inNavigateApps
canChooseDirectories:(BOOL)inChooseDirectories
canChooseFiles:(BOOL)inChooseFiles
canCreateDirectories:(BOOL)inCreateDirectories
withEnv:(JNIEnv*)env;
// Invoked from the main thread

View File

@@ -47,6 +47,7 @@
shouldNavigate:(BOOL)inNavigateApps
canChooseDirectories:(BOOL)inChooseDirectories
canChooseFiles:(BOOL)inChooseFiles
canCreateDirectories:(BOOL)inCreateDirectories
withEnv:(JNIEnv*)env;
{
if (self = [super init]) {
@@ -63,6 +64,7 @@ canChooseDirectories:(BOOL)inChooseDirectories
fNavigateApps = inNavigateApps;
fChooseDirectories = inChooseDirectories;
fChooseFiles = inChooseFiles;
fCreateDirectories = inCreateDirectories;
fPanelResult = NSCancelButton;
}
@@ -123,7 +125,7 @@ canChooseDirectories:(BOOL)inChooseDirectories
[openPanel setAllowsMultipleSelection:fMultipleMode];
[openPanel setCanChooseFiles:fChooseFiles];
[openPanel setCanChooseDirectories:fChooseDirectories];
[openPanel setCanCreateDirectories:YES];
[openPanel setCanCreateDirectories:fCreateDirectories];
}
[thePanel setDelegate:self];
@@ -243,13 +245,11 @@ canChooseDirectories:(BOOL)inChooseDirectories
/*
* Class: sun_lwawt_macosx_CFileDialog
* Method: nativeRunFileDialog
* Signature: (Ljava/lang/String;ILjava/io/FilenameFilter;
* Ljava/lang/String;Ljava/lang/String;)[Ljava/lang/String;
*/
JNIEXPORT jobjectArray JNICALL
Java_sun_lwawt_macosx_CFileDialog_nativeRunFileDialog
(JNIEnv *env, jobject peer, jstring title, jint mode, jboolean multipleMode,
jboolean navigateApps, jboolean chooseDirectories, jboolean chooseFiles,
jboolean navigateApps, jboolean chooseDirectories, jboolean chooseFiles, jboolean createDirectories,
jboolean hasFilter, jstring directory, jstring file)
{
jobjectArray returnValue = NULL;
@@ -270,6 +270,7 @@ JNI_COCOA_ENTER(env);
shouldNavigate:navigateApps
canChooseDirectories:chooseDirectories
canChooseFiles:chooseFiles
canCreateDirectories:createDirectories
withEnv:env];
[ThreadUtilities performOnMainThread:@selector(safeSaveOrLoad)

View File

@@ -36,6 +36,9 @@ public class JBRApiModule {
static {
JBRApi.registerModule(MethodHandles.lookup(), JBRApiModule.class.getModule()::addExports)
.service("com.jetbrains.ExtendedGlyphCache", null)
.withStatic("getSubpixelResolution", "sun.font.FontUtilities");
.withStatic("getSubpixelResolution", "sun.font.FontUtilities")
.service("com.jetbrains.JBRFileDialogService", null)
.withStatic("getFileDialog", "com.jetbrains.desktop.JBRFileDialog", "get")
.proxy("com.jetbrains.JBRFileDialog", "com.jetbrains.desktop.JBRFileDialog");
}
}

View File

@@ -0,0 +1,63 @@
package com.jetbrains.desktop;
import java.io.Serial;
import java.io.Serializable;
import java.lang.annotation.Native;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.VarHandle;
import java.awt.*;
public class JBRFileDialog implements Serializable {
@Serial
private static final long serialVersionUID = -9154712118353824660L;
private static final VarHandle getter;
static {
try {
getter = MethodHandles.privateLookupIn(FileDialog.class, MethodHandles.lookup())
.findVarHandle(FileDialog.class, "jbrDialog", JBRFileDialog.class);
} catch (NoSuchFieldException | IllegalAccessException e) {
throw new Error(e);
}
}
public static JBRFileDialog get(FileDialog dialog) {
return (JBRFileDialog) getter.get(dialog);
}
/**
* Whether to select files, directories or both (used when common file dialogs are enabled on Windows, or on macOS)
*/
@Native public static final int SELECT_FILES_HINT = 1, SELECT_DIRECTORIES_HINT = 2;
/**
* Whether to allow creating directories or not (used on macOS)
*/
@Native public static final int CREATE_DIRECTORIES_HINT = 4;
public int hints = CREATE_DIRECTORIES_HINT;
/**
* Text for "Open" button (used when common file dialogs are enabled on
* Windows).
*/
public String openButtonText;
/**
* Text for "Select Folder" button (used when common file dialogs are
* enabled on Windows).
*/
public String selectFolderButtonText;
public void setHints(int hints) {
this.hints = hints;
}
public int getHints() {
return hints;
}
public void setLocalizationStrings(String openButtonText, String selectFolderButtonText) {
this.openButtonText = openButtonText;
this.selectFolderButtonText = selectFolderButtonText;
}
}

View File

@@ -33,6 +33,7 @@ import java.io.ObjectInputStream;
import java.io.Serial;
import java.lang.annotation.Native;
import com.jetbrains.desktop.JBRFileDialog;
import sun.awt.AWTAccessor;
/**
@@ -630,44 +631,36 @@ public class FileDialog extends Dialog {
return false;
}
/**
* Text for "Open" button (used when common file dialogs are enabled on
* Windows).
*/
private String openButtonText;
/**
* Text for "Select Folder" button (used when common file dialogs are
* enabled on Windows).
*/
private String selectFolderButtonText;
/**
* Called using reflection; sets localization strings used when common
* file dialogs are enabled on Windows.
*/
@Deprecated(forRemoval = true)
private void setLocalizationStrings(String openButtonText, String selectFolderButtonText) {
this.openButtonText = openButtonText;
this.selectFolderButtonText = selectFolderButtonText;
jbrDialog.openButtonText = openButtonText;
jbrDialog.selectFolderButtonText = selectFolderButtonText;
}
/**
* Whether to enable folder picker mode (used when common file dialogs are
* enabled on Windows).
*/
private boolean folderPickerMode;
@Deprecated(forRemoval = true)
private void setFolderPickerMode(boolean folderPickerMode) {
this.folderPickerMode = folderPickerMode;
int hints = jbrDialog.getHints();
if (folderPickerMode) {
hints |= JBRFileDialog.SELECT_DIRECTORIES_HINT;
} else {
hints &= ~JBRFileDialog.SELECT_DIRECTORIES_HINT;
}
}
/**
* Whether to enable exclusive file picker mode, with no folder picker
* available (used when common file dialogs are enabled on Windows).
*/
private boolean fileExclusivePickerMode;
@Deprecated(forRemoval = true)
private void setFileExclusivePickerMode(boolean fileExclusivePickerMode) {
this.fileExclusivePickerMode = fileExclusivePickerMode;
int hints = jbrDialog.getHints();
if (fileExclusivePickerMode) {
hints |= JBRFileDialog.SELECT_FILES_HINT;
} else {
hints &= ~JBRFileDialog.SELECT_FILES_HINT;
jbrDialog.setHints(hints);
}
}
private final JBRFileDialog jbrDialog = new JBRFileDialog();
}

View File

@@ -29,6 +29,7 @@
#include "awt_Dialog.h"
#include "awt_Toolkit.h"
#include "ComCtl32Util.h"
#include "com_jetbrains_desktop_JBRFileDialog.h"
#include <commdlg.h>
#include <cderr.h>
#include <shlobj.h>
@@ -53,10 +54,10 @@ jfieldID AwtFileDialog::modeID;
jfieldID AwtFileDialog::dirID;
jfieldID AwtFileDialog::fileID;
jfieldID AwtFileDialog::filterID;
jfieldID AwtFileDialog::jbrDialogID;
jfieldID AwtFileDialog::openButtonTextID;
jfieldID AwtFileDialog::selectFolderButtonTextID;
jfieldID AwtFileDialog::folderPickerModeID;
jfieldID AwtFileDialog::fileExclusivePickerModeID;
jfieldID AwtFileDialog::hintsID;
class CoTaskStringHolder {
public:
@@ -746,16 +747,6 @@ HRESULT CreateShellItem(LPTSTR path, IShellItemPtr& shellItem) {
return ::SHCreateItemInKnownFolder(FOLDERID_ComputerFolder, 0, path, IID_PPV_ARGS(&shellItem));
}
CoTaskStringHolder GetShortName(LPTSTR path) {
CoTaskStringHolder shortName;
OLE_TRY
IShellItemPtr shellItem;
OLE_HRT(CreateShellItem(path, shellItem));
OLE_HRT(shellItem->GetDisplayName(SIGDN_PARENTRELATIVE, &shortName));
OLE_CATCH
return SUCCEEDED(OLE_HR) ? shortName : CoTaskStringHolder();
}
void AttachString(JNIEnv *env, const jstring string, SmartHolder<WCHAR[]> &holder) {
if (JNU_IsNull(env, string)) {
holder.Attach(nullptr);
@@ -770,9 +761,9 @@ void AttachString(JNIEnv *env, const jstring string, SmartHolder<WCHAR[]> &holde
}
}
void SaveCommonDialogLocalizationData(JNIEnv *env, const jobject fileDialog, FileDialogData &data) {
jstring openButtonText = static_cast<jstring>(env->GetObjectField(fileDialog, AwtFileDialog::openButtonTextID));
jstring selectFolderButtonText = static_cast<jstring>(env->GetObjectField(fileDialog, AwtFileDialog::selectFolderButtonTextID));
void SaveCommonDialogLocalizationData(JNIEnv *env, const jobject jbrFileDialog, FileDialogData &data) {
jstring openButtonText = static_cast<jstring>(env->GetObjectField(jbrFileDialog, AwtFileDialog::openButtonTextID));
jstring selectFolderButtonText = static_cast<jstring>(env->GetObjectField(jbrFileDialog, AwtFileDialog::selectFolderButtonTextID));
AttachString(env, openButtonText, data.openButtonText);
AttachString(env, selectFolderButtonText, data.selectFolderButtonText);
@@ -922,12 +913,17 @@ AwtFileDialog::Show(void *p)
GUID fileDialogMode = mode == java_awt_FileDialog_LOAD ? CLSID_FileOpenDialog : CLSID_FileSaveDialog;
OLE_HRT(pfd.CreateInstance(fileDialogMode));
bool folderPickerMode = env->GetBooleanField(target, AwtFileDialog::folderPickerModeID);
bool fileExclusivePickerMode = env->GetBooleanField(target, AwtFileDialog::fileExclusivePickerModeID);
jobject jbrDialog = env->GetObjectField(target, AwtFileDialog::jbrDialogID);
jint hints = env->GetIntField(jbrDialog, AwtFileDialog::hintsID);
bool folderPickerMode = hints & com_jetbrains_desktop_JBRFileDialog_SELECT_DIRECTORIES_HINT;
bool fileExclusivePickerMode = hints & com_jetbrains_desktop_JBRFileDialog_SELECT_FILES_HINT;
if (folderPickerMode && fileExclusivePickerMode) {
folderPickerMode = fileExclusivePickerMode = false;
}
data.ignoreCustomizations = folderPickerMode || fileExclusivePickerMode || mode == java_awt_FileDialog_SAVE;
data.fileDialog = pfd;
data.peer = peer;
SaveCommonDialogLocalizationData(env, target, data);
SaveCommonDialogLocalizationData(env, jbrDialog, data);
OLE_HRT(CDialogEventHandler_CreateInstance(&data, IID_PPV_ARGS(&pfde)));
OLE_HRT(pfd->Advise(pfde, &dwCookie));
@@ -958,12 +954,9 @@ AwtFileDialog::Show(void *p)
}
{
CoTaskStringHolder shortName = GetShortName(fileBuffer);
if (shortName) {
OLE_TRY
OLE_HRT(pfd->SetFileName(shortName));
OLE_CATCH
}
OLE_TRY
OLE_HRT(pfd->SetFileName(fileBuffer));
OLE_CATCH
}
OLE_CATCH
@@ -985,6 +978,7 @@ AwtFileDialog::Show(void *p)
CoTaskStringHolder filePath;
OLE_HRT(psiResult->GetDisplayName(SIGDN_FILESYSPATH, &filePath));
size_t filePathLength = _tcslen(filePath);
data.resultSize = filePathLength;
data.result.Attach(new TCHAR[filePathLength + 1]);
_tcscpy_s(data.result, filePathLength + 1, filePath);
OLE_CATCH
@@ -1216,6 +1210,15 @@ Java_sun_awt_windows_WFileDialogPeer_initIDs(JNIEnv *env, jclass cls)
env->GetFieldID(cls, "filter", "Ljava/io/FilenameFilter;");
DASSERT(AwtFileDialog::filterID != NULL);
AwtFileDialog::jbrDialogID =
env->GetFieldID(cls, "jbrDialog", "Lcom/jetbrains/desktop/JBRFileDialog;");
DASSERT(AwtFileDialog::jbrDialogID != NULL);
CHECK_NULL(AwtFileDialog::jbrDialogID);
/* com.jetbrains.desktop.JBRFileDialog fields */
cls = env->FindClass("com/jetbrains/desktop/JBRFileDialog");
CHECK_NULL(cls);
AwtFileDialog::openButtonTextID =
env->GetFieldID(cls, "openButtonText", "Ljava/lang/String;");
DASSERT(AwtFileDialog::openButtonTextID != NULL);
@@ -1226,13 +1229,9 @@ Java_sun_awt_windows_WFileDialogPeer_initIDs(JNIEnv *env, jclass cls)
DASSERT(AwtFileDialog::selectFolderButtonTextID != NULL);
CHECK_NULL(AwtFileDialog::selectFolderButtonTextID);
AwtFileDialog::folderPickerModeID = env->GetFieldID(cls, "folderPickerMode", "Z");
DASSERT(AwtFileDialog::folderPickerModeID != NULL);
CHECK_NULL(AwtFileDialog::folderPickerModeID);
AwtFileDialog::fileExclusivePickerModeID = env->GetFieldID(cls, "fileExclusivePickerMode", "Z");
DASSERT(AwtFileDialog::fileExclusivePickerModeID != NULL);
CHECK_NULL(AwtFileDialog::fileExclusivePickerModeID);
AwtFileDialog::hintsID = env->GetFieldID(cls, "hints", "I");
DASSERT(AwtFileDialog::hintsID != NULL);
CHECK_NULL(AwtFileDialog::hintsID);
CATCH_BAD_ALLOC;
}

View File

@@ -56,10 +56,12 @@ public:
static jfieldID dirID;
static jfieldID fileID;
static jfieldID filterID;
static jfieldID jbrDialogID;
/* com.jetbrains.desktop.JBRFileDialog field and method ids */
static jfieldID openButtonTextID;
static jfieldID selectFolderButtonTextID;
static jfieldID folderPickerModeID;
static jfieldID fileExclusivePickerModeID;
static jfieldID hintsID;
static void Initialize(JNIEnv *env, jstring filterDescription);
static void Show(void *peer);

View File

@@ -0,0 +1,61 @@
/*
* Copyright 2000-2023 JetBrains s.r.o.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.jetbrains;
import java.awt.*;
public interface JBRFileDialog {
/*CONST com.jetbrains.desktop.JBRFileDialog.*_HINT*/
static JBRFileDialog get(FileDialog dialog) {
if (JBRFileDialogService.INSTANCE == null) return null;
else return JBRFileDialogService.INSTANCE.getFileDialog(dialog);
}
/**
* Set JBR-specific file dialog hints:
* <ul>
* <li>SELECT_FILES_HINT, SELECT_DIRECTORIES_HINT - Whether to select files, directories or both
* (used when common file dialogs are enabled on Windows, or on macOS),
* both unset bits are treated as a default platform-specific behavior</li>
* <li>CREATE_DIRECTORIES_HINT - Whether to allow creating directories or not (used on macOS)</li>
* </ul>
*/
void setHints(int hints);
/**
* @see #setHints(int)
*/
int getHints();
void setLocalizationStrings(String openButtonText, String selectFolderButtonText);
}
interface JBRFileDialogService {
JBRFileDialogService INSTANCE = JBR.getService(JBRFileDialogService.class);
JBRFileDialog getFileDialog(FileDialog dialog);
}

View File

@@ -6,9 +6,9 @@
# 2. When only new API is added, or some existing API was @Deprecated - increment MINOR, reset PATCH to 0
# 3. For major backwards incompatible API changes - increment MAJOR, reset MINOR and PATCH to 0
VERSION = 0.0.0
VERSION = 0.0.2
# Hash is used to track changes to jetbrains.api, so you would not forget to update version when needed.
# When you make any changes, "make jbr-api" will fail and ask you to update hash and version number here.
HASH = 92C0C6E35DC69EE86FD74E4083E1668
HASH = 814F29888E5EB6C23DF27B53636E9F94

View File

@@ -0,0 +1,115 @@
/*
* Copyright 2000-2023 JetBrains s.r.o.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @requires (os.family == "mac")
* @run shell build.sh
* @run main/manual JBRApiTest
*/
import com.jetbrains.JBRFileDialog;
import java.awt.*;
import java.io.File;
import java.util.Arrays;
import java.util.List;
public class FileDialogTest {
private static final File directory = new File("FileDialogTest").getAbsoluteFile();
private static void refresh() {
for (File f : directory.listFiles()) f.delete();
}
public static void main(String[] args) throws Exception {
directory.mkdirs();
refresh();
var dialog = new FileDialog((Frame) null);
dialog.setTitle("Press Save");
dialog.setDirectory(directory.getAbsolutePath());
dialog.setFile("PASS");
dialog.setMode(FileDialog.SAVE);
dialog.setVisible(true);
var file = new File(directory, "PASS");
check(dialog, file);
refresh();
file = new File(directory, "OPEN ME");
file.createNewFile();
dialog = open(JBRFileDialog.SELECT_FILES_HINT);
dialog.setVisible(true);
check(dialog, file);
refresh();
file.mkdir();
dialog = open(JBRFileDialog.SELECT_DIRECTORIES_HINT);
dialog.setVisible(true);
check(dialog, file);
refresh();
file = new File(directory, "OPEN US");
file.createNewFile();
var file2 = new File(directory, "OPEN US");
file2.mkdir();
dialog = open(JBRFileDialog.SELECT_FILES_HINT | JBRFileDialog.SELECT_DIRECTORIES_HINT);
dialog.setMultipleMode(true);
dialog.setVisible(true);
check(dialog, file, file2);
refresh();
new File(directory, "CREATE DIRECTORY").createNewFile();
new File(directory, "AND OPEN IT").createNewFile();
dialog = open(JBRFileDialog.SELECT_DIRECTORIES_HINT | JBRFileDialog.CREATE_DIRECTORIES_HINT);
dialog.setVisible(true);
file = dialog.getFiles()[0];
dialog.dispose();
if (!file.isDirectory() || !file.exists()) {
throw new RuntimeException("Selected file doesn't exist");
}
}
private static FileDialog open(int hints) {
var dialog = new FileDialog((Frame) null);
dialog.setMode(FileDialog.LOAD);
JBRFileDialog.get(dialog).setHints(hints);
return dialog;
}
private static void check(FileDialog dialog, File... expected) {
List<File> actual = List.of(dialog.getFiles());
dialog.dispose();
boolean match = expected.length == actual.size();
if (match) {
for (File f : expected) {
if (!actual.contains(f)) {
match = false;
break;
}
}
}
if (!match) {
throw new RuntimeException("Invalid files, expected: " + Arrays.toString(expected) + ", actual: " + actual);
}
}
}

View File

@@ -28,6 +28,7 @@
*/
import com.jetbrains.JBR;
import com.jetbrains.JBRFileDialog;
import java.awt.*;
import java.lang.reflect.Field;
@@ -54,6 +55,7 @@ public class JBRApiTest {
}
private static void testServices() {
Objects.requireNonNull((Dimension) JBR.getExtendedGlyphCache().getSubpixelResolution());
Objects.requireNonNull(JBR.getExtendedGlyphCache().getSubpixelResolution());
Objects.requireNonNull(JBRFileDialog.get(new FileDialog((Frame) null)));
}
}