mirror of
https://github.com/JFormDesigner/FlatLaf.git
synced 2026-02-11 22:47:13 -06:00
Compare commits
8 Commits
system-fil
...
signpath
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
93408b50df | ||
|
|
465254c0da | ||
|
|
aaca7cace1 | ||
|
|
c995b4cbdf | ||
|
|
b251ff76e8 | ||
|
|
ea2a985481 | ||
|
|
3ca7ebbfee | ||
|
|
7e6dc269c5 |
42
.github/workflows/natives.yml
vendored
42
.github/workflows/natives.yml
vendored
@@ -72,19 +72,39 @@ jobs:
|
|||||||
# tar.exe: Couldn't open ~/.gradle/caches/modules-2/modules-2.lock: Permission denied
|
# tar.exe: Couldn't open ~/.gradle/caches/modules-2/modules-2.lock: Permission denied
|
||||||
run: ./gradlew build-natives --no-daemon
|
run: ./gradlew build-natives --no-daemon
|
||||||
|
|
||||||
- name: Sign Windows DLLs
|
- name: Upload unsigned Windows DLLs for signing by SignPath.org
|
||||||
if: false
|
if: matrix.os == 'windows-latest' && github.repository == 'JFormDesigner/FlatLaf'
|
||||||
# if: matrix.os == 'windows-latest'
|
id: windows-unsigned
|
||||||
uses: skymatic/code-sign-action@v3
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
certificate: '${{ secrets.CODE_SIGN_CERT_BASE64 }}'
|
name: FlatLaf-natives-windows-unsigned
|
||||||
password: '${{ secrets.CODE_SIGN_CERT_PASSWORD }}'
|
path: flatlaf-natives/flatlaf-natives-windows/build/lib/main/release/**/*.dll
|
||||||
certificatesha1: '${{ secrets.CODE_SIGN_CERT_SHA1 }}'
|
|
||||||
folder: 'flatlaf-core/src/main/resources/com/formdev/flatlaf/natives'
|
- name: Sign Windows DLLs using SignPath.org
|
||||||
|
if: matrix.os == 'windows-latest' && github.repository == 'JFormDesigner/FlatLaf'
|
||||||
|
uses: signpath/github-action-submit-signing-request@v2
|
||||||
|
with:
|
||||||
|
api-token: ${{ secrets.SIGNPATH_API_TOKEN }}
|
||||||
|
organization-id: ${{ secrets.SIGNPATH_ORGANIZATION_ID }}
|
||||||
|
project-slug: FlatLaf
|
||||||
|
signing-policy-slug: release-signing
|
||||||
|
artifact-configuration-slug: windows-dlls
|
||||||
|
github-artifact-id: ${{ steps.windows-unsigned.outputs.artifact-id }}
|
||||||
|
wait-for-completion: true
|
||||||
|
output-artifact-directory: flatlaf-natives/flatlaf-natives-windows/build/lib/signed
|
||||||
|
|
||||||
|
- name: Copy signed Windows DLLs to flatlaf-core
|
||||||
|
if: matrix.os == 'windows-latest' && github.repository == 'JFormDesigner/FlatLaf'
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
SRC=flatlaf-natives/flatlaf-natives-windows/build/lib/signed
|
||||||
|
DEST=flatlaf-core/src/main/resources/com/formdev/flatlaf/natives
|
||||||
|
cp $SRC/aarch64/flatlaf-natives-windows.dll $DEST/flatlaf-windows-arm64.dll
|
||||||
|
cp $SRC/x86/flatlaf-natives-windows.dll $DEST/flatlaf-windows-x86.dll
|
||||||
|
cp $SRC/x86-64/flatlaf-natives-windows.dll $DEST/flatlaf-windows-x86_64.dll
|
||||||
|
|
||||||
- name: Sign macOS natives
|
- name: Sign macOS natives
|
||||||
if: false
|
if: matrix.os == 'DISABLED--macos-latest'
|
||||||
# if: matrix.os == 'DISABLED--macos-latest'
|
|
||||||
env:
|
env:
|
||||||
CERT_BASE64: ${{ secrets.CODE_SIGN_CERT_BASE64 }}
|
CERT_BASE64: ${{ secrets.CODE_SIGN_CERT_BASE64 }}
|
||||||
CERT_PASSWORD: ${{ secrets.CODE_SIGN_CERT_PASSWORD }}
|
CERT_PASSWORD: ${{ secrets.CODE_SIGN_CERT_PASSWORD }}
|
||||||
@@ -114,7 +134,7 @@ jobs:
|
|||||||
# cleanup
|
# cleanup
|
||||||
security delete-keychain $KEYCHAIN_PATH
|
security delete-keychain $KEYCHAIN_PATH
|
||||||
|
|
||||||
- name: Set artifacts pattern
|
- name: Set artifacts pattern for upload step
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
case ${{ matrix.os }} in
|
case ${{ matrix.os }} in
|
||||||
|
|||||||
18
CHANGELOG.md
18
CHANGELOG.md
@@ -3,19 +3,19 @@ FlatLaf Change Log
|
|||||||
|
|
||||||
## 3.7.1-SNAPSHOT
|
## 3.7.1-SNAPSHOT
|
||||||
|
|
||||||
- System File Chooser:
|
|
||||||
- Update current filter before invoking approve callback and after closing
|
|
||||||
dialog. (issue #1065)
|
|
||||||
- Added `PatternFilter` to support glob file filter (e.g. `*.tar.gz`) on
|
|
||||||
Windows and on Linux, but not on macOS. (issue #1076)
|
|
||||||
- Fixed: System and Swing file dialogs were shown at the same time if
|
|
||||||
application has no other displayable window. (issue #1078)
|
|
||||||
- On Linux: Check whether required GSettings schemas are installed to avoid
|
|
||||||
application crash (occurred on NixOS with Plasma/KDE desktop). (issue #1069)
|
|
||||||
- ComboBox: Added UI property `ComboBox.buttonFocusedEditableBackground`. (issue
|
- ComboBox: Added UI property `ComboBox.buttonFocusedEditableBackground`. (issue
|
||||||
#1068)
|
#1068)
|
||||||
- Popup: Fixed scrolling popup painting issue on Windows 10 when a glass pane is
|
- Popup: Fixed scrolling popup painting issue on Windows 10 when a glass pane is
|
||||||
visible and frame is maximized. (issue #1071)
|
visible and frame is maximized. (issue #1071)
|
||||||
|
- Slider: Styling `thumbSize` or `focusWidth` did not update slider size/layout.
|
||||||
|
(PR #1074)
|
||||||
|
- ToolBar: Grip disappeared when switching between Look and Feels. (issue #1075)
|
||||||
|
- Extras:
|
||||||
|
- UI defaults inspector: Fixed NPE if color of `FlatLineBorder` is null. Also
|
||||||
|
use `FlatLineBorder` line color as cell background color in "Value" column.
|
||||||
|
(PR #1080)
|
||||||
|
- `FlatDesktop`: Avoid unnecessary logging if desktop is not supported (e.g.
|
||||||
|
on NixOS with Plasma/KDE desktop).
|
||||||
|
|
||||||
|
|
||||||
## 3.7
|
## 3.7
|
||||||
|
|||||||
17
README.md
17
README.md
@@ -76,10 +76,19 @@ Otherwise, download `flatlaf-<version>.jar` here:
|
|||||||
|
|
||||||
[](https://central.sonatype.com/artifact/com.formdev/flatlaf)
|
[](https://central.sonatype.com/artifact/com.formdev/flatlaf)
|
||||||
|
|
||||||
See also
|
- See
|
||||||
[Native Libraries distribution](https://www.formdev.com/flatlaf/native-libraries/)
|
[Native Libraries distribution](https://www.formdev.com/flatlaf/native-libraries/)
|
||||||
for instructions on how to redistribute FlatLaf native libraries with your
|
for instructions on how to redistribute FlatLaf native libraries with your
|
||||||
application.
|
application.
|
||||||
|
- Windows DLLs: Free code signing provided by
|
||||||
|
[SignPath.io](https://about.signpath.io/), certificate by
|
||||||
|
[SignPath Foundation](https://signpath.org/).
|
||||||
|
- If repackaging FlatLaf (and other) JARs into a single fat/uber JAR:
|
||||||
|
- add `Multi-Release: true` to `META-INF/MANIFEST.MF`
|
||||||
|
- keep `META-INF/versions/` and `META-INF/services/` directories
|
||||||
|
- merge content of equally named files in `META-INF/services/`
|
||||||
|
- If using obfuscation/minimizing/shrinking tools (e.g. **ProGuard** or
|
||||||
|
**Shadow**), exclude package `com.formdev.flatlaf` and all sub-packages.
|
||||||
|
|
||||||
|
|
||||||
### Snapshots
|
### Snapshots
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ import com.formdev.flatlaf.util.SystemInfo;
|
|||||||
*/
|
*/
|
||||||
public class FlatNativeLinuxLibrary
|
public class FlatNativeLinuxLibrary
|
||||||
{
|
{
|
||||||
private static int API_VERSION_LINUX = 3004;
|
private static int API_VERSION_LINUX = 3003;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks whether native library is loaded/available.
|
* Checks whether native library is loaded/available.
|
||||||
@@ -186,8 +186,8 @@ public class FlatNativeLinuxLibrary
|
|||||||
* Use '__' for '_' character (e.g. "Choose__and__Quit").
|
* Use '__' for '_' character (e.g. "Choose__and__Quit").
|
||||||
* @param currentName user-editable filename currently shown in the filename field in save dialog; or {@code null}
|
* @param currentName user-editable filename currently shown in the filename field in save dialog; or {@code null}
|
||||||
* @param currentFolder current directory shown in the dialog; or {@code null}
|
* @param currentFolder current directory shown in the dialog; or {@code null}
|
||||||
* @param optionsSet options to set; see {@code FC_*} constants
|
* @param optionsSet options to set; see {@code FOS_*} constants
|
||||||
* @param optionsClear options to clear; see {@code FC_*} constants
|
* @param optionsClear options to clear; see {@code FOS_*} constants
|
||||||
* @param callback approve callback; or {@code null}
|
* @param callback approve callback; or {@code null}
|
||||||
* @param fileTypeIndex the file type that appears as selected (zero-based)
|
* @param fileTypeIndex the file type that appears as selected (zero-based)
|
||||||
* @param fileTypes file types that the dialog can open or save.
|
* @param fileTypes file types that the dialog can open or save.
|
||||||
@@ -195,20 +195,19 @@ public class FlatNativeLinuxLibrary
|
|||||||
* First string is the display name of the filter shown in the combobox (e.g. "Text Files").
|
* First string is the display name of the filter shown in the combobox (e.g. "Text Files").
|
||||||
* Subsequent strings are the filter patterns (e.g. "*.txt" or "*").
|
* Subsequent strings are the filter patterns (e.g. "*.txt" or "*").
|
||||||
* {@code null} is required to mark end of filter.
|
* {@code null} is required to mark end of filter.
|
||||||
* @param retFileTypeIndex returns selected file type (zero-based); array must be have one element
|
|
||||||
* @return file path(s) that the user selected; an empty array if canceled;
|
* @return file path(s) that the user selected; an empty array if canceled;
|
||||||
* or {@code null} on failures (no dialog shown)
|
* or {@code null} on failures (no dialog shown)
|
||||||
*
|
*
|
||||||
* @since 3.7.1
|
* @since 3.7
|
||||||
*/
|
*/
|
||||||
public native static String[] showFileChooser( Window owner, int dark, boolean open,
|
public native static String[] showFileChooser( Window owner, int dark, boolean open,
|
||||||
String title, String okButtonLabel, String currentName, String currentFolder,
|
String title, String okButtonLabel, String currentName, String currentFolder,
|
||||||
int optionsSet, int optionsClear, FileChooserCallback callback,
|
int optionsSet, int optionsClear, FileChooserCallback callback,
|
||||||
int fileTypeIndex, String[] fileTypes, int[] retFileTypeIndex );
|
int fileTypeIndex, String... fileTypes );
|
||||||
|
|
||||||
/** @since 3.7.1 */
|
/** @since 3.7 */
|
||||||
public interface FileChooserCallback {
|
public interface FileChooserCallback {
|
||||||
boolean approve( String[] files, int fileTypeIndex, long hwndFileDialog );
|
boolean approve( String[] files, long hwndFileDialog );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ import com.formdev.flatlaf.util.SystemInfo;
|
|||||||
*/
|
*/
|
||||||
public class FlatNativeMacLibrary
|
public class FlatNativeMacLibrary
|
||||||
{
|
{
|
||||||
private static int API_VERSION_MACOS = 2003;
|
private static int API_VERSION_MACOS = 2002;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks whether native library is loaded/available.
|
* Checks whether native library is loaded/available.
|
||||||
@@ -115,23 +115,22 @@ public class FlatNativeMacLibrary
|
|||||||
* @param fileTypes file types that the dialog can open or save.
|
* @param fileTypes file types that the dialog can open or save.
|
||||||
* Two or more strings and {@code null} are required for each filter.
|
* Two or more strings and {@code null} are required for each filter.
|
||||||
* First string is the display name of the filter shown in the combobox (e.g. "Text Files").
|
* First string is the display name of the filter shown in the combobox (e.g. "Text Files").
|
||||||
* Subsequent strings are the file name extensions (e.g. "txt" or "*"; '.' is not supported).
|
* Subsequent strings are the filter patterns (e.g. "txt" or "*").
|
||||||
* {@code null} is required to mark end of filter.
|
* {@code null} is required to mark end of filter.
|
||||||
* @param retFileTypeIndex returns selected file type (zero-based); array must be have one element
|
|
||||||
* @return file path(s) that the user selected; an empty array if canceled;
|
* @return file path(s) that the user selected; an empty array if canceled;
|
||||||
* or {@code null} on failures (no dialog shown)
|
* or {@code null} on failures (no dialog shown)
|
||||||
*
|
*
|
||||||
* @since 3.7.1
|
* @since 3.7
|
||||||
*/
|
*/
|
||||||
public native static String[] showFileChooser( Window owner, int dark, boolean open,
|
public native static String[] showFileChooser( Window owner, int dark, boolean open,
|
||||||
String title, String prompt, String message, String filterFieldLabel,
|
String title, String prompt, String message, String filterFieldLabel,
|
||||||
String nameFieldLabel, String nameFieldStringValue, String directoryURL,
|
String nameFieldLabel, String nameFieldStringValue, String directoryURL,
|
||||||
int optionsSet, int optionsClear, FileChooserCallback callback,
|
int optionsSet, int optionsClear, FileChooserCallback callback,
|
||||||
int fileTypeIndex, String[] fileTypes, int[] retFileTypeIndex );
|
int fileTypeIndex, String... fileTypes );
|
||||||
|
|
||||||
/** @since 3.7.1 */
|
/** @since 3.7 */
|
||||||
public interface FileChooserCallback {
|
public interface FileChooserCallback {
|
||||||
boolean approve( String[] files, int fileTypeIndex, long hwndFileDialog );
|
boolean approve( String[] files, long hwndFileDialog );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ import com.formdev.flatlaf.util.SystemInfo;
|
|||||||
*/
|
*/
|
||||||
public class FlatNativeWindowsLibrary
|
public class FlatNativeWindowsLibrary
|
||||||
{
|
{
|
||||||
private static int API_VERSION_WINDOWS = 1003;
|
private static int API_VERSION_WINDOWS = 1002;
|
||||||
|
|
||||||
private static long osBuildNumber = Long.MIN_VALUE;
|
private static long osBuildNumber = Long.MIN_VALUE;
|
||||||
|
|
||||||
@@ -226,21 +226,20 @@ public class FlatNativeWindowsLibrary
|
|||||||
* Pairs of strings are required for each filter.
|
* Pairs of strings are required for each filter.
|
||||||
* First string is the display name of the filter shown in the combobox (e.g. "Text Files").
|
* First string is the display name of the filter shown in the combobox (e.g. "Text Files").
|
||||||
* Second string is the filter pattern (e.g. "*.txt", "*.exe;*.dll" or "*.*").
|
* Second string is the filter pattern (e.g. "*.txt", "*.exe;*.dll" or "*.*").
|
||||||
* @param retFileTypeIndex returns selected file type (zero-based); array must be have one element
|
|
||||||
* @return file path(s) that the user selected; an empty array if canceled;
|
* @return file path(s) that the user selected; an empty array if canceled;
|
||||||
* or {@code null} on failures (no dialog shown)
|
* or {@code null} on failures (no dialog shown)
|
||||||
*
|
*
|
||||||
* @since 3.7.1
|
* @since 3.7
|
||||||
*/
|
*/
|
||||||
public native static String[] showFileChooser( Window owner, boolean open,
|
public native static String[] showFileChooser( Window owner, boolean open,
|
||||||
String title, String okButtonLabel, String fileNameLabel, String fileName,
|
String title, String okButtonLabel, String fileNameLabel, String fileName,
|
||||||
String folder, String saveAsItem, String defaultFolder, String defaultExtension,
|
String folder, String saveAsItem, String defaultFolder, String defaultExtension,
|
||||||
int optionsSet, int optionsClear, FileChooserCallback callback,
|
int optionsSet, int optionsClear, FileChooserCallback callback,
|
||||||
int fileTypeIndex, String[] fileTypes, int[] retFileTypeIndex );
|
int fileTypeIndex, String... fileTypes );
|
||||||
|
|
||||||
/** @since 3.7.1 */
|
/** @since 3.7 */
|
||||||
public interface FileChooserCallback {
|
public interface FileChooserCallback {
|
||||||
boolean approve( String[] files, int fileTypeIndex, long hwndFileDialog );
|
boolean approve( String[] files, long hwndFileDialog );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -227,7 +227,13 @@ public class FlatSliderUI
|
|||||||
|
|
||||||
/** @since 2 */
|
/** @since 2 */
|
||||||
protected void applyStyle( Object style ) {
|
protected void applyStyle( Object style ) {
|
||||||
|
Dimension oldThumbSize = thumbSize;
|
||||||
|
int oldFocusWidth = focusWidth;
|
||||||
|
|
||||||
oldStyleValues = FlatStylingSupport.parseAndApply( oldStyleValues, style, this::applyStyleProperty );
|
oldStyleValues = FlatStylingSupport.parseAndApply( oldStyleValues, style, this::applyStyleProperty );
|
||||||
|
|
||||||
|
if( !thumbSize.equals( oldThumbSize ) || focusWidth != oldFocusWidth )
|
||||||
|
calculateGeometry();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @since 2 */
|
/** @since 2 */
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ import java.awt.event.ComponentListener;
|
|||||||
import java.awt.event.FocusEvent;
|
import java.awt.event.FocusEvent;
|
||||||
import java.awt.event.FocusListener;
|
import java.awt.event.FocusListener;
|
||||||
import java.awt.geom.Rectangle2D;
|
import java.awt.geom.Rectangle2D;
|
||||||
import java.beans.PropertyChangeEvent;
|
|
||||||
import java.beans.PropertyChangeListener;
|
import java.beans.PropertyChangeListener;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import javax.swing.Action;
|
import javax.swing.Action;
|
||||||
@@ -66,6 +65,7 @@ import com.formdev.flatlaf.FlatClientProperties;
|
|||||||
import com.formdev.flatlaf.icons.FlatCheckBoxIcon;
|
import com.formdev.flatlaf.icons.FlatCheckBoxIcon;
|
||||||
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
|
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
|
||||||
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI;
|
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI;
|
||||||
|
import com.formdev.flatlaf.ui.FlatUIUtils.FlatPropertyWatcher;
|
||||||
import com.formdev.flatlaf.util.Graphics2DProxy;
|
import com.formdev.flatlaf.util.Graphics2DProxy;
|
||||||
import com.formdev.flatlaf.util.HiDPIUtils;
|
import com.formdev.flatlaf.util.HiDPIUtils;
|
||||||
import com.formdev.flatlaf.util.LoggingFacade;
|
import com.formdev.flatlaf.util.LoggingFacade;
|
||||||
@@ -189,29 +189,26 @@ public class FlatTableUI
|
|||||||
if( rowHeight > 0 )
|
if( rowHeight > 0 )
|
||||||
LookAndFeel.installProperty( table, "rowHeight", UIScale.scale( rowHeight ) );
|
LookAndFeel.installProperty( table, "rowHeight", UIScale.scale( rowHeight ) );
|
||||||
|
|
||||||
FlatTablePropertyWatcher watcher = FlatTablePropertyWatcher.get( table );
|
if( !showHorizontalLines ) {
|
||||||
if( watcher != null )
|
FlatPropertyWatcher.runIfNotChanged( table, "showHorizontalLines", () -> {
|
||||||
watcher.enabled = false;
|
oldShowHorizontalLines = table.getShowHorizontalLines();
|
||||||
|
table.setShowHorizontalLines( false );
|
||||||
if( !showHorizontalLines && (watcher == null || !watcher.showHorizontalLinesChanged) ) {
|
} );
|
||||||
oldShowHorizontalLines = table.getShowHorizontalLines();
|
|
||||||
table.setShowHorizontalLines( false );
|
|
||||||
}
|
}
|
||||||
if( !showVerticalLines && (watcher == null || !watcher.showVerticalLinesChanged) ) {
|
if( !showVerticalLines ) {
|
||||||
oldShowVerticalLines = table.getShowVerticalLines();
|
FlatPropertyWatcher.runIfNotChanged( table, "showVerticalLines", () -> {
|
||||||
table.setShowVerticalLines( false );
|
oldShowVerticalLines = table.getShowVerticalLines();
|
||||||
|
table.setShowVerticalLines( false );
|
||||||
|
} );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( intercellSpacing != null && (watcher == null || !watcher.intercellSpacingChanged) ) {
|
if( intercellSpacing != null ) {
|
||||||
oldIntercellSpacing = table.getIntercellSpacing();
|
FlatPropertyWatcher.runIfNotChanged( table, "rowMargin", () -> {
|
||||||
table.setIntercellSpacing( intercellSpacing );
|
oldIntercellSpacing = table.getIntercellSpacing();
|
||||||
|
table.setIntercellSpacing( intercellSpacing );
|
||||||
|
} );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( watcher != null )
|
|
||||||
watcher.enabled = true;
|
|
||||||
else
|
|
||||||
table.addPropertyChangeListener( new FlatTablePropertyWatcher() );
|
|
||||||
|
|
||||||
// install boolean renderer
|
// install boolean renderer
|
||||||
oldBooleanRenderer = table.getDefaultRenderer( Boolean.class );
|
oldBooleanRenderer = table.getDefaultRenderer( Boolean.class );
|
||||||
if( oldBooleanRenderer instanceof UIResource )
|
if( oldBooleanRenderer instanceof UIResource )
|
||||||
@@ -231,25 +228,24 @@ public class FlatTableUI
|
|||||||
|
|
||||||
oldStyleValues = null;
|
oldStyleValues = null;
|
||||||
|
|
||||||
FlatTablePropertyWatcher watcher = FlatTablePropertyWatcher.get( table );
|
|
||||||
if( watcher != null )
|
|
||||||
watcher.enabled = false;
|
|
||||||
|
|
||||||
// restore old show horizontal/vertical lines (if not modified)
|
// restore old show horizontal/vertical lines (if not modified)
|
||||||
if( !showHorizontalLines && oldShowHorizontalLines && !table.getShowHorizontalLines() &&
|
if( !showHorizontalLines && oldShowHorizontalLines && !table.getShowHorizontalLines() ) {
|
||||||
(watcher == null || !watcher.showHorizontalLinesChanged) )
|
FlatPropertyWatcher.runIfNotChanged( table, "showHorizontalLines", () -> {
|
||||||
table.setShowHorizontalLines( true );
|
table.setShowHorizontalLines( true );
|
||||||
if( !showVerticalLines && oldShowVerticalLines && !table.getShowVerticalLines() &&
|
} );
|
||||||
(watcher == null || !watcher.showVerticalLinesChanged) )
|
}
|
||||||
table.setShowVerticalLines( true );
|
if( !showVerticalLines && oldShowVerticalLines && !table.getShowVerticalLines() ) {
|
||||||
|
FlatPropertyWatcher.runIfNotChanged( table, "showVerticalLines", () -> {
|
||||||
|
table.setShowVerticalLines( true );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
// restore old intercell spacing (if not modified)
|
// restore old intercell spacing (if not modified)
|
||||||
if( intercellSpacing != null && table.getIntercellSpacing().equals( intercellSpacing ) &&
|
if( intercellSpacing != null && table.getIntercellSpacing().equals( intercellSpacing ) ) {
|
||||||
(watcher == null || !watcher.intercellSpacingChanged) )
|
FlatPropertyWatcher.runIfNotChanged( table, "rowMargin", () -> {
|
||||||
table.setIntercellSpacing( oldIntercellSpacing );
|
table.setIntercellSpacing( oldIntercellSpacing );
|
||||||
|
} );
|
||||||
if( watcher != null )
|
}
|
||||||
watcher.enabled = true;
|
|
||||||
|
|
||||||
// uninstall boolean renderer
|
// uninstall boolean renderer
|
||||||
if( table.getDefaultRenderer( Boolean.class ) instanceof FlatBooleanRenderer ) {
|
if( table.getDefaultRenderer( Boolean.class ) instanceof FlatBooleanRenderer ) {
|
||||||
@@ -938,48 +934,6 @@ public class FlatTableUI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//---- class FlatTablePropertyWatcher -------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Listener that watches for change of some table properties from application code.
|
|
||||||
* This information is used in {@link FlatTableUI#installDefaults()} and
|
|
||||||
* {@link FlatTableUI#uninstallDefaults()} to decide whether FlatLaf modifies those properties.
|
|
||||||
* If they are modified in application code, FlatLaf no longer changes them.
|
|
||||||
*
|
|
||||||
* The listener is added once for each table, but never removed.
|
|
||||||
* So switching Laf/theme reuses existing listener.
|
|
||||||
*/
|
|
||||||
private static class FlatTablePropertyWatcher
|
|
||||||
implements PropertyChangeListener
|
|
||||||
{
|
|
||||||
boolean enabled = true;
|
|
||||||
boolean showHorizontalLinesChanged;
|
|
||||||
boolean showVerticalLinesChanged;
|
|
||||||
boolean intercellSpacingChanged;
|
|
||||||
|
|
||||||
static FlatTablePropertyWatcher get( JTable table ) {
|
|
||||||
for( PropertyChangeListener l : table.getPropertyChangeListeners() ) {
|
|
||||||
if( l instanceof FlatTablePropertyWatcher )
|
|
||||||
return (FlatTablePropertyWatcher) l;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
//---- interface PropertyChangeListener ----
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void propertyChange( PropertyChangeEvent e ) {
|
|
||||||
if( !enabled )
|
|
||||||
return;
|
|
||||||
|
|
||||||
switch( e.getPropertyName() ) {
|
|
||||||
case "showHorizontalLines": showHorizontalLinesChanged = true; break;
|
|
||||||
case "showVerticalLines": showVerticalLinesChanged = true; break;
|
|
||||||
case "rowMargin": intercellSpacingChanged = true; break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//---- class FlatBooleanRenderer ------------------------------------------
|
//---- class FlatBooleanRenderer ------------------------------------------
|
||||||
|
|
||||||
private static class FlatBooleanRenderer
|
private static class FlatBooleanRenderer
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ import javax.swing.plaf.basic.BasicToolBarUI;
|
|||||||
import com.formdev.flatlaf.FlatClientProperties;
|
import com.formdev.flatlaf.FlatClientProperties;
|
||||||
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
|
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
|
||||||
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI;
|
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI;
|
||||||
|
import com.formdev.flatlaf.ui.FlatUIUtils.FlatPropertyWatcher;
|
||||||
import com.formdev.flatlaf.util.HiDPIUtils;
|
import com.formdev.flatlaf.util.HiDPIUtils;
|
||||||
import com.formdev.flatlaf.util.LoggingFacade;
|
import com.formdev.flatlaf.util.LoggingFacade;
|
||||||
import com.formdev.flatlaf.util.UIScale;
|
import com.formdev.flatlaf.util.UIScale;
|
||||||
@@ -144,11 +145,13 @@ public class FlatToolBarUI
|
|||||||
hoverButtonGroupBackground = UIManager.getColor( "ToolBar.hoverButtonGroupBackground" );
|
hoverButtonGroupBackground = UIManager.getColor( "ToolBar.hoverButtonGroupBackground" );
|
||||||
|
|
||||||
// floatable
|
// floatable
|
||||||
|
oldFloatable = null;
|
||||||
if( !UIManager.getBoolean( "ToolBar.floatable" ) ) {
|
if( !UIManager.getBoolean( "ToolBar.floatable" ) ) {
|
||||||
oldFloatable = toolBar.isFloatable();
|
FlatPropertyWatcher.runIfNotChanged( toolBar, "floatable", () -> {
|
||||||
toolBar.setFloatable( false );
|
oldFloatable = toolBar.isFloatable();
|
||||||
} else
|
toolBar.setFloatable( false );
|
||||||
oldFloatable = null;
|
} );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -158,7 +161,9 @@ public class FlatToolBarUI
|
|||||||
hoverButtonGroupBackground = null;
|
hoverButtonGroupBackground = null;
|
||||||
|
|
||||||
if( oldFloatable != null ) {
|
if( oldFloatable != null ) {
|
||||||
toolBar.setFloatable( oldFloatable );
|
FlatPropertyWatcher.runIfNotChanged( toolBar, "floatable", () -> {
|
||||||
|
toolBar.setFloatable( oldFloatable );
|
||||||
|
} );
|
||||||
oldFloatable = null;
|
oldFloatable = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,6 +44,8 @@ import java.awt.geom.Path2D;
|
|||||||
import java.awt.geom.Point2D;
|
import java.awt.geom.Point2D;
|
||||||
import java.awt.geom.Rectangle2D;
|
import java.awt.geom.Rectangle2D;
|
||||||
import java.awt.geom.RoundRectangle2D;
|
import java.awt.geom.RoundRectangle2D;
|
||||||
|
import java.beans.PropertyChangeEvent;
|
||||||
|
import java.beans.PropertyChangeListener;
|
||||||
import java.util.IdentityHashMap;
|
import java.util.IdentityHashMap;
|
||||||
import java.util.WeakHashMap;
|
import java.util.WeakHashMap;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
@@ -1413,4 +1415,47 @@ debug*/
|
|||||||
return delegate.isBorderOpaque();
|
return delegate.isBorderOpaque();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---- class FlatPropertyWatcher ------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listener that watches for change of a property from application code.
|
||||||
|
* This information can be used to decide whether FlatLaf modifies the property.
|
||||||
|
* If it is modified in application code, FlatLaf no longer changes it.
|
||||||
|
* <p>
|
||||||
|
* The listener is added once for a property, but never removed.
|
||||||
|
* So switching Laf/theme reuses existing listener.
|
||||||
|
*/
|
||||||
|
static class FlatPropertyWatcher
|
||||||
|
implements PropertyChangeListener
|
||||||
|
{
|
||||||
|
private boolean changed;
|
||||||
|
|
||||||
|
static void runIfNotChanged( JComponent c, String propName, Runnable runnable ) {
|
||||||
|
FlatPropertyWatcher watcher = getOrInstall( c, propName );
|
||||||
|
if( watcher.changed )
|
||||||
|
return;
|
||||||
|
|
||||||
|
runnable.run();
|
||||||
|
watcher.changed = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static FlatPropertyWatcher getOrInstall( JComponent c, String propName ) {
|
||||||
|
for( PropertyChangeListener l : c.getPropertyChangeListeners( propName ) ) {
|
||||||
|
if( l instanceof FlatPropertyWatcher )
|
||||||
|
return (FlatPropertyWatcher) l;
|
||||||
|
}
|
||||||
|
|
||||||
|
FlatPropertyWatcher watcher = new FlatPropertyWatcher();
|
||||||
|
c.addPropertyChangeListener( propName, watcher );
|
||||||
|
return watcher;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---- interface PropertyChangeListener ----
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void propertyChange( PropertyChangeEvent e ) {
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,8 +18,6 @@ package com.formdev.flatlaf.util;
|
|||||||
|
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
import java.awt.EventQueue;
|
|
||||||
import java.awt.Frame;
|
|
||||||
import java.awt.KeyboardFocusManager;
|
import java.awt.KeyboardFocusManager;
|
||||||
import java.awt.SecondaryLoop;
|
import java.awt.SecondaryLoop;
|
||||||
import java.awt.Toolkit;
|
import java.awt.Toolkit;
|
||||||
@@ -30,13 +28,11 @@ import java.lang.reflect.Method;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.IdentityHashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Scanner;
|
import java.util.Scanner;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
import java.util.regex.Pattern;
|
|
||||||
import javax.swing.JDialog;
|
import javax.swing.JDialog;
|
||||||
import javax.swing.JFileChooser;
|
import javax.swing.JFileChooser;
|
||||||
import javax.swing.JOptionPane;
|
import javax.swing.JOptionPane;
|
||||||
@@ -91,8 +87,7 @@ import com.formdev.flatlaf.ui.FlatNativeWindowsLibrary;
|
|||||||
* <li>{@link JFileChooser#FILES_AND_DIRECTORIES} is not supported.
|
* <li>{@link JFileChooser#FILES_AND_DIRECTORIES} is not supported.
|
||||||
* <li>{@link #getSelectedFiles()} returns selected file also in single selection mode.
|
* <li>{@link #getSelectedFiles()} returns selected file also in single selection mode.
|
||||||
* {@link JFileChooser#getSelectedFiles()} only in multi selection mode.
|
* {@link JFileChooser#getSelectedFiles()} only in multi selection mode.
|
||||||
* <li>Only file name extension filters (see {@link FileNameExtensionFilter}) are supported on all platforms.
|
* <li>Only file name extension filters (see {@link FileNameExtensionFilter}) are supported.
|
||||||
* <li>Pattern filters (see {@link PatternFilter}) are only supported on Windows and Linux, but not on macOS.
|
|
||||||
* <li>If adding choosable file filters and {@link #isAcceptAllFileFilterUsed()} is {@code true},
|
* <li>If adding choosable file filters and {@link #isAcceptAllFileFilterUsed()} is {@code true},
|
||||||
* then the <b>All Files</b> filter is placed at the end of the combobox list
|
* then the <b>All Files</b> filter is placed at the end of the combobox list
|
||||||
* (as usual in current operating systems) and the first choosable filter is selected by default.
|
* (as usual in current operating systems) and the first choosable filter is selected by default.
|
||||||
@@ -589,7 +584,6 @@ public class SystemFileChooser
|
|||||||
private void checkSupportedFileFilter( FileFilter filter ) throws IllegalArgumentException {
|
private void checkSupportedFileFilter( FileFilter filter ) throws IllegalArgumentException {
|
||||||
if( filter == null ||
|
if( filter == null ||
|
||||||
filter instanceof FileNameExtensionFilter ||
|
filter instanceof FileNameExtensionFilter ||
|
||||||
filter instanceof PatternFilter ||
|
|
||||||
filter instanceof AcceptAllFileFilter )
|
filter instanceof AcceptAllFileFilter )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -613,11 +607,6 @@ public class SystemFileChooser
|
|||||||
return filters2;
|
return filters2;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateFileFilter( List<FileFilter> filters, int index ) {
|
|
||||||
if( index >= 0 && index < filters.size() )
|
|
||||||
setFileFilter( filters.get( index ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
public ApproveCallback getApproveCallback() {
|
public ApproveCallback getApproveCallback() {
|
||||||
return approveCallback;
|
return approveCallback;
|
||||||
}
|
}
|
||||||
@@ -748,9 +737,6 @@ public class SystemFileChooser
|
|||||||
}
|
}
|
||||||
|
|
||||||
private int showDialogImpl( Component parent ) {
|
private int showDialogImpl( Component parent ) {
|
||||||
if( !EventQueue.isDispatchThread() )
|
|
||||||
throw new IllegalStateException( "Must be invoked from the AWT/Swing event dispatch thread" );
|
|
||||||
|
|
||||||
Window owner = (parent instanceof Window)
|
Window owner = (parent instanceof Window)
|
||||||
? (Window) parent
|
? (Window) parent
|
||||||
: (parent != null) ? SwingUtilities.windowForComponent( parent ) : null;
|
: (parent != null) ? SwingUtilities.windowForComponent( parent ) : null;
|
||||||
@@ -799,16 +785,6 @@ public class SystemFileChooser
|
|||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
public File[] showDialog( Window owner, SystemFileChooser fc ) {
|
public File[] showDialog( Window owner, SystemFileChooser fc ) {
|
||||||
// if there is no displayable window, then AWT's auto-shutdown feature
|
|
||||||
// quits our secondary event loop (see below) immediately
|
|
||||||
// https://docs.oracle.com/en/java/javase/25/docs/api/java.desktop/java/awt/doc-files/AWTThreadIssues.html#Autoshutdown
|
|
||||||
Window dummyWindow = null;
|
|
||||||
if( !hasDisplayableWindow( owner ) ) {
|
|
||||||
// create a (not visible) displayable window to avoid AWT auto-shutdown
|
|
||||||
dummyWindow = new Window( (Frame) null );
|
|
||||||
dummyWindow.addNotify();
|
|
||||||
}
|
|
||||||
|
|
||||||
AtomicReference<String[]> filenamesRef = new AtomicReference<>();
|
AtomicReference<String[]> filenamesRef = new AtomicReference<>();
|
||||||
|
|
||||||
// create secondary event look and invoke system file dialog on a new thread
|
// create secondary event look and invoke system file dialog on a new thread
|
||||||
@@ -819,10 +795,6 @@ public class SystemFileChooser
|
|||||||
}, "FlatLaf SystemFileChooser" ).start();
|
}, "FlatLaf SystemFileChooser" ).start();
|
||||||
secondaryLoop.enter();
|
secondaryLoop.enter();
|
||||||
|
|
||||||
// dispose dummy window to allow AWT to auto-shutdown
|
|
||||||
if( dummyWindow != null )
|
|
||||||
dummyWindow.dispose();
|
|
||||||
|
|
||||||
String[] filenames = filenamesRef.get();
|
String[] filenames = filenamesRef.get();
|
||||||
|
|
||||||
// fallback to Swing file chooser if system file dialog failed or is not available
|
// fallback to Swing file chooser if system file dialog failed or is not available
|
||||||
@@ -859,17 +831,6 @@ public class SystemFileChooser
|
|||||||
files[i] = fsv.createFileObject( filenames[i] );
|
files[i] = fsv.createFileObject( filenames[i] );
|
||||||
return files;
|
return files;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean hasDisplayableWindow( Window owner ) {
|
|
||||||
if( owner != null && owner.isDisplayable() )
|
|
||||||
return true;
|
|
||||||
|
|
||||||
for( Window window : Window.getWindows() ) {
|
|
||||||
if( window.isDisplayable() )
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//---- class WindowsFileChooserProvider -----------------------------------
|
//---- class WindowsFileChooserProvider -----------------------------------
|
||||||
@@ -929,7 +890,6 @@ public class SystemFileChooser
|
|||||||
// filter
|
// filter
|
||||||
int fileTypeIndex = 0;
|
int fileTypeIndex = 0;
|
||||||
ArrayList<String> fileTypes = new ArrayList<>();
|
ArrayList<String> fileTypes = new ArrayList<>();
|
||||||
ArrayList<FileFilter> fileTypeFilters = new ArrayList<>();
|
|
||||||
if( !fc.isDirectorySelectionEnabled() ) {
|
if( !fc.isDirectorySelectionEnabled() ) {
|
||||||
List<FileFilter> filters = fc.getFiltersForDialog();
|
List<FileFilter> filters = fc.getFiltersForDialog();
|
||||||
if( !filters.isEmpty() ) {
|
if( !filters.isEmpty() ) {
|
||||||
@@ -938,15 +898,9 @@ public class SystemFileChooser
|
|||||||
if( filter instanceof FileNameExtensionFilter ) {
|
if( filter instanceof FileNameExtensionFilter ) {
|
||||||
fileTypes.add( filter.getDescription() );
|
fileTypes.add( filter.getDescription() );
|
||||||
fileTypes.add( "*." + String.join( ";*.", ((FileNameExtensionFilter)filter).getExtensions() ) );
|
fileTypes.add( "*." + String.join( ";*.", ((FileNameExtensionFilter)filter).getExtensions() ) );
|
||||||
fileTypeFilters.add( filter );
|
|
||||||
} else if( filter instanceof PatternFilter ) {
|
|
||||||
fileTypes.add( filter.getDescription() );
|
|
||||||
fileTypes.add( String.join( ";", ((PatternFilter)filter).getPatterns() ) );
|
|
||||||
fileTypeFilters.add( filter );
|
|
||||||
} else if( filter instanceof AcceptAllFileFilter ) {
|
} else if( filter instanceof AcceptAllFileFilter ) {
|
||||||
fileTypes.add( filter.getDescription() );
|
fileTypes.add( filter.getDescription() );
|
||||||
fileTypes.add( "*.*" );
|
fileTypes.add( "*.*" );
|
||||||
fileTypeFilters.add( filter );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -962,24 +916,19 @@ public class SystemFileChooser
|
|||||||
|
|
||||||
// callback
|
// callback
|
||||||
FlatNativeWindowsLibrary.FileChooserCallback callback = (fc.getApproveCallback() != null)
|
FlatNativeWindowsLibrary.FileChooserCallback callback = (fc.getApproveCallback() != null)
|
||||||
? (files, fileTypeIndex2, hwndFileDialog) -> {
|
? (files, hwndFileDialog) -> {
|
||||||
fc.updateFileFilter( fileTypeFilters, fileTypeIndex2 );
|
|
||||||
return invokeApproveCallback( fc, files, new WindowsApproveContext( hwndFileDialog ) );
|
return invokeApproveCallback( fc, files, new WindowsApproveContext( hwndFileDialog ) );
|
||||||
} : null;
|
} : null;
|
||||||
|
|
||||||
// show system file dialog
|
// show system file dialog
|
||||||
int[] retFileTypeIndex = { -1 };
|
return FlatNativeWindowsLibrary.showFileChooser( owner, open,
|
||||||
String[] result = FlatNativeWindowsLibrary.showFileChooser( owner, open,
|
|
||||||
fc.getDialogTitle(), approveButtonText,
|
fc.getDialogTitle(), approveButtonText,
|
||||||
fc.getPlatformProperty( WINDOWS_FILE_NAME_LABEL ),
|
fc.getPlatformProperty( WINDOWS_FILE_NAME_LABEL ),
|
||||||
fileName, folder, saveAsItem,
|
fileName, folder, saveAsItem,
|
||||||
fc.getPlatformProperty( WINDOWS_DEFAULT_FOLDER ),
|
fc.getPlatformProperty( WINDOWS_DEFAULT_FOLDER ),
|
||||||
fc.getPlatformProperty( WINDOWS_DEFAULT_EXTENSION ),
|
fc.getPlatformProperty( WINDOWS_DEFAULT_EXTENSION ),
|
||||||
optionsSet, optionsClear, callback,
|
optionsSet, optionsClear, callback,
|
||||||
fileTypeIndex, fileTypes.toArray( new String[fileTypes.size()] ), retFileTypeIndex );
|
fileTypeIndex, fileTypes.toArray( new String[fileTypes.size()] ) );
|
||||||
if( result != null )
|
|
||||||
fc.updateFileFilter( fileTypeFilters, retFileTypeIndex[0] );
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//---- class WindowsApproveContext ----
|
//---- class WindowsApproveContext ----
|
||||||
@@ -1020,26 +969,6 @@ public class SystemFileChooser
|
|||||||
private static class MacFileChooserProvider
|
private static class MacFileChooserProvider
|
||||||
extends SystemFileChooserProvider
|
extends SystemFileChooserProvider
|
||||||
{
|
{
|
||||||
@Override
|
|
||||||
public File[] showDialog( Window owner, SystemFileChooser fc ) {
|
|
||||||
// fallback to Swing file chooser if PatternFilter is used
|
|
||||||
boolean usesPatternFilter = (fc.getFileFilter() instanceof PatternFilter);
|
|
||||||
if( !usesPatternFilter ) {
|
|
||||||
for( FileFilter filter : fc.getChoosableFileFilters() ) {
|
|
||||||
if( filter instanceof PatternFilter ) {
|
|
||||||
usesPatternFilter = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if( usesPatternFilter ) {
|
|
||||||
LoggingFacade.INSTANCE.logSevere( "FlatLaf: SystemFileChooser.PatternFilter is not supported on macOS. Using Swing JFileChooser.", null );
|
|
||||||
return new SwingFileChooserProvider().showDialog( owner, fc );
|
|
||||||
}
|
|
||||||
|
|
||||||
return super.showDialog( owner, fc );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
String[] showSystemDialog( Window owner, SystemFileChooser fc ) {
|
String[] showSystemDialog( Window owner, SystemFileChooser fc ) {
|
||||||
int dark = FlatLaf.isLafDark() ? 1 : 0;
|
int dark = FlatLaf.isLafDark() ? 1 : 0;
|
||||||
@@ -1084,7 +1013,6 @@ public class SystemFileChooser
|
|||||||
// filter
|
// filter
|
||||||
int fileTypeIndex = 0;
|
int fileTypeIndex = 0;
|
||||||
ArrayList<String> fileTypes = new ArrayList<>();
|
ArrayList<String> fileTypes = new ArrayList<>();
|
||||||
ArrayList<FileFilter> fileTypeFilters = new ArrayList<>();
|
|
||||||
if( !fc.isDirectorySelectionEnabled() ) {
|
if( !fc.isDirectorySelectionEnabled() ) {
|
||||||
List<FileFilter> filters = fc.getFiltersForDialog();
|
List<FileFilter> filters = fc.getFiltersForDialog();
|
||||||
if( !filters.isEmpty() ) {
|
if( !filters.isEmpty() ) {
|
||||||
@@ -1095,12 +1023,10 @@ public class SystemFileChooser
|
|||||||
for( String ext : ((FileNameExtensionFilter)filter).getExtensions() )
|
for( String ext : ((FileNameExtensionFilter)filter).getExtensions() )
|
||||||
fileTypes.add( ext );
|
fileTypes.add( ext );
|
||||||
fileTypes.add( null );
|
fileTypes.add( null );
|
||||||
fileTypeFilters.add( filter );
|
|
||||||
} else if( filter instanceof AcceptAllFileFilter ) {
|
} else if( filter instanceof AcceptAllFileFilter ) {
|
||||||
fileTypes.add( filter.getDescription() );
|
fileTypes.add( filter.getDescription() );
|
||||||
fileTypes.add( "*" );
|
fileTypes.add( "*" );
|
||||||
fileTypes.add( null );
|
fileTypes.add( null );
|
||||||
fileTypeFilters.add( filter );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1108,23 +1034,18 @@ public class SystemFileChooser
|
|||||||
|
|
||||||
// callback
|
// callback
|
||||||
FlatNativeMacLibrary.FileChooserCallback callback = (fc.getApproveCallback() != null)
|
FlatNativeMacLibrary.FileChooserCallback callback = (fc.getApproveCallback() != null)
|
||||||
? (files, fileTypeIndex2, hwndFileDialog) -> {
|
? (files, hwndFileDialog) -> {
|
||||||
fc.updateFileFilter( fileTypeFilters, fileTypeIndex2 );
|
|
||||||
return invokeApproveCallback( fc, files, new MacApproveContext( hwndFileDialog ) );
|
return invokeApproveCallback( fc, files, new MacApproveContext( hwndFileDialog ) );
|
||||||
} : null;
|
} : null;
|
||||||
|
|
||||||
// show system file dialog
|
// show system file dialog
|
||||||
int[] retFileTypeIndex = { -1 };
|
return FlatNativeMacLibrary.showFileChooser( owner, dark, open,
|
||||||
String[] result = FlatNativeMacLibrary.showFileChooser( owner, dark, open,
|
|
||||||
fc.getDialogTitle(), fc.getApproveButtonText(),
|
fc.getDialogTitle(), fc.getApproveButtonText(),
|
||||||
fc.getPlatformProperty( MAC_MESSAGE ),
|
fc.getPlatformProperty( MAC_MESSAGE ),
|
||||||
fc.getPlatformProperty( MAC_FILTER_FIELD_LABEL ),
|
fc.getPlatformProperty( MAC_FILTER_FIELD_LABEL ),
|
||||||
fc.getPlatformProperty( MAC_NAME_FIELD_LABEL ),
|
fc.getPlatformProperty( MAC_NAME_FIELD_LABEL ),
|
||||||
nameFieldStringValue, directoryURL, optionsSet, optionsClear, callback,
|
nameFieldStringValue, directoryURL, optionsSet, optionsClear, callback,
|
||||||
fileTypeIndex, fileTypes.toArray( new String[fileTypes.size()] ), retFileTypeIndex );
|
fileTypeIndex, fileTypes.toArray( new String[fileTypes.size()] ) );
|
||||||
if( result != null )
|
|
||||||
fc.updateFileFilter( fileTypeFilters, retFileTypeIndex[0] );
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//---- class MacApproveContext ----
|
//---- class MacApproveContext ----
|
||||||
@@ -1220,7 +1141,6 @@ public class SystemFileChooser
|
|||||||
// filter
|
// filter
|
||||||
int fileTypeIndex = 0;
|
int fileTypeIndex = 0;
|
||||||
ArrayList<String> fileTypes = new ArrayList<>();
|
ArrayList<String> fileTypes = new ArrayList<>();
|
||||||
ArrayList<FileFilter> fileTypeFilters = new ArrayList<>();
|
|
||||||
if( !fc.isDirectorySelectionEnabled() ) {
|
if( !fc.isDirectorySelectionEnabled() ) {
|
||||||
List<FileFilter> filters = fc.getFiltersForDialog();
|
List<FileFilter> filters = fc.getFiltersForDialog();
|
||||||
if( !filters.isEmpty() ) {
|
if( !filters.isEmpty() ) {
|
||||||
@@ -1229,19 +1149,12 @@ public class SystemFileChooser
|
|||||||
if( filter instanceof FileNameExtensionFilter ) {
|
if( filter instanceof FileNameExtensionFilter ) {
|
||||||
fileTypes.add( filter.getDescription() );
|
fileTypes.add( filter.getDescription() );
|
||||||
for( String ext : ((FileNameExtensionFilter)filter).getExtensions() )
|
for( String ext : ((FileNameExtensionFilter)filter).getExtensions() )
|
||||||
fileTypes.add( "*." + caseInsensitiveGlobPattern( ext ) );
|
fileTypes.add( caseInsensitiveGlobPattern( ext ) );
|
||||||
fileTypes.add( null );
|
fileTypes.add( null );
|
||||||
fileTypeFilters.add( filter );
|
|
||||||
} else if( filter instanceof PatternFilter ) {
|
|
||||||
fileTypes.add( filter.getDescription() );
|
|
||||||
for( String pattern : ((PatternFilter)filter).getPatterns() )
|
|
||||||
fileTypes.add( caseInsensitiveGlobPattern( pattern ) );
|
|
||||||
fileTypeFilters.add( filter );
|
|
||||||
} else if( filter instanceof AcceptAllFileFilter ) {
|
} else if( filter instanceof AcceptAllFileFilter ) {
|
||||||
fileTypes.add( filter.getDescription() );
|
fileTypes.add( filter.getDescription() );
|
||||||
fileTypes.add( "*" );
|
fileTypes.add( "*" );
|
||||||
fileTypes.add( null );
|
fileTypes.add( null );
|
||||||
fileTypeFilters.add( filter );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1249,24 +1162,20 @@ public class SystemFileChooser
|
|||||||
|
|
||||||
// callback
|
// callback
|
||||||
FlatNativeLinuxLibrary.FileChooserCallback callback = (fc.getApproveCallback() != null)
|
FlatNativeLinuxLibrary.FileChooserCallback callback = (fc.getApproveCallback() != null)
|
||||||
? (files, fileTypeIndex2, hwndFileDialog) -> {
|
? (files, hwndFileDialog) -> {
|
||||||
fc.updateFileFilter( fileTypeFilters, fileTypeIndex2 );
|
|
||||||
return invokeApproveCallback( fc, files, new LinuxApproveContext( hwndFileDialog ) );
|
return invokeApproveCallback( fc, files, new LinuxApproveContext( hwndFileDialog ) );
|
||||||
} : null;
|
} : null;
|
||||||
|
|
||||||
// show system file dialog
|
// show system file dialog
|
||||||
int[] retFileTypeIndex = { -1 };
|
return FlatNativeLinuxLibrary.showFileChooser( owner, dark, open,
|
||||||
String[] result = FlatNativeLinuxLibrary.showFileChooser( owner, dark, open,
|
|
||||||
fc.getDialogTitle(), approveButtonText, currentName, currentFolder,
|
fc.getDialogTitle(), approveButtonText, currentName, currentFolder,
|
||||||
optionsSet, optionsClear, callback,
|
optionsSet, optionsClear, callback,
|
||||||
fileTypeIndex, fileTypes.toArray( new String[fileTypes.size()] ), retFileTypeIndex );
|
fileTypeIndex, fileTypes.toArray( new String[fileTypes.size()] ) );
|
||||||
if( result != null )
|
|
||||||
fc.updateFileFilter( fileTypeFilters, retFileTypeIndex[0] );
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String caseInsensitiveGlobPattern( String ext ) {
|
private String caseInsensitiveGlobPattern( String ext ) {
|
||||||
StringBuilder buf = new StringBuilder();
|
StringBuilder buf = new StringBuilder();
|
||||||
|
buf.append( "*." );
|
||||||
int len = ext.length();
|
int len = ext.length();
|
||||||
for( int i = 0; i < len; i++ ) {
|
for( int i = 0; i < len; i++ ) {
|
||||||
char ch = ext.charAt( i );
|
char ch = ext.charAt( i );
|
||||||
@@ -1344,8 +1253,6 @@ public class SystemFileChooser
|
|||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
public File[] showDialog( Window owner, SystemFileChooser fc ) {
|
public File[] showDialog( Window owner, SystemFileChooser fc ) {
|
||||||
IdentityHashMap<javax.swing.filechooser.FileFilter, FileFilter> filterMap = new IdentityHashMap<>();
|
|
||||||
|
|
||||||
JFileChooser chooser = new JFileChooser() {
|
JFileChooser chooser = new JFileChooser() {
|
||||||
@Override
|
@Override
|
||||||
public void approveSelection() {
|
public void approveSelection() {
|
||||||
@@ -1366,7 +1273,6 @@ public class SystemFileChooser
|
|||||||
// callback
|
// callback
|
||||||
ApproveCallback approveCallback = fc.getApproveCallback();
|
ApproveCallback approveCallback = fc.getApproveCallback();
|
||||||
if( approveCallback != null ) {
|
if( approveCallback != null ) {
|
||||||
updateFileFilter( fc, this, filterMap );
|
|
||||||
int result = approveCallback.approve( files, new SwingApproveContext( this ) );
|
int result = approveCallback.approve( files, new SwingApproveContext( this ) );
|
||||||
if( result == CANCEL_OPTION )
|
if( result == CANCEL_OPTION )
|
||||||
return;
|
return;
|
||||||
@@ -1407,7 +1313,6 @@ public class SystemFileChooser
|
|||||||
chooser.addChoosableFileFilter( jfilter );
|
chooser.addChoosableFileFilter( jfilter );
|
||||||
if( filter == currentFilter )
|
if( filter == currentFilter )
|
||||||
chooser.setFileFilter( jfilter );
|
chooser.setFileFilter( jfilter );
|
||||||
filterMap.put( jfilter, filter );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1435,7 +1340,6 @@ public class SystemFileChooser
|
|||||||
|
|
||||||
// show dialog
|
// show dialog
|
||||||
int result = chooser.showDialog( owner, null );
|
int result = chooser.showDialog( owner, null );
|
||||||
updateFileFilter( fc, chooser, filterMap );
|
|
||||||
|
|
||||||
// save window size
|
// save window size
|
||||||
Dimension windowSize = chooser.getSize();
|
Dimension windowSize = chooser.getSize();
|
||||||
@@ -1457,24 +1361,12 @@ public class SystemFileChooser
|
|||||||
return new javax.swing.filechooser.FileNameExtensionFilter(
|
return new javax.swing.filechooser.FileNameExtensionFilter(
|
||||||
((FileNameExtensionFilter)filter).getDescription(),
|
((FileNameExtensionFilter)filter).getDescription(),
|
||||||
((FileNameExtensionFilter)filter).getExtensions() );
|
((FileNameExtensionFilter)filter).getExtensions() );
|
||||||
} else if( filter instanceof PatternFilter ) {
|
|
||||||
return new SwingGlobFilter(
|
|
||||||
((PatternFilter)filter).getDescription(),
|
|
||||||
((PatternFilter)filter).getPatterns() );
|
|
||||||
} else if( filter instanceof AcceptAllFileFilter )
|
} else if( filter instanceof AcceptAllFileFilter )
|
||||||
return chooser.getAcceptAllFileFilter();
|
return chooser.getAcceptAllFileFilter();
|
||||||
else
|
else
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateFileFilter( SystemFileChooser fc, JFileChooser chooser,
|
|
||||||
IdentityHashMap<javax.swing.filechooser.FileFilter, FileFilter> filterMap )
|
|
||||||
{
|
|
||||||
FileFilter fileFilter = filterMap.get( chooser.getFileFilter() );
|
|
||||||
if( fileFilter != null )
|
|
||||||
fc.setFileFilter( fileFilter );
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean checkMustExist( JFileChooser chooser, File[] files ) {
|
private static boolean checkMustExist( JFileChooser chooser, File[] files ) {
|
||||||
for( File file : files ) {
|
for( File file : files ) {
|
||||||
if( !file.exists() ) {
|
if( !file.exists() ) {
|
||||||
@@ -1550,86 +1442,6 @@ public class SystemFileChooser
|
|||||||
null, buttons, buttons[Math.min( Math.max( defaultButton, 0 ), buttons.length - 1 )] );
|
null, buttons, buttons[Math.min( Math.max( defaultButton, 0 ), buttons.length - 1 )] );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//---- class SwingGlobFilter ------------------------------------------
|
|
||||||
|
|
||||||
private static class SwingGlobFilter
|
|
||||||
extends javax.swing.filechooser.FileFilter
|
|
||||||
{
|
|
||||||
private final String description;
|
|
||||||
private final String[] patterns;
|
|
||||||
private Pattern regexPattern;
|
|
||||||
|
|
||||||
SwingGlobFilter( String description, String... patterns ) {
|
|
||||||
this.description = description;
|
|
||||||
this.patterns = patterns;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getDescription() {
|
|
||||||
return description;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean accept( File f ) {
|
|
||||||
if( f == null )
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if( f.isDirectory() )
|
|
||||||
return true;
|
|
||||||
|
|
||||||
initRegexPattern();
|
|
||||||
return regexPattern.matcher( f.getName() ).matches();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initRegexPattern() {
|
|
||||||
if( regexPattern != null )
|
|
||||||
return;
|
|
||||||
|
|
||||||
StringBuilder buf = new StringBuilder();
|
|
||||||
for( String pattern : patterns ) {
|
|
||||||
if( buf.length() > 0 )
|
|
||||||
buf.append( '|' );
|
|
||||||
glob2regexPattern( pattern, buf );
|
|
||||||
}
|
|
||||||
regexPattern = Pattern.compile( buf.toString(), Pattern.CASE_INSENSITIVE );
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void glob2regexPattern( String globPattern, StringBuilder buf ) {
|
|
||||||
int globLength = globPattern.length();
|
|
||||||
|
|
||||||
// on windows, a pattern ending with "*.*" is equal to ending with "*"
|
|
||||||
if( SystemInfo.isWindows && globPattern.endsWith( "*.*" ) )
|
|
||||||
globLength -= 2;
|
|
||||||
|
|
||||||
for( int i = 0; i < globLength; i++ ) {
|
|
||||||
char ch = globPattern.charAt( i );
|
|
||||||
switch( ch ) {
|
|
||||||
// glob pattern
|
|
||||||
case '*': buf.append( ".*" ); break;
|
|
||||||
case '?': buf.append( '.' ); break;
|
|
||||||
|
|
||||||
// escape special regex characters
|
|
||||||
case '\\':
|
|
||||||
case '.':
|
|
||||||
case '+':
|
|
||||||
case '^':
|
|
||||||
case '$':
|
|
||||||
case '(':
|
|
||||||
case ')':
|
|
||||||
case '{':
|
|
||||||
case '}':
|
|
||||||
case '[':
|
|
||||||
case ']':
|
|
||||||
case '|':
|
|
||||||
buf.append( '\\' ).append( ch );
|
|
||||||
break;
|
|
||||||
|
|
||||||
default: buf.append( ch ); break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//---- class FileFilter ---------------------------------------------------
|
//---- class FileFilter ---------------------------------------------------
|
||||||
@@ -1681,67 +1493,6 @@ public class SystemFileChooser
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//---- class PatternFilter ------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A case-insensitive file filter which accepts file patterns containing
|
|
||||||
* the wildcard characters {@code *?} on Windows and Linux.
|
|
||||||
* <ul>
|
|
||||||
* <li>{@code '*'} matches any sequence of characters.
|
|
||||||
* <li>{@code '?'} matches any single character.
|
|
||||||
* </ul>
|
|
||||||
* Sample filters: {@code *.tar.gz} or {@code *_copy.txt}
|
|
||||||
* <p>
|
|
||||||
* <b>Warning</b>: This filter is <b>not supported on macOS</b>.
|
|
||||||
* If used on macOS, the Swing file chooser {@link JFileChooser} is shown
|
|
||||||
* (instead of macOS file dialog) and a warning is logged.
|
|
||||||
* To avoid this, do not use this filter on macOS.
|
|
||||||
* <p>
|
|
||||||
* E.g.:
|
|
||||||
* <pre>{@code
|
|
||||||
* if( SystemInfo.isMacOS )
|
|
||||||
* chooser.addChoosableFileFilter( new FileNameExtensionFilter( "Compressed TAR", "tgz" ) );
|
|
||||||
* else
|
|
||||||
* chooser.addChoosableFileFilter( new PatternFilter( "Compressed TAR", "*.tar.gz" ) );
|
|
||||||
* } );
|
|
||||||
* }</pre>
|
|
||||||
*
|
|
||||||
* @see FileNameExtensionFilter
|
|
||||||
* @since 3.7.1
|
|
||||||
*/
|
|
||||||
public static final class PatternFilter
|
|
||||||
extends FileFilter
|
|
||||||
{
|
|
||||||
private final String description;
|
|
||||||
private final String[] patterns;
|
|
||||||
|
|
||||||
public PatternFilter( String description, String... patterns ) {
|
|
||||||
if( patterns == null || patterns.length == 0 )
|
|
||||||
throw new IllegalArgumentException( "Missing patterns" );
|
|
||||||
for( String extension : patterns ) {
|
|
||||||
if( extension == null || extension.isEmpty() )
|
|
||||||
throw new IllegalArgumentException( "Pattern is null or empty string" );
|
|
||||||
}
|
|
||||||
|
|
||||||
this.description = description;
|
|
||||||
this.patterns = patterns.clone();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getDescription() {
|
|
||||||
return description;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String[] getPatterns() {
|
|
||||||
return patterns.clone();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return super.toString() + "[description=" + description + " patterns=" + Arrays.toString( patterns ) + "]";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//---- class AcceptAllFileFilter ------------------------------------------
|
//---- class AcceptAllFileFilter ------------------------------------------
|
||||||
|
|
||||||
private static final class AcceptAllFileFilter
|
private static final class AcceptAllFileFilter
|
||||||
|
|||||||
@@ -43,7 +43,8 @@ public class FlatDesktop
|
|||||||
public static boolean isSupported( Action action ) {
|
public static boolean isSupported( Action action ) {
|
||||||
if( SystemInfo.isJava_9_orLater ) {
|
if( SystemInfo.isJava_9_orLater ) {
|
||||||
try {
|
try {
|
||||||
return Desktop.getDesktop().isSupported( Enum.valueOf( Desktop.Action.class, action.name() ) );
|
return Desktop.isDesktopSupported() &&
|
||||||
|
Desktop.getDesktop().isSupported( Enum.valueOf( Desktop.Action.class, action.name() ) );
|
||||||
} catch( Exception ex ) {
|
} catch( Exception ex ) {
|
||||||
LoggingFacade.INSTANCE.logSevere( null, ex );
|
LoggingFacade.INSTANCE.logSevere( null, ex );
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -777,6 +777,9 @@ public class FlatUIDefaultsInspector
|
|||||||
|
|
||||||
@SuppressWarnings( "FormatString" ) // Error Prone
|
@SuppressWarnings( "FormatString" ) // Error Prone
|
||||||
private static String color2hex( Color color ) {
|
private static String color2hex( Color color ) {
|
||||||
|
if( color == null )
|
||||||
|
return "";
|
||||||
|
|
||||||
int rgb = color.getRGB();
|
int rgb = color.getRGB();
|
||||||
boolean hasAlpha = color.getAlpha() != 255;
|
boolean hasAlpha = color.getAlpha() != 255;
|
||||||
|
|
||||||
@@ -1018,28 +1021,36 @@ public class FlatUIDefaultsInspector
|
|||||||
item = (Item) value;
|
item = (Item) value;
|
||||||
init( table, item.key, isSelected, row );
|
init( table, item.key, isSelected, row );
|
||||||
|
|
||||||
// reset background, foreground and icon
|
// get color of value
|
||||||
if( !(item.value instanceof Color) ) {
|
valueColor = null;
|
||||||
|
if( item.value instanceof Color )
|
||||||
|
valueColor = (item.info instanceof Color[]) ? ((Color[])item.info)[0] : (Color) item.value;
|
||||||
|
else if( item.value instanceof FlatLineBorder )
|
||||||
|
valueColor = ((FlatLineBorder)item.value).getLineColor();
|
||||||
|
|
||||||
|
// reset background and foreground
|
||||||
|
if( valueColor == null ) {
|
||||||
setBackground( null );
|
setBackground( null );
|
||||||
setForeground( null );
|
setForeground( null );
|
||||||
}
|
}
|
||||||
if( !(item.value instanceof Icon) )
|
|
||||||
setIcon( null );
|
|
||||||
|
|
||||||
// value to string
|
// value to string
|
||||||
value = item.getValueAsString();
|
value = item.getValueAsString();
|
||||||
|
|
||||||
super.getTableCellRendererComponent( table, value, isSelected, hasFocus, row, column );
|
super.getTableCellRendererComponent( table, value, isSelected, hasFocus, row, column );
|
||||||
|
|
||||||
if( item.value instanceof Color ) {
|
// set foreground, if value has color
|
||||||
Color color = (item.info instanceof Color[]) ? ((Color[])item.info)[0] : (Color) item.value;
|
if( valueColor != null ) {
|
||||||
boolean isDark = new HSLColor( color ).getLuminance() < 70 && color.getAlpha() >= 128;
|
boolean isDark = new HSLColor( valueColor ).getLuminance() < 70 && valueColor.getAlpha() >= 128;
|
||||||
valueColor = color;
|
|
||||||
setForeground( isDark ? Color.white : Color.black );
|
setForeground( isDark ? Color.white : Color.black );
|
||||||
} else if( item.value instanceof Icon ) {
|
}
|
||||||
|
|
||||||
|
// set icon
|
||||||
|
if( item.value instanceof Icon ) {
|
||||||
Icon icon = (Icon) item.value;
|
Icon icon = (Icon) item.value;
|
||||||
setIcon( new SafeIcon( icon ) );
|
setIcon( new SafeIcon( icon ) );
|
||||||
}
|
} else
|
||||||
|
setIcon( null );
|
||||||
|
|
||||||
// set tooltip
|
// set tooltip
|
||||||
String toolTipText = (item.value instanceof Object[])
|
String toolTipText = (item.value instanceof Object[])
|
||||||
@@ -1056,7 +1067,7 @@ public class FlatUIDefaultsInspector
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void paintComponent( Graphics g ) {
|
protected void paintComponent( Graphics g ) {
|
||||||
if( item.value instanceof Color ) {
|
if( valueColor != null ) {
|
||||||
int width = getWidth();
|
int width = getWidth();
|
||||||
int height = getHeight();
|
int height = getHeight();
|
||||||
Color background = valueColor;
|
Color background = valueColor;
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
|
|
||||||
// increase this version if changing API or functionality of native library
|
// increase this version if changing API or functionality of native library
|
||||||
// also update version in Java class com.formdev.flatlaf.ui.FlatNativeLinuxLibrary
|
// also update version in Java class com.formdev.flatlaf.ui.FlatNativeLinuxLibrary
|
||||||
#define API_VERSION_LINUX 3004
|
#define API_VERSION_LINUX 3003
|
||||||
|
|
||||||
|
|
||||||
//---- JNI methods ------------------------------------------------------------
|
//---- JNI methods ------------------------------------------------------------
|
||||||
|
|||||||
@@ -33,9 +33,6 @@ extern Window getWindowHandle( JNIEnv* env, JAWT* awt, jobject window, Display**
|
|||||||
// declare internal methods
|
// declare internal methods
|
||||||
static jobjectArray fileListToStringArray( JNIEnv* env, GSList* fileList );
|
static jobjectArray fileListToStringArray( JNIEnv* env, GSList* fileList );
|
||||||
|
|
||||||
// fields
|
|
||||||
static int settingsSchemaInstalled = -1;
|
|
||||||
|
|
||||||
//---- helper -----------------------------------------------------------------
|
//---- helper -----------------------------------------------------------------
|
||||||
|
|
||||||
#define isOptionSet( option ) ((optionsSet & com_formdev_flatlaf_ui_FlatNativeLinuxLibrary_ ## option) != 0)
|
#define isOptionSet( option ) ((optionsSet & com_formdev_flatlaf_ui_FlatNativeLinuxLibrary_ ## option) != 0)
|
||||||
@@ -61,7 +58,6 @@ static void initFilters( GtkFileChooser* chooser, JNIEnv* env, jint fileTypeInde
|
|||||||
gtk_file_chooser_add_filter( chooser, filter );
|
gtk_file_chooser_add_filter( chooser, filter );
|
||||||
if( fileTypeIndex == filterIndex )
|
if( fileTypeIndex == filterIndex )
|
||||||
gtk_file_chooser_set_filter( chooser, filter );
|
gtk_file_chooser_set_filter( chooser, filter );
|
||||||
g_object_set_data( G_OBJECT( filter ), "flatlaf-filter-index", GINT_TO_POINTER( filterIndex + 1 ) );
|
|
||||||
filter = NULL;
|
filter = NULL;
|
||||||
filterIndex++;
|
filterIndex++;
|
||||||
}
|
}
|
||||||
@@ -134,42 +130,32 @@ struct ResponseData {
|
|||||||
JNIEnv* env;
|
JNIEnv* env;
|
||||||
jobject callback;
|
jobject callback;
|
||||||
GSList* fileList;
|
GSList* fileList;
|
||||||
int filterIndex;
|
|
||||||
|
|
||||||
ResponseData( JNIEnv* _env, jobject _callback ) {
|
ResponseData( JNIEnv* _env, jobject _callback ) {
|
||||||
env = _env;
|
env = _env;
|
||||||
callback = _callback;
|
callback = _callback;
|
||||||
fileList = NULL;
|
fileList = NULL;
|
||||||
filterIndex = -1;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static void handle_response( GtkWidget* dialog, gint responseId, gpointer data ) {
|
static void handle_response( GtkWidget* dialog, gint responseId, gpointer data ) {
|
||||||
GtkFileChooser* chooser = GTK_FILE_CHOOSER( dialog );
|
|
||||||
ResponseData *response = static_cast<ResponseData*>( data );
|
|
||||||
|
|
||||||
// get selected filter (even if user cancels dialog)
|
|
||||||
GtkFileFilter* filter = gtk_file_chooser_get_filter( chooser );
|
|
||||||
response->filterIndex = (filter != NULL)
|
|
||||||
? GPOINTER_TO_INT( g_object_get_data( G_OBJECT( filter ), "flatlaf-filter-index" ) ) - 1
|
|
||||||
: -1;
|
|
||||||
|
|
||||||
// get filenames if user pressed OK
|
// get filenames if user pressed OK
|
||||||
if( responseId == GTK_RESPONSE_ACCEPT ) {
|
if( responseId == GTK_RESPONSE_ACCEPT ) {
|
||||||
|
ResponseData *response = static_cast<ResponseData*>( data );
|
||||||
if( response->callback != NULL ) {
|
if( response->callback != NULL ) {
|
||||||
GSList* fileList = gtk_file_chooser_get_filenames( chooser );
|
GSList* fileList = gtk_file_chooser_get_filenames( GTK_FILE_CHOOSER( dialog ) );
|
||||||
jobjectArray files = fileListToStringArray( response->env, fileList );
|
jobjectArray files = fileListToStringArray( response->env, fileList );
|
||||||
jint filterIndex = response->filterIndex;
|
|
||||||
GtkWindow* window = GTK_WINDOW( dialog );
|
GtkWindow* window = GTK_WINDOW( dialog );
|
||||||
|
|
||||||
// invoke callback: boolean approve( String[] files, long hwnd );
|
// invoke callback: boolean approve( String[] files, long hwnd );
|
||||||
jclass cls = response->env->GetObjectClass( response->callback );
|
jclass cls = response->env->GetObjectClass( response->callback );
|
||||||
jmethodID approveID = response->env->GetMethodID( cls, "approve", "([Ljava/lang/String;IJ)Z" );
|
jmethodID approveID = response->env->GetMethodID( cls, "approve", "([Ljava/lang/String;J)Z" );
|
||||||
if( approveID != NULL && !response->env->CallBooleanMethod( response->callback, approveID, files, filterIndex, window ) )
|
if( approveID != NULL && !response->env->CallBooleanMethod( response->callback, approveID, files, window ) )
|
||||||
return; // keep dialog open
|
return; // keep dialog open
|
||||||
}
|
}
|
||||||
|
|
||||||
response->fileList = gtk_file_chooser_get_filenames( chooser );
|
response->fileList = gtk_file_chooser_get_filenames( GTK_FILE_CHOOSER( dialog ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
// hide/destroy file dialog and quit loop
|
// hide/destroy file dialog and quit loop
|
||||||
@@ -184,29 +170,12 @@ extern "C"
|
|||||||
JNIEXPORT jobjectArray JNICALL Java_com_formdev_flatlaf_ui_FlatNativeLinuxLibrary_showFileChooser
|
JNIEXPORT jobjectArray JNICALL Java_com_formdev_flatlaf_ui_FlatNativeLinuxLibrary_showFileChooser
|
||||||
( JNIEnv* env, jclass cls, jobject owner, jint dark, jboolean open,
|
( JNIEnv* env, jclass cls, jobject owner, jint dark, jboolean open,
|
||||||
jstring title, jstring okButtonLabel, jstring currentName, jstring currentFolder,
|
jstring title, jstring okButtonLabel, jstring currentName, jstring currentFolder,
|
||||||
jint optionsSet, jint optionsClear, jobject callback,
|
jint optionsSet, jint optionsClear, jobject callback, jint fileTypeIndex, jobjectArray fileTypes )
|
||||||
jint fileTypeIndex, jobjectArray fileTypes, jintArray retFileTypeIndex )
|
|
||||||
{
|
{
|
||||||
// initialize GTK
|
// initialize GTK
|
||||||
if( !gtk_init_check( NULL, NULL ) )
|
if( !gtk_init_check( NULL, NULL ) )
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
// check whether required GSettings schemas are installed (e.g. on NixOS)
|
|
||||||
// this avoids output of following message on console, followed by an application crash:
|
|
||||||
// GLib-GIO-ERROR: No GSettings schemas are installed on the system
|
|
||||||
if( settingsSchemaInstalled < 0 ) {
|
|
||||||
GSettingsSchemaSource* schemaSource = g_settings_schema_source_get_default();
|
|
||||||
GSettingsSchema* schema = (schemaSource != NULL)
|
|
||||||
? g_settings_schema_source_lookup( schemaSource, "org.gtk.Settings.FileChooser", FALSE )
|
|
||||||
: NULL;
|
|
||||||
if( schema != NULL )
|
|
||||||
g_settings_schema_unref( schema );
|
|
||||||
|
|
||||||
settingsSchemaInstalled = (schema != NULL);
|
|
||||||
}
|
|
||||||
if( settingsSchemaInstalled <= 0 )
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
// convert Java strings to C strings
|
// convert Java strings to C strings
|
||||||
AutoReleaseStringUTF8 ctitle( env, title );
|
AutoReleaseStringUTF8 ctitle( env, title );
|
||||||
AutoReleaseStringUTF8 cokButtonLabel( env, okButtonLabel );
|
AutoReleaseStringUTF8 cokButtonLabel( env, okButtonLabel );
|
||||||
@@ -313,11 +282,7 @@ JNIEXPORT jobjectArray JNICALL Java_com_formdev_flatlaf_ui_FlatNativeLinuxLibrar
|
|||||||
// start event loop (will be quit in respone handler)
|
// start event loop (will be quit in respone handler)
|
||||||
gtk_main();
|
gtk_main();
|
||||||
|
|
||||||
// return selected filter
|
// canceled?
|
||||||
jint selectedFilterIndex = responseData.filterIndex;
|
|
||||||
env->SetIntArrayRegion( retFileTypeIndex, 0, 1, &selectedFilterIndex );
|
|
||||||
|
|
||||||
// return empty array if canceled
|
|
||||||
if( responseData.fileList == NULL )
|
if( responseData.fileList == NULL )
|
||||||
return newJavaStringArray( env, 0 );
|
return newJavaStringArray( env, 0 );
|
||||||
|
|
||||||
|
|||||||
@@ -64,10 +64,10 @@ JNIEXPORT jboolean JNICALL Java_com_formdev_flatlaf_ui_FlatNativeLinuxLibrary_is
|
|||||||
/*
|
/*
|
||||||
* Class: com_formdev_flatlaf_ui_FlatNativeLinuxLibrary
|
* Class: com_formdev_flatlaf_ui_FlatNativeLinuxLibrary
|
||||||
* Method: showFileChooser
|
* Method: showFileChooser
|
||||||
* Signature: (Ljava/awt/Window;IZLjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;IILcom/formdev/flatlaf/ui/FlatNativeLinuxLibrary/FileChooserCallback;I[Ljava/lang/String;[I)[Ljava/lang/String;
|
* Signature: (Ljava/awt/Window;IZLjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;IILcom/formdev/flatlaf/ui/FlatNativeLinuxLibrary/FileChooserCallback;I[Ljava/lang/String;)[Ljava/lang/String;
|
||||||
*/
|
*/
|
||||||
JNIEXPORT jobjectArray JNICALL Java_com_formdev_flatlaf_ui_FlatNativeLinuxLibrary_showFileChooser
|
JNIEXPORT jobjectArray JNICALL Java_com_formdev_flatlaf_ui_FlatNativeLinuxLibrary_showFileChooser
|
||||||
(JNIEnv *, jclass, jobject, jint, jboolean, jstring, jstring, jstring, jstring, jint, jint, jobject, jint, jobjectArray, jintArray);
|
(JNIEnv *, jclass, jobject, jint, jboolean, jstring, jstring, jstring, jstring, jint, jint, jobject, jint, jobjectArray);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Class: com_formdev_flatlaf_ui_FlatNativeLinuxLibrary
|
* Class: com_formdev_flatlaf_ui_FlatNativeLinuxLibrary
|
||||||
|
|||||||
@@ -82,10 +82,10 @@ JNIEXPORT jboolean JNICALL Java_com_formdev_flatlaf_ui_FlatNativeMacLibrary_togg
|
|||||||
/*
|
/*
|
||||||
* Class: com_formdev_flatlaf_ui_FlatNativeMacLibrary
|
* Class: com_formdev_flatlaf_ui_FlatNativeMacLibrary
|
||||||
* Method: showFileChooser
|
* Method: showFileChooser
|
||||||
* Signature: (Ljava/awt/Window;IZLjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;IILcom/formdev/flatlaf/ui/FlatNativeMacLibrary/FileChooserCallback;I[Ljava/lang/String;[I)[Ljava/lang/String;
|
* Signature: (Ljava/awt/Window;IZLjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;IILcom/formdev/flatlaf/ui/FlatNativeMacLibrary/FileChooserCallback;I[Ljava/lang/String;)[Ljava/lang/String;
|
||||||
*/
|
*/
|
||||||
JNIEXPORT jobjectArray JNICALL Java_com_formdev_flatlaf_ui_FlatNativeMacLibrary_showFileChooser
|
JNIEXPORT jobjectArray JNICALL Java_com_formdev_flatlaf_ui_FlatNativeMacLibrary_showFileChooser
|
||||||
(JNIEnv *, jclass, jobject, jint, jboolean, jstring, jstring, jstring, jstring, jstring, jstring, jstring, jint, jint, jobject, jint, jobjectArray, jintArray);
|
(JNIEnv *, jclass, jobject, jint, jboolean, jstring, jstring, jstring, jstring, jstring, jstring, jstring, jint, jint, jobject, jint, jobjectArray);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Class: com_formdev_flatlaf_ui_FlatNativeMacLibrary
|
* Class: com_formdev_flatlaf_ui_FlatNativeMacLibrary
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
|
|
||||||
// increase this version if changing API or functionality of native library
|
// increase this version if changing API or functionality of native library
|
||||||
// also update version in Java class com.formdev.flatlaf.ui.FlatNativeMacLibrary
|
// also update version in Java class com.formdev.flatlaf.ui.FlatNativeMacLibrary
|
||||||
#define API_VERSION_MACOS 2003
|
#define API_VERSION_MACOS 2002
|
||||||
|
|
||||||
|
|
||||||
//---- JNI methods ------------------------------------------------------------
|
//---- JNI methods ------------------------------------------------------------
|
||||||
|
|||||||
@@ -35,7 +35,6 @@ static NSArray* getDialogURLs( NSSavePanel* dialog );
|
|||||||
|
|
||||||
@interface FileChooserDelegate : NSObject <NSOpenSavePanelDelegate, NSWindowDelegate> {
|
@interface FileChooserDelegate : NSObject <NSOpenSavePanelDelegate, NSWindowDelegate> {
|
||||||
NSArray* _filters;
|
NSArray* _filters;
|
||||||
int _selectedFormatIndex;
|
|
||||||
|
|
||||||
JavaVM* _jvm;
|
JavaVM* _jvm;
|
||||||
jobject _callback;
|
jobject _callback;
|
||||||
@@ -44,26 +43,18 @@ static NSArray* getDialogURLs( NSSavePanel* dialog );
|
|||||||
|
|
||||||
@property (nonatomic, assign) NSSavePanel* dialog;
|
@property (nonatomic, assign) NSSavePanel* dialog;
|
||||||
|
|
||||||
- (id) init;
|
|
||||||
- (void) initFilterAccessoryView: (NSMutableArray*)filters :(int)filterIndex
|
- (void) initFilterAccessoryView: (NSMutableArray*)filters :(int)filterIndex
|
||||||
:(NSString*)filterFieldLabel :(bool)showSingleFilterField;
|
:(NSString*)filterFieldLabel :(bool)showSingleFilterField;
|
||||||
- (void) selectFormat: (id)sender;
|
- (void) selectFormat: (id)sender;
|
||||||
- (void) selectFormatAtIndex: (int)index;
|
- (void) selectFormatAtIndex: (int)index;
|
||||||
- (int) selectedFormatIndex;
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation FileChooserDelegate
|
@implementation FileChooserDelegate
|
||||||
|
|
||||||
- (id) init {
|
|
||||||
_selectedFormatIndex = -1;
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void) initFilterAccessoryView: (NSMutableArray*)filters :(int)filterIndex
|
- (void) initFilterAccessoryView: (NSMutableArray*)filters :(int)filterIndex
|
||||||
:(NSString*)filterFieldLabel :(bool)showSingleFilterField
|
:(NSString*)filterFieldLabel :(bool)showSingleFilterField
|
||||||
{
|
{
|
||||||
_filters = filters;
|
_filters = filters;
|
||||||
_selectedFormatIndex = filterIndex;
|
|
||||||
|
|
||||||
// get filter names
|
// get filter names
|
||||||
NSArray* filterNames = filters.lastObject;
|
NSArray* filterNames = filters.lastObject;
|
||||||
@@ -134,12 +125,6 @@ static NSArray* getDialogURLs( NSSavePanel* dialog );
|
|||||||
// to support older macOS versions 10.14+ and because of some problems with allowedContentTypes:
|
// to support older macOS versions 10.14+ and because of some problems with allowedContentTypes:
|
||||||
// https://github.com/chromium/chromium/blob/d8e0032963b7ca4728ff4117933c0feb3e479b7a/components/remote_cocoa/app_shim/select_file_dialog_bridge.mm#L209-232
|
// https://github.com/chromium/chromium/blob/d8e0032963b7ca4728ff4117933c0feb3e479b7a/components/remote_cocoa/app_shim/select_file_dialog_bridge.mm#L209-232
|
||||||
_dialog.allowedFileTypes = [fileTypes containsObject:@"*"] ? nil : fileTypes;
|
_dialog.allowedFileTypes = [fileTypes containsObject:@"*"] ? nil : fileTypes;
|
||||||
|
|
||||||
_selectedFormatIndex = index;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (int) selectedFormatIndex {
|
|
||||||
return _selectedFormatIndex;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//---- NSOpenSavePanelDelegate ----
|
//---- NSOpenSavePanelDelegate ----
|
||||||
@@ -176,13 +161,12 @@ static NSArray* getDialogURLs( NSSavePanel* dialog );
|
|||||||
JNI_THREAD_ENTER( _jvm, true )
|
JNI_THREAD_ENTER( _jvm, true )
|
||||||
|
|
||||||
jobjectArray files = urlsToStringArray( env, urls );
|
jobjectArray files = urlsToStringArray( env, urls );
|
||||||
jint selectedFormatIndex = ((FileChooserDelegate*)((NSSavePanel*)sender).delegate).selectedFormatIndex;
|
|
||||||
jlong window = (jlong) sender;
|
jlong window = (jlong) sender;
|
||||||
|
|
||||||
// invoke callback: boolean approve( String[] files, long hwnd );
|
// invoke callback: boolean approve( String[] files, long hwnd );
|
||||||
jclass cls = env->GetObjectClass( _callback );
|
jclass cls = env->GetObjectClass( _callback );
|
||||||
jmethodID approveID = env->GetMethodID( cls, "approve", "([Ljava/lang/String;IJ)Z" );
|
jmethodID approveID = env->GetMethodID( cls, "approve", "([Ljava/lang/String;J)Z" );
|
||||||
if( approveID != NULL && !env->CallBooleanMethod( _callback, approveID, files, selectedFormatIndex, window ) ) {
|
if( approveID != NULL && !env->CallBooleanMethod( _callback, approveID, files, window ) ) {
|
||||||
_urlsSet = NULL;
|
_urlsSet = NULL;
|
||||||
return false; // keep dialog open
|
return false; // keep dialog open
|
||||||
}
|
}
|
||||||
@@ -281,8 +265,7 @@ JNIEXPORT jobjectArray JNICALL Java_com_formdev_flatlaf_ui_FlatNativeMacLibrary_
|
|||||||
( JNIEnv* env, jclass cls, jobject owner, jint dark, jboolean open,
|
( JNIEnv* env, jclass cls, jobject owner, jint dark, jboolean open,
|
||||||
jstring title, jstring prompt, jstring message, jstring filterFieldLabel,
|
jstring title, jstring prompt, jstring message, jstring filterFieldLabel,
|
||||||
jstring nameFieldLabel, jstring nameFieldStringValue, jstring directoryURL,
|
jstring nameFieldLabel, jstring nameFieldStringValue, jstring directoryURL,
|
||||||
jint optionsSet, jint optionsClear, jobject callback,
|
jint optionsSet, jint optionsClear, jobject callback, jint fileTypeIndex, jobjectArray fileTypes )
|
||||||
jint fileTypeIndex, jobjectArray fileTypes, jintArray retFileTypeIndex )
|
|
||||||
{
|
{
|
||||||
JNI_COCOA_ENTER()
|
JNI_COCOA_ENTER()
|
||||||
|
|
||||||
@@ -382,26 +365,17 @@ JNIEXPORT jobjectArray JNICALL Java_com_formdev_flatlaf_ui_FlatNativeMacLibrary_
|
|||||||
|
|
||||||
// show dialog
|
// show dialog
|
||||||
NSModalResponse response = [dialog runModal];
|
NSModalResponse response = [dialog runModal];
|
||||||
|
|
||||||
// return selected filter
|
|
||||||
jint selectedFormatIndex = delegate.selectedFormatIndex;
|
|
||||||
env->SetIntArrayRegion( retFileTypeIndex, 0, 1, &selectedFormatIndex );
|
|
||||||
|
|
||||||
[delegate release];
|
[delegate release];
|
||||||
|
|
||||||
// return empty array if canceled
|
|
||||||
if( response != NSModalResponseOK ) {
|
if( response != NSModalResponseOK ) {
|
||||||
*purls = @[];
|
*purls = @[];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// get selected file(s)
|
|
||||||
*purls = getDialogURLs( dialog );
|
*purls = getDialogURLs( dialog );
|
||||||
|
|
||||||
JNI_COCOA_CATCH()
|
JNI_COCOA_CATCH()
|
||||||
}];
|
}];
|
||||||
|
|
||||||
// return null on failures
|
|
||||||
if( urls == NULL )
|
if( urls == NULL )
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
|
|
||||||
// increase this version if changing API or functionality of native library
|
// increase this version if changing API or functionality of native library
|
||||||
// also update version in Java class com.formdev.flatlaf.ui.FlatNativeWindowsLibrary
|
// also update version in Java class com.formdev.flatlaf.ui.FlatNativeWindowsLibrary
|
||||||
#define API_VERSION_WINDOWS 1003
|
#define API_VERSION_WINDOWS 1002
|
||||||
|
|
||||||
|
|
||||||
//---- JNI methods ------------------------------------------------------------
|
//---- JNI methods ------------------------------------------------------------
|
||||||
|
|||||||
@@ -128,11 +128,6 @@ public:
|
|||||||
} else
|
} else
|
||||||
files = getFiles( env, false, dialog );
|
files = getFiles( env, false, dialog );
|
||||||
|
|
||||||
// get selected filter
|
|
||||||
UINT selectedFileTypeIndex = 0;
|
|
||||||
dialog->GetFileTypeIndex( &selectedFileTypeIndex );
|
|
||||||
jint jselectedFileTypeIndex = selectedFileTypeIndex - 1;
|
|
||||||
|
|
||||||
// get hwnd of file dialog
|
// get hwnd of file dialog
|
||||||
HWND hwndFileDialog = 0;
|
HWND hwndFileDialog = 0;
|
||||||
AutoReleasePtr<IOleWindow> window;
|
AutoReleasePtr<IOleWindow> window;
|
||||||
@@ -141,10 +136,10 @@ public:
|
|||||||
|
|
||||||
// invoke callback: boolean approve( String[] files, long hwnd );
|
// invoke callback: boolean approve( String[] files, long hwnd );
|
||||||
jclass cls = env->GetObjectClass( callback );
|
jclass cls = env->GetObjectClass( callback );
|
||||||
jmethodID approveID = env->GetMethodID( cls, "approve", "([Ljava/lang/String;IJ)Z" );
|
jmethodID approveID = env->GetMethodID( cls, "approve", "([Ljava/lang/String;J)Z" );
|
||||||
if( approveID == NULL )
|
if( approveID == NULL )
|
||||||
return S_OK;
|
return S_OK;
|
||||||
return env->CallBooleanMethod( callback, approveID, files, jselectedFileTypeIndex, hwndFileDialog ) ? S_OK : S_FALSE;
|
return env->CallBooleanMethod( callback, approveID, files, hwndFileDialog ) ? S_OK : S_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
IFACEMETHODIMP OnFolderChange( IFileDialog* ) { return S_OK; }
|
IFACEMETHODIMP OnFolderChange( IFileDialog* ) { return S_OK; }
|
||||||
@@ -152,7 +147,7 @@ public:
|
|||||||
IFACEMETHODIMP OnHelp( IFileDialog* ) { return S_OK; }
|
IFACEMETHODIMP OnHelp( IFileDialog* ) { return S_OK; }
|
||||||
IFACEMETHODIMP OnSelectionChange( IFileDialog* ) { return S_OK; }
|
IFACEMETHODIMP OnSelectionChange( IFileDialog* ) { return S_OK; }
|
||||||
IFACEMETHODIMP OnShareViolation( IFileDialog*, IShellItem*, FDE_SHAREVIOLATION_RESPONSE* ) { return S_OK; }
|
IFACEMETHODIMP OnShareViolation( IFileDialog*, IShellItem*, FDE_SHAREVIOLATION_RESPONSE* ) { return S_OK; }
|
||||||
IFACEMETHODIMP OnTypeChange( IFileDialog* ) { return S_OK; }
|
IFACEMETHODIMP OnTypeChange( IFileDialog*pfd ) { return S_OK; }
|
||||||
IFACEMETHODIMP OnOverwrite( IFileDialog*, IShellItem*, FDE_OVERWRITE_RESPONSE* ) { return S_OK; }
|
IFACEMETHODIMP OnOverwrite( IFileDialog*, IShellItem*, FDE_OVERWRITE_RESPONSE* ) { return S_OK; }
|
||||||
|
|
||||||
//---- IUnknown methods ----
|
//---- IUnknown methods ----
|
||||||
@@ -218,8 +213,7 @@ JNIEXPORT jobjectArray JNICALL Java_com_formdev_flatlaf_ui_FlatNativeWindowsLibr
|
|||||||
( JNIEnv* env, jclass cls, jobject owner, jboolean open,
|
( JNIEnv* env, jclass cls, jobject owner, jboolean open,
|
||||||
jstring title, jstring okButtonLabel, jstring fileNameLabel, jstring fileName,
|
jstring title, jstring okButtonLabel, jstring fileNameLabel, jstring fileName,
|
||||||
jstring folder, jstring saveAsItem, jstring defaultFolder, jstring defaultExtension,
|
jstring folder, jstring saveAsItem, jstring defaultFolder, jstring defaultExtension,
|
||||||
jint optionsSet, jint optionsClear, jobject callback,
|
jint optionsSet, jint optionsClear, jobject callback, jint fileTypeIndex, jobjectArray fileTypes )
|
||||||
jint fileTypeIndex, jobjectArray fileTypes, jintArray retFileTypeIndex )
|
|
||||||
{
|
{
|
||||||
// initialize COM library
|
// initialize COM library
|
||||||
CoInitializer coInitializer;
|
CoInitializer coInitializer;
|
||||||
@@ -291,14 +285,6 @@ JNIEXPORT jobjectArray JNICALL Java_com_formdev_flatlaf_ui_FlatNativeWindowsLibr
|
|||||||
HWND hwndOwner = (owner != NULL) ? getWindowHandle( env, owner ) : NULL;
|
HWND hwndOwner = (owner != NULL) ? getWindowHandle( env, owner ) : NULL;
|
||||||
HRESULT hr = dialog->Show( hwndOwner );
|
HRESULT hr = dialog->Show( hwndOwner );
|
||||||
dialog->Unadvise( dwCookie );
|
dialog->Unadvise( dwCookie );
|
||||||
|
|
||||||
// return selected filter
|
|
||||||
UINT selectedFileTypeIndex = 0;
|
|
||||||
CHECK_HRESULT( dialog->GetFileTypeIndex( &selectedFileTypeIndex ) );
|
|
||||||
jint jselectedFileTypeIndex = selectedFileTypeIndex - 1;
|
|
||||||
env->SetIntArrayRegion( retFileTypeIndex, 0, 1, &jselectedFileTypeIndex );
|
|
||||||
|
|
||||||
// return empty array if canceled
|
|
||||||
if( hr == HRESULT_FROM_WIN32(ERROR_CANCELLED) )
|
if( hr == HRESULT_FROM_WIN32(ERROR_CANCELLED) )
|
||||||
return newJavaStringArray( env, 0 );
|
return newJavaStringArray( env, 0 );
|
||||||
CHECK_HRESULT( hr );
|
CHECK_HRESULT( hr );
|
||||||
|
|||||||
@@ -116,10 +116,10 @@ JNIEXPORT jboolean JNICALL Java_com_formdev_flatlaf_ui_FlatNativeWindowsLibrary_
|
|||||||
/*
|
/*
|
||||||
* Class: com_formdev_flatlaf_ui_FlatNativeWindowsLibrary
|
* Class: com_formdev_flatlaf_ui_FlatNativeWindowsLibrary
|
||||||
* Method: showFileChooser
|
* Method: showFileChooser
|
||||||
* Signature: (Ljava/awt/Window;ZLjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;IILcom/formdev/flatlaf/ui/FlatNativeWindowsLibrary/FileChooserCallback;I[Ljava/lang/String;[I)[Ljava/lang/String;
|
* Signature: (Ljava/awt/Window;ZLjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;IILcom/formdev/flatlaf/ui/FlatNativeWindowsLibrary/FileChooserCallback;I[Ljava/lang/String;)[Ljava/lang/String;
|
||||||
*/
|
*/
|
||||||
JNIEXPORT jobjectArray JNICALL Java_com_formdev_flatlaf_ui_FlatNativeWindowsLibrary_showFileChooser
|
JNIEXPORT jobjectArray JNICALL Java_com_formdev_flatlaf_ui_FlatNativeWindowsLibrary_showFileChooser
|
||||||
(JNIEnv *, jclass, jobject, jboolean, jstring, jstring, jstring, jstring, jstring, jstring, jstring, jstring, jint, jint, jobject, jint, jobjectArray, jintArray);
|
(JNIEnv *, jclass, jobject, jboolean, jstring, jstring, jstring, jstring, jstring, jstring, jstring, jstring, jint, jint, jobject, jint, jobjectArray);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Class: com_formdev_flatlaf_ui_FlatNativeWindowsLibrary
|
* Class: com_formdev_flatlaf_ui_FlatNativeWindowsLibrary
|
||||||
|
|||||||
@@ -110,8 +110,8 @@ public class FlatSystemFileChooserLinuxTest
|
|||||||
}
|
}
|
||||||
int fileTypeIndex = fileTypeIndexSlider.getValue();
|
int fileTypeIndex = fileTypeIndexSlider.getValue();
|
||||||
|
|
||||||
FlatNativeLinuxLibrary.FileChooserCallback callback = (files, fileTypeIndex2, hwndFileDialog) -> {
|
FlatNativeLinuxLibrary.FileChooserCallback callback = (files, hwndFileDialog) -> {
|
||||||
System.out.println( " -- callback " + hwndFileDialog + " " + Arrays.toString( files ) + " " + fileTypeIndex2 );
|
System.out.println( " -- callback " + hwndFileDialog + " " + Arrays.toString( files ) );
|
||||||
if( showMessageDialogOnOKCheckBox.isSelected() ) {
|
if( showMessageDialogOnOKCheckBox.isSelected() ) {
|
||||||
System.out.println( FlatNativeLinuxLibrary.showMessageDialog( hwndFileDialog,
|
System.out.println( FlatNativeLinuxLibrary.showMessageDialog( hwndFileDialog,
|
||||||
JOptionPane.INFORMATION_MESSAGE,
|
JOptionPane.INFORMATION_MESSAGE,
|
||||||
@@ -124,28 +124,24 @@ public class FlatSystemFileChooserLinuxTest
|
|||||||
|
|
||||||
int dark = FlatLaf.isLafDark() ? 1 : 0;
|
int dark = FlatLaf.isLafDark() ? 1 : 0;
|
||||||
if( direct ) {
|
if( direct ) {
|
||||||
int[] retFileTypeIndex = { -1 };
|
|
||||||
String[] files = FlatNativeLinuxLibrary.showFileChooser( owner, dark, open,
|
String[] files = FlatNativeLinuxLibrary.showFileChooser( owner, dark, open,
|
||||||
title, okButtonLabel, currentName, currentFolder,
|
title, okButtonLabel, currentName, currentFolder,
|
||||||
optionsSet.get(), optionsClear.get(), callback,
|
optionsSet.get(), optionsClear.get(), callback, fileTypeIndex, fileTypes );
|
||||||
fileTypeIndex, fileTypes, retFileTypeIndex );
|
|
||||||
|
|
||||||
outputResult( files, retFileTypeIndex[0] );
|
filesField.setText( (files != null) ? Arrays.toString( files ).replace( ',', '\n' ) : "null" );
|
||||||
} else {
|
} else {
|
||||||
SecondaryLoop secondaryLoop = Toolkit.getDefaultToolkit().getSystemEventQueue().createSecondaryLoop();
|
SecondaryLoop secondaryLoop = Toolkit.getDefaultToolkit().getSystemEventQueue().createSecondaryLoop();
|
||||||
|
|
||||||
String[] fileTypes2 = fileTypes;
|
String[] fileTypes2 = fileTypes;
|
||||||
new Thread( () -> {
|
new Thread( () -> {
|
||||||
int[] retFileTypeIndex = { -1 };
|
|
||||||
String[] files = FlatNativeLinuxLibrary.showFileChooser( owner, dark, open,
|
String[] files = FlatNativeLinuxLibrary.showFileChooser( owner, dark, open,
|
||||||
title, okButtonLabel, currentName, currentFolder,
|
title, okButtonLabel, currentName, currentFolder,
|
||||||
optionsSet.get(), optionsClear.get(), callback,
|
optionsSet.get(), optionsClear.get(), callback, fileTypeIndex, fileTypes2 );
|
||||||
fileTypeIndex, fileTypes2, retFileTypeIndex );
|
|
||||||
|
|
||||||
System.out.println( " secondaryLoop.exit() returned " + secondaryLoop.exit() );
|
System.out.println( " secondaryLoop.exit() returned " + secondaryLoop.exit() );
|
||||||
|
|
||||||
EventQueue.invokeLater( () -> {
|
EventQueue.invokeLater( () -> {
|
||||||
outputResult( files, retFileTypeIndex[0] );
|
filesField.setText( (files != null) ? Arrays.toString( files ).replace( ',', '\n' ) : "null" );
|
||||||
} );
|
} );
|
||||||
} ).start();
|
} ).start();
|
||||||
|
|
||||||
@@ -154,11 +150,6 @@ public class FlatSystemFileChooserLinuxTest
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void outputResult( String[] files, int retFileTypeIndex ) {
|
|
||||||
filesField.setText( (files != null) ? Arrays.toString( files ).replace( ',', '\n' ) : "null" );
|
|
||||||
filesField.append( "\n\nretFileTypeIndex " + retFileTypeIndex );
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String n( String s ) {
|
private static String n( String s ) {
|
||||||
return s != null && !s.isEmpty() ? s : null;
|
return s != null && !s.isEmpty() ? s : null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -145,8 +145,8 @@ public class FlatSystemFileChooserMacTest
|
|||||||
}
|
}
|
||||||
int fileTypeIndex = fileTypeIndexSlider.getValue();
|
int fileTypeIndex = fileTypeIndexSlider.getValue();
|
||||||
|
|
||||||
FlatNativeMacLibrary.FileChooserCallback callback = (files, fileTypeIndex2, hwndFileDialog) -> {
|
FlatNativeMacLibrary.FileChooserCallback callback = (files, hwndFileDialog) -> {
|
||||||
System.out.println( " -- callback " + hwndFileDialog + " " + Arrays.toString( files ) + " " + fileTypeIndex2 );
|
System.out.println( " -- callback " + hwndFileDialog + " " + Arrays.toString( files ) );
|
||||||
if( showMessageDialogOnOKCheckBox.isSelected() ) {
|
if( showMessageDialogOnOKCheckBox.isSelected() ) {
|
||||||
int result = FlatNativeMacLibrary.showMessageDialog( hwndFileDialog,
|
int result = FlatNativeMacLibrary.showMessageDialog( hwndFileDialog,
|
||||||
JOptionPane.INFORMATION_MESSAGE,
|
JOptionPane.INFORMATION_MESSAGE,
|
||||||
@@ -160,30 +160,26 @@ public class FlatSystemFileChooserMacTest
|
|||||||
|
|
||||||
int dark = FlatLaf.isLafDark() ? 1 : 0;
|
int dark = FlatLaf.isLafDark() ? 1 : 0;
|
||||||
if( direct ) {
|
if( direct ) {
|
||||||
int[] retFileTypeIndex = { -1 };
|
|
||||||
String[] files = FlatNativeMacLibrary.showFileChooser( owner, dark, open,
|
String[] files = FlatNativeMacLibrary.showFileChooser( owner, dark, open,
|
||||||
title, prompt, message, filterFieldLabel,
|
title, prompt, message, filterFieldLabel,
|
||||||
nameFieldLabel, nameFieldStringValue, directoryURL,
|
nameFieldLabel, nameFieldStringValue, directoryURL,
|
||||||
optionsSet.get(), optionsClear.get(), callback,
|
optionsSet.get(), optionsClear.get(), callback, fileTypeIndex, fileTypes );
|
||||||
fileTypeIndex, fileTypes, retFileTypeIndex );
|
|
||||||
|
|
||||||
outputResult( files, retFileTypeIndex[0] );
|
filesField.setText( (files != null) ? Arrays.toString( files ).replace( ',', '\n' ) : "null" );
|
||||||
} else {
|
} else {
|
||||||
SecondaryLoop secondaryLoop = Toolkit.getDefaultToolkit().getSystemEventQueue().createSecondaryLoop();
|
SecondaryLoop secondaryLoop = Toolkit.getDefaultToolkit().getSystemEventQueue().createSecondaryLoop();
|
||||||
|
|
||||||
String[] fileTypes2 = fileTypes;
|
String[] fileTypes2 = fileTypes;
|
||||||
new Thread( () -> {
|
new Thread( () -> {
|
||||||
int[] retFileTypeIndex = { -1 };
|
|
||||||
String[] files = FlatNativeMacLibrary.showFileChooser( owner, dark, open,
|
String[] files = FlatNativeMacLibrary.showFileChooser( owner, dark, open,
|
||||||
title, prompt, message, filterFieldLabel,
|
title, prompt, message, filterFieldLabel,
|
||||||
nameFieldLabel, nameFieldStringValue, directoryURL,
|
nameFieldLabel, nameFieldStringValue, directoryURL,
|
||||||
optionsSet.get(), optionsClear.get(), callback,
|
optionsSet.get(), optionsClear.get(), callback, fileTypeIndex, fileTypes2 );
|
||||||
fileTypeIndex, fileTypes2, retFileTypeIndex );
|
|
||||||
|
|
||||||
System.out.println( " secondaryLoop.exit() returned " + secondaryLoop.exit() );
|
System.out.println( " secondaryLoop.exit() returned " + secondaryLoop.exit() );
|
||||||
|
|
||||||
SwingUtilities.invokeLater( () -> {
|
SwingUtilities.invokeLater( () -> {
|
||||||
outputResult( files, retFileTypeIndex[0] );
|
filesField.setText( (files != null) ? Arrays.toString( files ).replace( ',', '\n' ) : "null" );
|
||||||
} );
|
} );
|
||||||
} ).start();
|
} ).start();
|
||||||
|
|
||||||
@@ -192,11 +188,6 @@ public class FlatSystemFileChooserMacTest
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void outputResult( String[] files, int retFileTypeIndex ) {
|
|
||||||
filesField.setText( (files != null) ? Arrays.toString( files ).replace( ',', '\n' ) : "null" );
|
|
||||||
filesField.append( "\n\nretFileTypeIndex " + retFileTypeIndex );
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String n( String s ) {
|
private static String n( String s ) {
|
||||||
return s != null && !s.isEmpty() ? s : null;
|
return s != null && !s.isEmpty() ? s : null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -234,9 +234,7 @@ public class FlatSystemFileChooserTest
|
|||||||
for( int i = 0; i < fileTypes.length; i += 2 ) {
|
for( int i = 0; i < fileTypes.length; i += 2 ) {
|
||||||
fc.addChoosableFileFilter( "*".equals( fileTypes[i+1] )
|
fc.addChoosableFileFilter( "*".equals( fileTypes[i+1] )
|
||||||
? fc.getAcceptAllFileFilter()
|
? fc.getAcceptAllFileFilter()
|
||||||
: ((fileTypes[i+1].indexOf( '*' ) >= 0 || fileTypes[i+1].indexOf( '?' ) >= 0)
|
: new SystemFileChooser.FileNameExtensionFilter( fileTypes[i], fileTypes[i+1].split( ";" ) ) );
|
||||||
? new SystemFileChooser.PatternFilter( fileTypes[i], fileTypes[i+1].split( ";" ) )
|
|
||||||
: new SystemFileChooser.FileNameExtensionFilter( fileTypes[i], fileTypes[i+1].split( ";" ) )) );
|
|
||||||
}
|
}
|
||||||
SystemFileChooser.FileFilter[] filters = fc.getChoosableFileFilters();
|
SystemFileChooser.FileFilter[] filters = fc.getChoosableFileFilters();
|
||||||
if( filters.length > 0 )
|
if( filters.length > 0 )
|
||||||
@@ -312,8 +310,7 @@ public class FlatSystemFileChooserTest
|
|||||||
"result", result,
|
"result", result,
|
||||||
"currentDirectory", fc.getCurrentDirectory(),
|
"currentDirectory", fc.getCurrentDirectory(),
|
||||||
"selectedFile", fc.getSelectedFile(),
|
"selectedFile", fc.getSelectedFile(),
|
||||||
"selectedFiles", fc.getSelectedFiles(),
|
"selectedFiles", fc.getSelectedFiles() );
|
||||||
"fileFilter", fc.getFileFilter() );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void outputSwingFileChooser( String type, JFileChooser fc, int result ) {
|
private void outputSwingFileChooser( String type, JFileChooser fc, int result ) {
|
||||||
@@ -322,8 +319,7 @@ public class FlatSystemFileChooserTest
|
|||||||
"result", result,
|
"result", result,
|
||||||
"currentDirectory", fc.getCurrentDirectory(),
|
"currentDirectory", fc.getCurrentDirectory(),
|
||||||
"selectedFile", fc.getSelectedFile(),
|
"selectedFile", fc.getSelectedFile(),
|
||||||
"selectedFiles", fc.getSelectedFiles(),
|
"selectedFiles", fc.getSelectedFiles() );
|
||||||
"fileFilter", fc.getFileFilter() );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void outputAWTFileChooser( FileDialog fc ) {
|
private void outputAWTFileChooser( FileDialog fc ) {
|
||||||
|
|||||||
@@ -131,8 +131,8 @@ public class FlatSystemFileChooserWindowsTest
|
|||||||
fileTypes = fileTypesStr.trim().split( "[,]+" );
|
fileTypes = fileTypesStr.trim().split( "[,]+" );
|
||||||
int fileTypeIndex = fileTypeIndexSlider.getValue();
|
int fileTypeIndex = fileTypeIndexSlider.getValue();
|
||||||
|
|
||||||
FlatNativeWindowsLibrary.FileChooserCallback callback = (files, fileTypeIndex2, hwndFileDialog) -> {
|
FlatNativeWindowsLibrary.FileChooserCallback callback = (files, hwndFileDialog) -> {
|
||||||
System.out.println( " -- callback " + hwndFileDialog + " " + Arrays.toString( files ) + " " + fileTypeIndex2 );
|
System.out.println( " -- callback " + hwndFileDialog + " " + Arrays.toString( files ) );
|
||||||
if( showMessageDialogOnOKCheckBox.isSelected() ) {
|
if( showMessageDialogOnOKCheckBox.isSelected() ) {
|
||||||
System.out.println( FlatNativeWindowsLibrary.showMessageDialog( hwndFileDialog,
|
System.out.println( FlatNativeWindowsLibrary.showMessageDialog( hwndFileDialog,
|
||||||
JOptionPane.INFORMATION_MESSAGE,
|
JOptionPane.INFORMATION_MESSAGE,
|
||||||
@@ -142,30 +142,26 @@ public class FlatSystemFileChooserWindowsTest
|
|||||||
};
|
};
|
||||||
|
|
||||||
if( direct ) {
|
if( direct ) {
|
||||||
int[] retFileTypeIndex = { -1 };
|
|
||||||
String[] files = FlatNativeWindowsLibrary.showFileChooser( owner, open,
|
String[] files = FlatNativeWindowsLibrary.showFileChooser( owner, open,
|
||||||
title, okButtonLabel, fileNameLabel, fileName,
|
title, okButtonLabel, fileNameLabel, fileName,
|
||||||
folder, saveAsItem, defaultFolder, defaultExtension,
|
folder, saveAsItem, defaultFolder, defaultExtension,
|
||||||
optionsSet.get(), optionsClear.get(), callback,
|
optionsSet.get(), optionsClear.get(), callback, fileTypeIndex, fileTypes );
|
||||||
fileTypeIndex, fileTypes, retFileTypeIndex );
|
|
||||||
|
|
||||||
outputResult( files, retFileTypeIndex[0] );
|
filesField.setText( (files != null) ? Arrays.toString( files ).replace( ',', '\n' ) : "null" );
|
||||||
} else {
|
} else {
|
||||||
SecondaryLoop secondaryLoop = Toolkit.getDefaultToolkit().getSystemEventQueue().createSecondaryLoop();
|
SecondaryLoop secondaryLoop = Toolkit.getDefaultToolkit().getSystemEventQueue().createSecondaryLoop();
|
||||||
|
|
||||||
String[] fileTypes2 = fileTypes;
|
String[] fileTypes2 = fileTypes;
|
||||||
new Thread( () -> {
|
new Thread( () -> {
|
||||||
int[] retFileTypeIndex = { -1 };
|
|
||||||
String[] files = FlatNativeWindowsLibrary.showFileChooser( owner, open,
|
String[] files = FlatNativeWindowsLibrary.showFileChooser( owner, open,
|
||||||
title, okButtonLabel, fileNameLabel, fileName,
|
title, okButtonLabel, fileNameLabel, fileName,
|
||||||
folder, saveAsItem, defaultFolder, defaultExtension,
|
folder, saveAsItem, defaultFolder, defaultExtension,
|
||||||
optionsSet.get(), optionsClear.get(), callback,
|
optionsSet.get(), optionsClear.get(), callback, fileTypeIndex, fileTypes2 );
|
||||||
fileTypeIndex, fileTypes2, retFileTypeIndex );
|
|
||||||
|
|
||||||
System.out.println( " secondaryLoop.exit() returned " + secondaryLoop.exit() );
|
System.out.println( " secondaryLoop.exit() returned " + secondaryLoop.exit() );
|
||||||
|
|
||||||
EventQueue.invokeLater( () -> {
|
EventQueue.invokeLater( () -> {
|
||||||
outputResult( files, retFileTypeIndex[0] );
|
filesField.setText( (files != null) ? Arrays.toString( files ).replace( ',', '\n' ) : "null" );
|
||||||
} );
|
} );
|
||||||
} ).start();
|
} ).start();
|
||||||
|
|
||||||
@@ -174,11 +170,6 @@ public class FlatSystemFileChooserWindowsTest
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void outputResult( String[] files, int retFileTypeIndex ) {
|
|
||||||
filesField.setText( (files != null) ? Arrays.toString( files ).replace( ',', '\n' ) : "null" );
|
|
||||||
filesField.append( "\n\nretFileTypeIndex " + retFileTypeIndex );
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String n( String s ) {
|
private static String n( String s ) {
|
||||||
return s != null && !s.isEmpty() ? s : null;
|
return s != null && !s.isEmpty() ? s : null;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user