Skip to content

Commit 061ed6c

Browse files
committed
Use Path to represent file-system paths for ImageData creation
Use java.nio.file.Path to model file-system paths instead of String to represent file-system paths. Add the new way to create ImageData as static factory instead of a constructor, because a constructor is not really suitable to create a copy of the first element of an array of ImageData. Also inline the ImageDataLoader and use the new ImageData.load() factories instead.
1 parent 9f60279 commit 061ed6c

File tree

11 files changed

+561
-166
lines changed

11 files changed

+561
-166
lines changed

bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/Image.java

+66-28
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2000, 2020 IBM Corporation and others.
2+
* Copyright (c) 2000, 2025 IBM Corporation and others.
33
*
44
* This program and the accompanying materials
55
* are made available under the terms of the Eclipse Public License 2.0
@@ -15,6 +15,7 @@
1515

1616

1717
import java.io.*;
18+
import java.nio.file.Path;
1819
import java.util.*;
1920

2021
import org.eclipse.swt.*;
@@ -127,9 +128,9 @@ public final class Image extends Resource implements Drawable {
127128
static final int DEFAULT_SCANLINE_PAD = 4;
128129

129130
/**
130-
* ImageFileNameProvider to provide file names at various Zoom levels
131+
* ImageFileProvider to provide files at various Zoom levels
131132
*/
132-
private ImageFileNameProvider imageFileNameProvider;
133+
private ImageFileProvider imageFileProvider;
133134

134135
/**
135136
* ImageDataProvider to provide ImageData at various Zoom levels
@@ -388,11 +389,11 @@ public Image(Device device, Image srcImage, int flag) {
388389
/* Create the 100% representation for the new image from source image & apply flag */
389390
createRepFromSourceAndApplyFlag(srcImage.getRepresentation (100), srcWidth, srcHeight, flag);
390391

391-
imageFileNameProvider = srcImage.imageFileNameProvider;
392+
imageFileProvider = srcImage.imageFileProvider;
392393
imageDataProvider = srcImage.imageDataProvider;
393394
imageGcDrawer = srcImage.imageGcDrawer;
394395
this.styleFlag = srcImage.styleFlag | flag;
395-
if (imageFileNameProvider != null || imageDataProvider != null ||srcImage.imageGcDrawer != null) {
396+
if (imageFileProvider != null || imageDataProvider != null ||srcImage.imageGcDrawer != null) {
396397
/* If source image has 200% representation then create the 200% representation for the new image & apply flag */
397398
NSBitmapImageRep rep200 = srcImage.getRepresentation (200);
398399
if (rep200 != null) createRepFromSourceAndApplyFlag(rep200, srcWidth * 2, srcHeight * 2, flag);
@@ -737,8 +738,9 @@ public Image(Device device, String filename) {
737738
if (!NSThread.isMainThread()) pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init();
738739
try {
739740
if (filename == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
740-
initNative(filename);
741-
if (this.handle == null) init(new ImageData(filename));
741+
Path file = Path.of(filename);
742+
initNative(file);
743+
if (this.handle == null) init(ImageData.load(file));
742744
init();
743745
} finally {
744746
if (pool != null) pool.release();
@@ -747,16 +749,16 @@ public Image(Device device, String filename) {
747749

748750
/**
749751
* Constructs an instance of this class by loading its representation
750-
* from the file retrieved from the ImageFileNameProvider. Throws an
752+
* from the file retrieved from the {@link ImageFileProvider}. Throws an
751753
* error if an error occurs while loading the image, or if the result
752754
* is an image of an unsupported type.
753755
* <p>
754756
* This constructor is provided for convenience for loading image as
755757
* per DPI level.
756758
*
757759
* @param device the device on which to create the image
758-
* @param imageFileNameProvider the ImageFileNameProvider object that is
759-
* to be used to get the file name
760+
* @param imageFileProvider the {@link ImageFileProvider} object that is
761+
* to be used to get the file
760762
*
761763
* @exception IllegalArgumentException <ul>
762764
* <li>ERROR_NULL_ARGUMENT - if device is null and there is no current device</li>
@@ -772,24 +774,24 @@ public Image(Device device, String filename) {
772774
* @exception SWTError <ul>
773775
* <li>ERROR_NO_HANDLES if a handle could not be obtained for image creation</li>
774776
* </ul>
775-
* @since 3.104
777+
* @since 3.129
776778
*/
777-
public Image(Device device, ImageFileNameProvider imageFileNameProvider) {
779+
public Image(Device device, ImageFileProvider imageFileProvider) {
778780
super(device);
779-
if (imageFileNameProvider == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
780-
this.imageFileNameProvider = imageFileNameProvider;
781-
String filename = imageFileNameProvider.getImagePath(100);
782-
if (filename == null) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
781+
if (imageFileProvider == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
782+
this.imageFileProvider = imageFileProvider;
783+
Path file = imageFileProvider.getImagePath(100);
784+
if (file == null) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
783785
NSAutoreleasePool pool = null;
784786
if (!NSThread.isMainThread()) pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init();
785787
try {
786-
initNative(filename);
787-
if (this.handle == null) init(new ImageData(filename));
788+
initNative(file);
789+
if (this.handle == null) init(ImageData.load(file));
788790
init();
789-
String filename2x = imageFileNameProvider.getImagePath(200);
790-
if (filename2x != null) {
791+
Path file2x = imageFileProvider.getImagePath(200);
792+
if (file2x != null) {
791793
alphaInfo_200 = new AlphaInfo();
792-
id id = NSImageRep.imageRepWithContentsOfFile(NSString.stringWith(filename2x));
794+
id id = NSImageRep.imageRepWithContentsOfFile(NSString.stringWith(file2x.toString()));
793795
NSImageRep rep = new NSImageRep(id);
794796
handle.addRepresentation(rep);
795797
}
@@ -798,6 +800,41 @@ public Image(Device device, ImageFileNameProvider imageFileNameProvider) {
798800
}
799801
}
800802

803+
/**
804+
* Constructs an instance of this class by loading its representation
805+
* from the file retrieved from the ImageFileNameProvider. Throws an
806+
* error if an error occurs while loading the image, or if the result
807+
* is an image of an unsupported type.
808+
* <p>
809+
* This constructor is provided for convenience for loading image as
810+
* per DPI level.
811+
*
812+
* @param device the device on which to create the image
813+
* @param imageFileNameProvider the ImageFileNameProvider object that is
814+
* to be used to get the file name
815+
*
816+
* @exception IllegalArgumentException <ul>
817+
* <li>ERROR_NULL_ARGUMENT - if device is null and there is no current device</li>
818+
* <li>ERROR_NULL_ARGUMENT - if the ImageFileNameProvider is null</li>
819+
* <li>ERROR_INVALID_ARGUMENT - if the fileName provided by ImageFileNameProvider is null at 100% zoom</li>
820+
* </ul>
821+
* @exception SWTException <ul>
822+
* <li>ERROR_IO - if an IO error occurs while reading from the file</li>
823+
* <li>ERROR_INVALID_IMAGE - if the image file contains invalid data </li>
824+
* <li>ERROR_UNSUPPORTED_DEPTH - if the image file describes an image with an unsupported depth</li>
825+
* <li>ERROR_UNSUPPORTED_FORMAT - if the image file contains an unrecognized format</li>
826+
* </ul>
827+
* @exception SWTError <ul>
828+
* <li>ERROR_NO_HANDLES if a handle could not be obtained for image creation</li>
829+
* </ul>
830+
* @since 3.104
831+
* @deprecated Instead use {@link #Image(Device, ImageFileProvider)}
832+
*/
833+
@Deprecated(since = "2025-03")
834+
public Image(Device device, ImageFileNameProvider imageFileNameProvider) {
835+
this(device, (ImageFileProvider) zoom -> Path.of(imageFileNameProvider.getImagePath(zoom)));
836+
}
837+
801838
/**
802839
* Constructs an instance of this class by loading its representation
803840
* from the ImageData retrieved from the ImageDataProvider. Throws an
@@ -880,7 +917,7 @@ public Image(Device device, ImageGcDrawer imageGcDrawer, int width, int height)
880917
if (!NSThread.isMainThread()) pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init();
881918
try {
882919
init (data);
883-
init ();
920+
init ();
884921
} finally {
885922
if (pool != null) pool.release();
886923
}
@@ -902,7 +939,7 @@ private ImageData drawWithImageGcDrawer(ImageGcDrawer imageGcDrawer, int width,
902939

903940
private AlphaInfo _getAlphaInfoAtCurrentZoom (NSBitmapImageRep rep) {
904941
int deviceZoom = DPIUtil.getDeviceZoom();
905-
if (deviceZoom != 100 && (imageFileNameProvider != null || imageDataProvider != null)) {
942+
if (deviceZoom != 100 && (imageFileProvider != null || imageDataProvider != null)) {
906943
if (alphaInfo_100.alphaData != null && alphaInfo_200 != null) {
907944
if (alphaInfo_200.alphaData == null) initAlpha_200(rep);
908945
return alphaInfo_200;
@@ -1176,8 +1213,8 @@ public boolean equals (Object object) {
11761213
if (device != image.device || alphaInfo_100.transparentPixel != image.alphaInfo_100.transparentPixel) return false;
11771214
if (imageDataProvider != null && image.imageDataProvider != null) {
11781215
return styleFlag == image.styleFlag && imageDataProvider.equals (image.imageDataProvider);
1179-
} else if (imageFileNameProvider != null && image.imageFileNameProvider != null) {
1180-
return styleFlag == image.styleFlag && imageFileNameProvider.equals (image.imageFileNameProvider);
1216+
} else if (imageFileProvider != null && image.imageFileProvider != null) {
1217+
return styleFlag == image.styleFlag && imageFileProvider.equals (image.imageFileProvider);
11811218
} else if (imageGcDrawer != null && image.imageGcDrawer != null) {
11821219
return styleFlag == image.styleFlag && imageGcDrawer.equals(image.imageGcDrawer) && width == image.width
11831220
&& height == image.height;
@@ -1415,8 +1452,8 @@ NSBitmapImageRep createImageRep(NSSize targetSize) {
14151452
public int hashCode () {
14161453
if (imageDataProvider != null) {
14171454
return imageDataProvider.hashCode();
1418-
} else if (imageFileNameProvider != null) {
1419-
return imageFileNameProvider.hashCode();
1455+
} else if (imageFileProvider != null) {
1456+
return imageFileProvider.hashCode();
14201457
} else if (imageGcDrawer != null) {
14211458
return Objects.hash(imageGcDrawer, height, width);
14221459
} else {
@@ -1507,7 +1544,8 @@ void initAlpha_100(NSBitmapImageRep nativeRep) {
15071544

15081545
}
15091546

1510-
void initNative(String filename) {
1547+
void initNative(Path file) {
1548+
String filename = file.toString();
15111549
NSAutoreleasePool pool = null;
15121550
NSImage nativeImage = null;
15131551

bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/ImageLoader.java

+75-10
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2000, 2016 IBM Corporation and others.
2+
* Copyright (c) 2000, 2025 IBM Corporation and others.
33
*
44
* This program and the accompanying materials
55
* are made available under the terms of the Eclipse Public License 2.0
@@ -13,8 +13,9 @@
1313
*******************************************************************************/
1414
package org.eclipse.swt.graphics;
1515

16-
1716
import java.io.*;
17+
import java.nio.file.*;
18+
import java.nio.file.Path;
1819
import java.util.*;
1920

2021
import org.eclipse.swt.*;
@@ -161,7 +162,7 @@ public ImageData[] load(InputStream stream) {
161162
* an error occurs while loading the images, or if the images are
162163
* not of a supported type. Returns the loaded image data array.
163164
*
164-
* @param filename the name of the file to load the images from
165+
* @param file the name of the file to load the images from
165166
* @return an array of <code>ImageData</code> objects loaded from the specified file
166167
*
167168
* @exception IllegalArgumentException <ul>
@@ -172,17 +173,42 @@ public ImageData[] load(InputStream stream) {
172173
* <li>ERROR_INVALID_IMAGE - if the image file contains invalid data</li>
173174
* <li>ERROR_UNSUPPORTED_FORMAT - if the image file contains an unrecognized format</li>
174175
* </ul>
176+
* @since 3.129
175177
*/
176-
public ImageData[] load(String filename) {
177-
if (filename == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
178-
try (InputStream stream = new FileInputStream(filename)) {
178+
public ImageData[] load(Path file) {
179+
if (file == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
180+
try (InputStream stream = Files.newInputStream(file)) {
179181
return load(stream);
180182
} catch (IOException e) {
181183
SWT.error(SWT.ERROR_IO, e);
182184
}
183185
return null;
184186
}
185187

188+
/**
189+
* Loads an array of <code>ImageData</code> objects from the
190+
* file with the specified name. Throws an error if either
191+
* an error occurs while loading the images, or if the images are
192+
* not of a supported type. Returns the loaded image data array.
193+
*
194+
* @param filename the name of the file to load the images from
195+
* @return an array of <code>ImageData</code> objects loaded from the specified file
196+
*
197+
* @exception IllegalArgumentException <ul>
198+
* <li>ERROR_NULL_ARGUMENT - if the file name is null</li>
199+
* </ul>
200+
* @exception SWTException <ul>
201+
* <li>ERROR_IO - if an IO error occurs while reading the file</li>
202+
* <li>ERROR_INVALID_IMAGE - if the image file contains invalid data</li>
203+
* <li>ERROR_UNSUPPORTED_FORMAT - if the image file contains an unrecognized format</li>
204+
* </ul>
205+
* @deprecated Instead use {@link #load(Path)}
206+
*/
207+
@Deprecated(since = "2025-03")
208+
public ImageData[] load(String filename) {
209+
return load(Path.of(filename));
210+
}
211+
186212
/**
187213
* Saves the image data in this ImageLoader to the specified stream.
188214
* The format parameter can have one of the following values:
@@ -240,7 +266,7 @@ public void save(OutputStream stream, int format) {
240266
* <dd>TIFF file format</dd>
241267
* </dl>
242268
*
243-
* @param filename the name of the file to write the images to
269+
* @param file the name of the file to write the images to
244270
* @param format the format to write the images in
245271
*
246272
* @exception IllegalArgumentException <ul>
@@ -251,16 +277,55 @@ public void save(OutputStream stream, int format) {
251277
* <li>ERROR_INVALID_IMAGE - if the image data contains invalid data</li>
252278
* <li>ERROR_UNSUPPORTED_FORMAT - if the image data cannot be saved to the requested format</li>
253279
* </ul>
280+
* @since 3.129
254281
*/
255-
public void save(String filename, int format) {
256-
if (filename == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
257-
try (OutputStream stream = new FileOutputStream(filename)) {
282+
public void save(Path file, int format) {
283+
if (file == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
284+
try (OutputStream stream = Files.newOutputStream(file)) {
258285
save(stream, format);
259286
} catch (IOException e) {
260287
SWT.error(SWT.ERROR_IO, e);
261288
}
262289
}
263290

291+
/**
292+
* Saves the image data in this ImageLoader to a file with the specified name.
293+
* The format parameter can have one of the following values:
294+
* <dl>
295+
* <dt>{@link SWT#IMAGE_BMP}</dt>
296+
* <dd>Windows BMP file format, no compression</dd>
297+
* <dt>{@link SWT#IMAGE_BMP_RLE}</dt>
298+
* <dd>Windows BMP file format, RLE compression if appropriate</dd>
299+
* <dt>{@link SWT#IMAGE_GIF}</dt>
300+
* <dd>GIF file format</dd>
301+
* <dt>{@link SWT#IMAGE_ICO}</dt>
302+
* <dd>Windows ICO file format</dd>
303+
* <dt>{@link SWT#IMAGE_JPEG}</dt>
304+
* <dd>JPEG file format</dd>
305+
* <dt>{@link SWT#IMAGE_PNG}</dt>
306+
* <dd>PNG file format</dd>
307+
* <dt>{@link SWT#IMAGE_TIFF}</dt>
308+
* <dd>TIFF file format</dd>
309+
* </dl>
310+
*
311+
* @param filename the name of the file to write the images to
312+
* @param format the format to write the images in
313+
*
314+
* @exception IllegalArgumentException <ul>
315+
* <li>ERROR_NULL_ARGUMENT - if the file name is null</li>
316+
* </ul>
317+
* @exception SWTException <ul>
318+
* <li>ERROR_IO - if an IO error occurs while writing to the file</li>
319+
* <li>ERROR_INVALID_IMAGE - if the image data contains invalid data</li>
320+
* <li>ERROR_UNSUPPORTED_FORMAT - if the image data cannot be saved to the requested format</li>
321+
* </ul>
322+
* @deprecated Instead use {@link #save(Path, int)}
323+
*/
324+
@Deprecated(since = "2025-03")
325+
public void save(String filename, int format) {
326+
save(Path.of(filename), format);
327+
}
328+
264329
/**
265330
* Adds the listener to the collection of listeners who will be
266331
* notified when image data is either partially or completely loaded.

0 commit comments

Comments
 (0)