How can I make work an image cache in Android? - java

I have some troubles with caching images in android. I'm downloading the images from an URL with an AsyncTask. Before the download I check if in the cache already contains a Drawable with the URL as key. If yes, the Drawable will be taken from the cache.
The download is triggered by a custom ArrayAdapter for a ListFragment or in the onCreateView() in another Fragment.
My issue is the following: The first download works properly. But if I scroll the ListFragment, the wrong images are loaded. If I reload the List or the Fragment, the Images will be taken from the cache, the ImageViews will be empty. If I don't use the cache, the image will be shown correctly.
Here the code of my CacheHandler:
import android.graphics.drawable.Drawable;
import android.util.LruCache;
public class CacheHandler {
private static CacheHandler instance;
private LruCache<String, Drawable> cache;
private final Logger logger = new Logger(CacheHandler.class);
private CacheHandler() {
final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
final int cacheSize = maxMemory / 8;
cache = new LruCache<String, Drawable>(cacheSize);
}
public static CacheHandler getInstance() {
if (instance == null)
instance = new CacheHandler();
return instance;
}
public void addToCache(String key, Drawable pic) {
if (getFromCache(key) == null) {
cache.put(key, pic);
logger.debug("Added drawable to cache with key " + key);
} else
logger.debug("Drawable with key " + key + " already exists");
}
public Drawable getFromCache(String key) {
logger.debug("Getting image for " + key);
Drawable d = cache.get(key);
logger.debug("Image is " + d);
return d;
}
}
Here the call in the AsyncTask:
logger.debug("Checking cache");
Drawable d = CacheHandler.getInstance().getFromCache((String) params[0]);
Thank you for your help.

There are many ways for your solutions.
You can Follow Links below
Link 1
Link 2
Link 3
Hope my answer is helpfull. :)

Related

How to Load WhatsApp Sticker from firebase?

Problem Description
How to Load Stickers Packs from firebase?
Links
Already I've been through -
https://github.com/idoideas/StickerMaker-for-Whatsapp
https://github.com/viztushar/stickers-internet
Well, you have to make a class with the sticker properties, a provider and a couple more things before loading the stickers from firebase(you can easily know how to retrieve data from firebase, it's the same for any data, so im going to skip that step)..
A dynamic WAStickers app should have following Characteristics:
Content Provider for necessary Details
It should Send an Intent to Whatsapp Sharing necessary details about the Sticker Pack All the
images must be in (or converted to) webp format
Why it should have a Content Provider?
A content provider is a class that sits between an application and its data source, and its job is to provide easy access to the underlying data source. This data can also be accessed by other applications on your device.
To provide necessary information about the StickerPack to WhatsApp you need to create a class called StickerPack which will hold the following parameters.
class StickerPack implements Parcelable {
String identifier;
String name;
String publisher;
String trayImageFile;
final String publisherEmail;
final String publisherWebsite;
final String privacyPolicyWebsite;
final String licenseAgreementWebsite;
String iosAppStoreLink;
private List<Sticker> stickers;
private long totalSize;
String androidPlayStoreLink;
private boolean isWhitelisted;
StickerPack(String identifier, String name, String publisher, String trayImageFile, String publisherEmail, String publisherWebsite, String privacyPolicyWebsite, String licenseAgreementWebsite) {
this.identifier = identifier;
this.name = name;
this.publisher = publisher;
this.trayImageFile = trayImageFile;
this.publisherEmail = publisherEmail;
this.publisherWebsite = publisherWebsite;
this.privacyPolicyWebsite = privacyPolicyWebsite;
this.licenseAgreementWebsite = licenseAgreementWebsite;
}
}
For additional information about this class follow the Link.
This class also contains an ArrayList of Stickers, where Sticker is defined by the following class.
package com.example.samplestickerapp;
import android.os.Parcel;
import android.os.Parcelable;
import java.util.List;
class Sticker implements Parcelable {
String imageFileName;
List<String> emojis;
long size;
Sticker(String imageFileName, List<String> emojis) {
this.imageFileName = imageFileName;
this.emojis = emojis;
}
protected Sticker(Parcel in) {
imageFileName = in.readString();
emojis = in.createStringArrayList();
size = in.readLong();
}
public static final Creator<Sticker> CREATOR = new Creator<Sticker>() {
#Override
public Sticker createFromParcel(Parcel in) {
return new Sticker(in);
}
#Override
public Sticker[] newArray(int size) {
return new Sticker[size];
}
};
public void setSize(long size) {
this.size = size;
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(imageFileName);
dest.writeStringList(emojis);
dest.writeLong(size);
}
}
Creating the Content Provider
For creating the content provider, first step is to:
Get permission to use the ContentProvider:
In the Android Manifest we should ask for a read/write permission to use the content provider. It’s a security feature which informs the user of what the app actually does.
<provider
android:name=".StickerContentProvider"
android:authorities="${contentProviderAuthority}"
android:enabled="true"
android:exported="true"
android:readPermission="com.whatsapp.sticker.READ" />
Where ${contentProviderAuthority} will be replaced by the authority name of your content provider.
Create a Class that extends ContentProvider
URI — Uniform Resource Identifier: URI is used to specifically identify or give the location of some data on your phone.
This location is how you know exactly what type of data we’re querying for. The location is build from 3 parts:
(1) content:// — The content provider prefix
(2) The content authority — specifies which Content Provider to use
(3) Specific
data — a string that identifies exactly what data in the Content
Provider we’re interesting in accessing.
In our Content Provider we need to mention 4 URI’S as mentioned here.
First, In the onCreate method of your ContentProvider class, create a URI Matcher object and add the URI’s to the object. Before going through the below code snippet read about Uri Matcher from the here.
Now since you are familiar with URI matcher you must be familiar with how to use it
First, we build a tree of Uri Matcher object.
Then we pass the Url to getType function which matches it against our URI
Let’s perform the first step here.
private static final UriMatcher MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
static final String METADATA = "metadata";
private static final int METADATA_CODE = 1;
private static final int METADATA_CODE_FOR_SINGLE_PACK = 2;
private static final int STICKERS_CODE = 3;
static final String STICKERS_ASSET = "stickers_asset";
private static final int STICKERS_ASSET_CODE = 4;
private static final int STICKER_PACK_TRAY_ICON_CODE = 5;
#Override
public boolean onCreate() {
final String authority = BuildConfig.CONTENT_PROVIDER_AUTHORITY;
if (!authority.startsWith(Objects.requireNonNull(getContext()).getPackageName())) {
throw new IllegalStateException("your authority (" + authority + ") for the content provider should start with your package name: " + getContext().getPackageName());
}
MATCHER.addURI(authority, METADATA, METADATA_CODE);
MATCHER.addURI(authority, METADATA + "/*", METADATA_CODE_FOR_SINGLE_PACK);
MATCHER.addURI(authority, STICKERS + "/*", STICKERS_CODE);
for (StickerPack stickerPack : getStickerPackList()) {
MATCHER.addURI(authority, STICKERS_ASSET + "/" + stickerPack.identifier + "/" + stickerPack.trayImageFile, STICKER_PACK_TRAY_ICON_CODE);
for (Sticker sticker : stickerPack.getStickers()) {
MATCHER.addURI(authority, STICKERS_ASSET + "/" + stickerPack.identifier + "/" + sticker.imageFileName, STICKERS_ASSET_CODE);
}
}
return true;
}
Here in the above method we have added a Uri pattern to our MATCHER object, now we need to match this pattern and return the exact UrI which will the location of sticker data on our device. Next the Url hit by WhatsApp is passed to the getType function to match it against our Uri’s and return the specific location of data on our device.
#Override
public String getType(#NonNull Uri uri) {
final int matchCode = MATCHER.match(uri);
switch (matchCode) {
case METADATA_CODE:
return "vnd.android.cursor.dir/vnd." + BuildConfig.CONTENT_PROVIDER_AUTHORITY + "." + METADATA;
case METADATA_CODE_FOR_SINGLE_PACK:
return "vnd.android.cursor.item/vnd." + BuildConfig.CONTENT_PROVIDER_AUTHORITY + "." + METADATA;
case STICKERS_CODE:
return "vnd.android.cursor.dir/vnd." + BuildConfig.CONTENT_PROVIDER_AUTHORITY + "." + STICKERS;
case STICKERS_ASSET_CODE:
return "image/webp";
case STICKER_PACK_TRAY_ICON_CODE:
return "image/png";
default:
throw new IllegalArgumentException("Unknown URI: " + uri);
}
}
Next, depending upon the Url we call the query method which will match the Uri and return a cursor object for the specific Uri.
#Override
public Cursor query(#NonNull Uri uri, #Nullable String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
final int code = MATCHER.match(uri);
if (code == METADATA_CODE) {
return getPackForAllStickerPacks(uri);
} else if (code == METADATA_CODE_FOR_SINGLE_PACK) {
return getCursorForSingleStickerPack(uri);
} else if (code == STICKERS_CODE) {
return getStickersForAStickerPack(uri);
} else {
throw new IllegalArgumentException("Unknown URI: " + uri);
}
}
Cursors are iterators that provide read/write access to the data of a Content Provider.
See the getPackForAllStickerPacks(), getCursorForSingleStickerPack() and getStickerPackInfo() function from here. To know the type of data to be provided by the Cursor Object.
Congratulations!! By now you have reached your first milestone. So far we have learnt:
What are Content Providers?
What type of Data do we send via ContentProviders?
How do we process the Uri’s to give a specific Cursor object?
If you can answer these questions then Congrats!! You have done a wonderful job. If not then I would suggest you to read about ContentProviders and UriMatcher’s to get a proper understanding.
After that, you just need to load the content from firebase, which should have the same structure on your class.
Source: Link

Share non-parcelable item between App and service

I'm looking for one way to share a non-parcelable item from my application and my current Service. This is the situation:
I have a Service to store all the media data from a camera application, photos, videos etc. The mission of this service is continue saving the media when the user go to background. When I did this in a first instance, I had a lot of SIGSEGV errors:
08-22 10:15:49.377 15784-15818/com.bq.camerabq A/libc: Fatal signal 11 (SIGSEGV), code 1, fault addr 0x8c3f4000 in tid 15818 (CameraModuleBac)
This was because the Image item that I recover from my imageReaders are not parceable, I fix this saving the Bytebuffers from the image instead of the whole image item.
But, now I'm getting the same problem with DNG captures, because from my imageReader I got a CaptureResult item that I need to use to create a DngCreator item to write the dng image.
CaptureResults and DngCreators are not parcelables or Serializables, so I don't find a way to save my data from the application to recover it in the service if I'm in background.
I have tried to copy the reference when calling the Service and it didn't worked. Also I saw in other posts as Object Sharing Between Activities in Android and Object Sharing Between Activities in Android that I can save the item in a static reference in my application context to be able to recover it in different activities. So finally I tried this:
public class DngManager extends Application {
public static DngManager sDngManagerInstance;
protected Hashtable<String, CaptureResult> dngCaptureResults;
private static String DNG_KEY_PREFIX = "dngResult_";
public DngManager(){
super();
createDNGCaptureResults();
}
public void createDNGCaptureResults() {
dngCaptureResults = new Hashtable<String, CaptureResult>();
}
public boolean addDNGCaptureResultToSharedMem(long dateKey, CaptureResult value) {
dngCaptureResults.put(DNG_KEY_PREFIX + dateKey, value);
return true;
}
public CaptureResult getFromDNGCaptureResults(long dateKey) {
return dngCaptureResults.get(DNG_KEY_PREFIX + dateKey);
}
private boolean containsDNGCaptureResults(long dateKey) {
return dngCaptureResults.containsKey(DNG_KEY_PREFIX + dateKey);
}
public void clearDNGCaptureResults(long dateKey) {
String partKey = String.valueOf(dateKey);
Enumeration<String> e2 = dngCaptureResults.keys();
while (e2.hasMoreElements()) {
String i = (String) e2.nextElement();
if (i.contains(partKey))
dngCaptureResults.remove(i);
}
}
public static DngManager getInstance(){
if (sDngManagerInstance == null){
sDngManagerInstance = new DngManager();
}
return sDngManagerInstance;
}
}
And later I recover it in my service:
CaptureResult dngResult = ((DngManager)getApplication()).getFromDNGCaptureResults(mDngPicture.getDateTaken());
if (dngResult == null) {
return;
}
DngCreator dngCreator = new DngCreator(mCameraCharacteristics, dngResult);
path = Storage.generateFilepath(title, "dng");
file = new File(Uri.decode(path));
try {
Log.e(TAG, "[DngSaveTask|run] WriteByteBuffer: Height " + mDngPicture.getSize().getHeight() + " Width " + mDngPicture.getSize().getWidth());
OutputStream os = new FileOutputStream(file);
dngCreator.writeByteBuffer(os, mDngPicture.getSize(), mDngPicture.getDngByteBuffer(), 0);
} catch (IOException e) {
Log.d(TAG, "[DngSaveTask|run] " + e);
e.printStackTrace();
}
dngCreator.close();
Log.e(TAG, "[DngSaveTask|run] Cleaning Result from shared memory");
DngManager.getInstance().clearDNGCaptureResults(mDngPicture.getDateTaken());
MediaScannerConnection.scanFile(getApplicationContext(), new String[]{file.getAbsolutePath()}, null, null);
Anyway, it still giving me back a SIGSEGV error. What else can I try?

Image field as part of the FieldGroup in Vaadin7

I have a requirement to display the image as part of the FieldGroup. This is for the functionality where the Image appears as normal on a web page, when in edit mode I need to edit this image value by providing an 'upload' option.
I have a Pojo with a property of type com.vaadin.ui.Image along with the other String and Integer values.
public Image getImage() {
return image;
}
public void setImage(Image image) {
this.image = image;
}
I need to work this Image as a normal form element, for example when I edit a form, I have an editable TextField to type in the String value and change it, the same way I intend to display an upload button where I would have an option to replace the existing image.
I have tried using EasyUploads addon for this purpose by intercepting the build method of FieldGroup and specifying the Image field as of type org.vaadin.easyuploads.UploadField
Like this;
#Override
#SuppressWarnings({ "rawtypes", "unchecked" })
protected <T extends Field> T build(String caption, Class<?> dataType,
Class<T> fieldType) throws BindException {
T field = super.build(caption, dataType, fieldType);
if (caption.equalsIgnoreCase("image")) {
final UploadField imageField = new UploadField() {
#Override
protected void updateDisplay() {
final byte[] pngData = (byte[]) getValue();
String filename = getLastFileName();
String mimeType = getLastMimeType();
long filesize = getLastFileSize();
if (mimeType.equals("image/jpeg")) {
StreamSource imagesource = new ImageSource(pngData);
StreamResource resource = new StreamResource(
imagesource, "Uploaded File");
Embedded embedded = new Embedded("Image:" + filename
+ "(" + filesize + " bytes)", resource);
getRootLayout().addComponent(embedded);
} else {
super.updateDisplay();
}
}
};
imageField.setFieldType(FieldType.BYTE_ARRAY);
...
This however fails to display the already available image, errors out with the stacktrace:
Caused by: java.lang.IllegalArgumentException: Property type class com.vaadin.ui.Image is not compatible with UploadField
at org.vaadin.easyuploads.UploadField.setPropertyDataSource(UploadField.java:1021)
at com.vaadin.data.fieldgroup.FieldGroup.bind(FieldGroup.java:265)
at com.vaadin.data.fieldgroup.BeanFieldGroup.bind(BeanFieldGroup.java:167)
at com.vaadin.data.fieldgroup.FieldGroup.setItemDataSource(FieldGroup.java:106)
at com.vaadin.data.fieldgroup.BeanFieldGroup.setItemDataSource(BeanFieldGroup.java:142)
Is there a cleaner way of using an Image as part of the FieldGroup in vaadin 7?
I would suggest replacing in your Pojo the Image instance with a simple byte[], because looking through the UploadField code, I can't see any natural way of converting the result from the upload (which is either a byte[] or a File instance) into something else, using the FieldGroup like you asked.
If you look inside AbstractField.getValue(), you will see that the model value is eventually passed through a settable converter which would have normally helped you in this case (see com.vaadin.data.util.converter.Converter). But I think you are pretty much forced to use byte[] if you want to bind a image bean to the FieldGroup.
Anyway, if you DO replace with byte[] the following steps will help you:
Create a custom FieldGroupFieldFactory that will create an UploadField if you want to bind to a byte[] property + passes a ValueChangeListener for the UploadField is done uploading:
public class ImageEnhancedFieldFactory extends DefaultFieldGroupFieldFactory {
private Property.ValueChangeListener fileUploadedListener;
private ImageEnhancedFieldFactory(Property.ValueChangeListener fileUploadedListener) {
this.fileUploadedListener = fileUploadedListener;
}
#Override
public <T extends Field> T createField(Class<?> type, Class<T> fieldType) {
if (byte[].class.equals(type)) {
UploadField uploadField = new UploadField(UploadField.StorageMode.MEMORY);
uploadField.setFieldType(UploadField.FieldType.BYTE_ARRAY);
uploadField.setButtonCaption("Change image");
uploadField.addListener(fileUploadedListener);
return (T) uploadField;
}
return super.createField(type, fieldType);
}
}
Create an Image instance that shows the content of the byte[] from the pojo:
final ImagePojo imagePojo = new ImagePojo();
imagePojo.setName("superman");
imagePojo.setImageContent(new byte[0]);
BeanItem<ImagePojo> item = new BeanItem<ImagePojo>(imagePojo);
final StreamResource imageResource = new StreamResource(new StreamResource.StreamSource() {
#Override
public InputStream getStream() {
return new ByteArrayInputStream(imagePojo.getImageContent());
}
}, "myimage");
imageResource.setCacheTime(0);
final Image image = new Image("Image", imageResource);
addComponent(image);
NOTE: its necessary to set the cache time to 0 in order to prevent the browser from caching the resource( see https://vaadin.com/book/vaadin7/-/page/components.embedded.html in the section Generating and Reloading Images)
3.Create the FieldGroup (with the new FieldGroupFieldFactory set) and bind to the properties of the pojo, including the one that contains the image content (the byte[]):
FieldGroup fieldGroup = new FieldGroup(item);
fieldGroup.setFieldFactory(new ImageEnhancedFieldFactory(new Property.ValueChangeListener() {
#Override
public void valueChange(Property.ValueChangeEvent event) {
SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmssSSS");
String filename = "myfilename-" + df.format(new Date()) + ".jpg";
imagePojo.setImageContent((byte[])event.getProperty().getValue());
image.markAsDirty();
imageResource.setFilename(filename);
}
}));
addComponent(fieldGroup.buildAndBind("Image name", "name"));
addComponent(fieldGroup.buildAndBind("Image content", "imageContent"));
I left a snippet on Gist of a component that you can paste in you UI and play around if you need (https://gist.github.com/gabrielruiu/9953279)

How to get profile image url from Facebook with spring-social?

I use spring-social-facebook to interact with Graph API (1.0.3.RELEASE if it's metter). And I can't find any operation to retrieve profile's image url. I found only operations which return array of bytes and they are not very convenient for the implementation.
Does any kind of operation which retrieves image url exist in Spring Social?
If not, is there any 'tidy' workaround for this?
Thanks!
Finally, I didn't find any mention of profile picture url in spring social
My solution:
Initially I planned to extend UserOperations (FacebokTemplate.userOperations) class and add new method. But it's a package-level class and doens't visible outside.
So I decided to create my own template class extending FacebookTemplate and implement the method in this way:
public String fetchPictureUrl(String userId, ImageType imageType) {
URI uri = URIBuilder.fromUri(GRAPH_API_URL + userId + "/picture" +
"?type=" + imageType.toString().toLowerCase() + "&redirect=false").build();
JsonNode response = getRestTemplate().getForObject(uri, JsonNode.class);
return response.get("data").get("url").getTextValue();
}
i just ran into same issue, hope this will help someone else
Connection<Facebook> connection = userConnectionRepository.findPrimaryConnection(Facebook.class);
connection.createData().getImageUrl()
You could take the miniature picture in this way :
"http://graph.facebook.com/" + fbUser.getId() + "/picture?type=square"
In social API you have ability just to fetch the image binary file:
byte[] profileImage = facebook.userOperations().getUserProfileImage(imageType);
To get URL you need to have something custom (as mentioned in the post above).
I took the part of code from Facebook Social API (see Facebook template source code for fetchImage) and the following utility class:
public final class FacebookUtils {
private static final String PICTURE_PATH = "picture";
private static final String TYPE_PARAMETER = "type";
private static final String WIDTH_PARAMETER = "width";
private static final String HEIGHT_PARAMETER = "height";
private FacebookUtils() {
}
public static String getUserProfileImageUrl(Facebook facebook, String userId, String width, String height, ImageType imageType) {
URIBuilder uriBuilder = URIBuilder.fromUri(facebook.getBaseGraphApiUrl() + userId + StringUtils.SLASH_CHARACTER + PICTURE_PATH);
if (imageType != null) {
uriBuilder.queryParam(TYPE_PARAMETER, imageType.toString().toLowerCase());
}
if (width != null) {
uriBuilder.queryParam(WIDTH_PARAMETER, width.toString());
}
if (height != null) {
uriBuilder.queryParam(HEIGHT_PARAMETER, height.toString());
}
URI uri = uriBuilder.build();
return uri.toString();
}
}

Modifying an Images Enum

So my friend crated this enum and i want to shorten it. I thought to shorting each of the file paths in strings and refrencing it String pokemonPath = "Pictures/Menu/MainMenu/"; and then being like pokePath +" Cosmet.png but I'm not sure on how to implement it. Also if anyone has anyideas on how to shorten it more, i would love to hear it too. ALos its in its own class file so putting constants at the top will not work properly, it give me an error.
I don't really work with enums so i dont know how to use them efficiently.
This is his code
import java.awt.Image;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public enum Images {
// Menu stuff. I don't know how to organize it. You do it.
WelcomeBG("Pictures/Menu/MainMenu/WelcomeBG.png"), PokemonTitleMenuBG(
"Pictures/Menu/MainMenu/PokemonTitleMenuBG.png"), PokemonMenuAll(
"Pictures/Menu/PokemonMenu/PokemonMenuAll.png"), PokemonMenuContinue(
"Pictures/Menu/PokemonMenu/PokemonMenuContinue.png"), PokemonMenuContinueSelected(
"Pictures/Menu/PokemonMenu/PokemonMenuContinueSelected.png"), PokemonMenuAllSelected(
"Pictures/Menu/PokemonMenu/PokemonMenuAllSelected.png"), TitleScreen(
"Pictures/Menu/MainMenu/TitleScreen.png"),
Professor("Pictures/Menu/NPC/Professor.png"), ProfessorFlip(
"Pictures/Menu/NPC/ProfessorFlip.png"),
FriendGirl("Pictures/Menu/PlayerPictures/FriendGirl.png"), FriendBoy(
"Pictures/Menu/PlayerPictures/FriendBoy.png"), PlayerBoy(
"Pictures/Menu/PlayerPictures/PlayerBoy.png"), PlayerGirl(
"Pictures/Menu/PlayerPictures/PlayerGirl.png"), Male(
"Pictures/Menu/PlayerPictures/Male.png"), Female(
"Pictures/Menu/PlayerPictures/Female.png"), Credits(
"Pictures/Menu/MainMenu/Credits.png"), Gender(
"Pictures/Menu/PlayerPictures/Gender.png"),
// Player sprites
PlayerDown("Pictures/Sprites/Player/"), PlayerDown1(
"Pictures/Sprites/Player/Down1.png"), PlayerDown2(
"Pictures/Sprites/Player/Down2.png"), PlayerLeft(
"Pictures/Sprites/Player/Left.png"), PlayerLeft1(
"Pictures/Sprites/Player/Left1.png"), PlayerLeft2(
"Pictures/Sprites/Player/Left2.png"), PlayerRight(
"Pictures/Sprites/Player/Right.png"), PlayerRight1(
"Pictures/Sprites/Player/Right1.png"), PlayerRight2(
"Pictures/Sprites/Player/Right2.png"), PlayerUp(
"Pictures/Sprites/Player/Up.png"), PlayerUp1(
"Pictures/Sprites/Player/Up1.png"), PlayerUp2(
"Pictures/Sprites/Player/Up2.png"),
// NPC Sprites
DadDown("Pictures/Sprites/NPC/Dad/DadDown.png"), DadRight(
"Pictures/Sprites/NPC/Dad/DadRight.png"), BoyLeft(
"Pictures/Sprites/NPC/Boy/BoyLeft.png"), BoyRight(
"Pictures/Sprites/NPC/Boy/BoyRight.png"), BoyRight1(
"Pictures/Sprites/NPC/Boy/BoyRight1.png"), BoyRight2(
"Pictures/Sprites/NPC/Boy/BoyRight2.png"), BoyUp(
"Pictures/Sprites/NPC/Boy/BoyUp.png"), BoyUp1(
"Pictures/Sprites/NPC/Boy/BoyUp1.png"), BoyUp2(
"Pictures/Sprites/NPC/Boy/BoyUp2.png"), DadUp(
"Pictures/Sprites/NPC/Dad/DadUp.png"), DadLeft(
"Pictures/Sprites/NPC/Dad/DadLeft.png"),
GirlDown("Pictures/Sprites/NPC/Girl/GirlDown.png"), GirlRight(
"Pictures/Sprites/NPC/Girl/GirlRight.png"), GirlLeft(
"Pictures/Sprites/NPC/Girl/GirlLeft.png"), GateDown(
"Pictures/Sprites/NPC/Gate/GateDown.png"), GateLeft(
"Pictures/Sprites/NPC/Gate/GateLeft.png"), GateLeft1(
"Pictures/Sprites/NPC/Gate/GateLeft1.png"), GateLeft2(
"Pictures/Sprites/NPC/Gate/GateLeft2.png"), GateRight(
"Pictures/Sprites/NPC/Gate/GateRight.png"), GateRight1(
"Pictures/Sprites/NPC/Gate/GateRight1.png"), GateRight2(
"Pictures/Sprites/NPC/Gate/GateRight2.png"), BoyDown(
"Pictures/Sprites/NPC/Boy/BoyDown.png"),
// NPC Effects
Exclamation("Pictures/Sprites/Misc/Exclamation.png"),
// Maps (the background, base thing)
Exitium("Pictures/Maps/Exitium.png"), Route1("Pictures/Maps/Route1.png"), House1Top(
"Pictures/Maps/House1Top.png"), House1Bot(
"Pictures/Maps/House1Bot.png"), MiracleForest1(
"Pictures/Maps/MiracleForest1.png"), MiracleForest2(
"Pictures/Maps/MiracleForest2.png"),
// Map decorations (the stuff you code on top of the map!)
House1Overlay("Pictures/Sprites/Structures/House1Overlay.png"), House2Overlay(
"Pictures/Sprites/Structures/House2Overlay.png"), House3Overlay(
"Pictures/Sprites/Structures/House3Overlay.png"), House4Overlay(
"Pictures/Sprites/Structures/House4Overlay.png"), Lamppost(
"Pictures/Sprites/Structures/Lamppost.png"), MailBox(
"Pictures/Sprites/Structures/MailBox.png"), MailBox2(
"Pictures/Sprites/Structures/MailBox2.png"), ColumnTrees(
"Pictures/Sprites/Structures/ColumnTrees.png"), Sign(
"Pictures/Sprites/Misc/Sign.png"), GreenColumnTrees(
"Pictures/Sprites/Structures/GreenColumnTrees.png"), GreenColumnTrees2(
"Pictures/Sprites/Structures/GreenColumnTrees2.png"), GreenColumnTrees3(
"Pictures/Sprites/Structures/GreenColumnTrees3.png"), ForestEntrance(
"Pictures/Sprites/Structures/ForestEntrance.png"), GreenTreeOverlay(
"Pictures/Sprites/Structures/GreenTreeOverlay.png"), LeftEntrance(
"Pictures/Sprites/Structures/LeftEntrance.png"), RightEntrance(
"Pictures/Sprites/Structures/RightEntrance.png"),
// GUI Things???
Arrow("Pictures/Sprites/Misc/Arrow.png"), Hand(
"Pictures/Sprites/Misc/Hand.png"), DialogBox(
"Pictures/Sprites/Misc/DialogBox.png"), DialogBox2(
"Pictures/Sprites/Misc/DialogBox2.png"), DialogBox3(
"Pictures/Sprites/Misc/DialogBox3.png"), DialogBox4(
"Pictures/Sprites/Misc/DialogBox4.png"),
// I dont even know
MainBattleBack("Pictures/Sprites/Battle/BattleStart/MainBattleBack.png"), Vs2(
"Pictures/Sprites/Battle/BattleStart/Vs2.png"), MainHead(
"Pictures/Sprites/Battle/BattleStart/MainHead.png"),
// Battle Menu GUI things??
GreenBackground("Pictures/Sprites/Battle/BattleMenu/GreenBackground.png"), BattleMenu2(
"Pictures/Sprites/Battle/BattleMenu/BattleMenu2.png"), HpBarAlly(
"Pictures/Sprites/Battle/BattleMenu/HpBarAlly.png"), HpBarEnemy(
"Pictures/Sprites/Battle/BattleMenu/HpBarEnemy.png"), MoveMenu2(
"Pictures/Sprites/Battle/BattleMenu/MoveMenu2.png"),
// Natalie
Natalie("Pictures/Menu/NPC/Natalie.png"), NatalieHead(
"Pictures/Sprites/Battle/BattleStart/NatalieHead.png"), NatalieBattleBack(
"Pictures/Sprites/Battle/BattleStart/NatalieBattleBack.png"),
// Flashing
PlayerFlashNormal(
"Pictures/Sprites/Battle/BattleStart/Player_flash_normal.gif"), OpponentFlashNormal(
"Pictures/Sprites/Battle/BattleStart/Opponent_flash_normal.gif"),
// Throwing Animation
MainThrow("Pictures/Sprites/Player/MainThrow.png"), MainThrow1(
"Pictures/Sprites/Player/MainThrow1.png"), MainThrow2(
"Pictures/Sprites/Player/MainThrow2.png"),
// Attack Effects
Tackle("Pictures/Sprites/Battle/Attacks/Tackle.png"), BlackBack(
"Pictures/Sprites/Battle/Attacks/BlackBack.png"), Growl(
"Pictures/Sprites/Battle/Attacks/Growl.png"), Leer(
"Pictures/Sprites/Battle/Attacks/Leer.png"),
// POKEMONS
Cosmet("Pictures/Sprites/Pokemon/Cosmet.png"), CosmetB(
"Pictures/Sprites/PokemonB/CosmetB.png"), CosmetStart(
"Pictures/Menu/Starters/CosmetStart.png"),
Tykepol("Pictures/Sprites/Pokemon/Tykepol.png"), TykepolB(
"Pictures/Sprites/PokemonB/TykepolB.png"), TykepolStart(
"Pictures/Menu/Starters/TykepolStart.png"),
Embite("Pictures/Sprites/Pokemon/Embite.png"), EmbiteB(
"Pictures/Sprites/PokemonB/EmbiteB.png"), EmbiteStart(
"Pictures/Menu/Starters/EmbiteStart.png"),
// Balls
Pokeball("Pictures/Sprites/Misc/Pokeball.png"), Pokeball4(
"Pictures/Sprites/Misc/Pokeball4.gif"),
// Outlines
Outline1("Pictures/Sprites/Battle/BattleMenu/Outline1.png"), Outline2(
"Pictures/Sprites/Battle/BattleMenu/Outline2.png"), Outline3(
"Pictures/Sprites/Battle/BattleMenu/Outline3.png"), Outline4(
"Pictures/Sprites/Battle/BattleMenu/Outline4.png");
private String filePath;
private Image image;
private boolean imageLoaded;
private Images(String imagePath) {
filePath = imagePath;
imageLoaded = false;
}
public Image getImage() {
if (!imageLoaded) {
loadImage();
}
return image;
}
public void loadImage() {
try {
image = ImageIO.read(new File(filePath));
} catch (IOException e) {
System.err.println("Failed to load image!");
e.printStackTrace();
}
imageLoaded = true;
}
How you do will depend on what it is you want to achieve.
If you want to prevent the need to replace the path in multiple places should it change, then using String constants is a reasonable idea.
Something like...
public interface PathConstants {
protected static final String SPRITES_PATH = "Pictures/Sprites";
protected static final String SPRITES_MISC_PATH = SPRITES_PATH + "/Misc";
protected static final String POKEMON_SPRITES_PATH = SPRITES_PATH + "/Pokemon";
protected static final String POKEMONB_SPRITES_PATH = SPRITES_PATH + "/PokemonB";
protected static final String STARTERS_MENU_PATH = "Pictures/Menu/Starters";
protected static final String SPRITES_BATTLE_PATH = SPRITES_PATH + "/Battle";
protected static final String MENU_BATTLE_PATH = SPRITES_BATTLE_PATH + "/BattleMenu";
}
Then you should be able to do something like...
public enum Images {
Cosmet(PathConstants.SPRITES_PATH + "/Cosmet.png"), CosmetB(
PathConstants.POKEMONB_SPRITES_PATH + "/CosmetB.png"), CosmetStart(
PathConstants.STARTERS_MENU_PATH + "/CosmetStart.png"),
Tykepol(PathConstants.POKEMON_SPRITES_PATH + "/Tykepol.png"), TykepolB(
PathConstants.POKEMONB_SPRITES_PATH + "/TykepolB.png"), TykepolStart(
PathConstants.STARTERS_MENU_PATH + "/TykepolStart.png"),
Embite(PathConstants.POKEMON_SPRITES_PATH + "/Embite.png"), EmbiteB(
PathConstants.POKEMONB_SPRITES_PATH + "/EmbiteB.png"), EmbiteStart(
PathConstants.STARTERS_MENU_PATH + "/EmbiteStart.png"),
// Balls
Pokeball(PathConstants.SPRITES_MISC_PATH + "/Pokeball.png"), Pokeball4(
PathConstants.SPRITES_MISC_PATH + "/Pokeball4.gif"),
// Outlines
Outline1(PathConstants.MENU_BATTLE_PATH + "/Outline1.png"), Outline2(
PathConstants.MENU_BATTLE_PATH + "/Outline2.png"), Outline3(
PathConstants.MENU_BATTLE_PATH + "/Outline3.png"), Outline4(
PathConstants.MENU_BATTLE_PATH + "/Outline4.png");
For example.
This means that if the SPRITES_PATH changes, you only need to change it one place and recompile.

Categories