Modifying an Images Enum - java

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.

Related

Exported SVG overflows boundaries

I am visualizing some data with vaadin-charts:3.2.0, and I am trying to export a SVG out from the chart. I get some results but it is not satisfying. I can only share the screenshosts instead of the SVG itself. I also had to pixelate the labels to mask private data.
Original vaadin-charts seen on screen:
Exported SVG:
One problem is that the labels overflow the svg boundaries. And the chart drawings also overflow the boundaries making it seem like an incomplete drawing. Any idea what is wrong with this structure?
public class SvgStreamResource extends StreamResource {
public SvgStreamResource(String svgText, String filename) {
super(new StreamSource() {
#Override
public InputStream getStream() {
InputStream s = new BufferedInputStream( new ReaderInputStream(new StringReader(svgText)));
return s;
}
}, filename + ".svg");
}
#Override
public String getMIMEType() {
return "image/svg+xml";
}
}
Within a component:
Button exportButton = createExportButton("SVG", createSVGStreamSource(conf));
private SvgStreamResource createSVGStreamSource(Configuration conf) {
String svg = SVGGenerator.getInstance().generate(conf);
return new SvgStreamResource(svg, fileBaseName);
}
private Button createExportButton(String caption, SvgStreamResource svgStreamResource) {
Button b = new Button(caption);
FileDownloader downloader = new FileDownloader(svgStreamResource);
downloader.extend(b);
return b;
}

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

Vaadin FileDropTarget terrible performance

I'm trying to use Vaadin 8 FileDropTarget with a Tomcat server. The example code is little bit long, but maybe it will fit here:
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStream;
import com.vaadin.server.StreamVariable;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.Label;
import com.vaadin.ui.Notification;
import com.vaadin.ui.ProgressBar;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.dnd.FileDropTarget;
import hu.dynaxpress.base.mvc.DynaAbstractController;
#SuppressWarnings({ "serial", "rawtypes" })
public class FileStreamController extends DynaAbstractController {
private VerticalLayout layout;
private ProgressBar progress;
#Override
protected void onInit() {
super.onInit();
System.err.println("FileStreamController.onInit");
}
#Override
protected void onEnter() {
System.err.println("FileStreamController.onEnter");
// https://vaadin.com/docs/v8/framework/components/components-upload.html
layout = new VerticalLayout();
final Label infoLabel = new Label("DROP A FILE ON THIS TEXT");
infoLabel.setWidth(240.0f, Unit.PIXELS);
final VerticalLayout dropPane = new VerticalLayout(infoLabel);
dropPane.setComponentAlignment(infoLabel, Alignment.MIDDLE_CENTER);
dropPane.addStyleName("drop-area");
dropPane.setSizeUndefined();
dropPane.setWidth("100%");
progress = new ProgressBar();
progress.setIndeterminate(false);
progress.setVisible(false);
progress.setWidth("100%");
dropPane.addComponent(progress);
layout.addComponent(dropPane);
new FileDropTarget<>(dropPane, fileDropEvent -> {
final long fileSizeLimit = 20 * 1024 * 1024 * 1024; // 20GB
fileDropEvent.getFiles().forEach(html5File -> {
// html5File.getFileSize() always returns zero, but why?
if (false && ( html5File.getFileSize() > fileSizeLimit) ) {
Notification.show(
"File rejected. Max size=" +fileSizeLimit+ ", actual="+html5File.getFileSize(),
Notification.Type.WARNING_MESSAGE);
} else {
Label lbl = new Label(html5File.getFileName() + " size=" + html5File.getFileSize() + " " + html5File.getType());
lbl.setWidth("100%");
layout.addComponent(lbl);
final StreamVariable streamVariable = new StreamVariable() {
#Override
public OutputStream getOutputStream() {
try {
return new FileOutputStream("F:\\"+html5File.getFileName());
} catch (FileNotFoundException e) {
e.printStackTrace();
throw new Error("F:\\"+html5File.getFileName());
}
}
#Override
public boolean listenProgress() { return false; }
#Override
public void onProgress(final StreamingProgressEvent event) {
progress.setValue(
event.getBytesReceived() / event.getContentLength()
);
}
#Override
public void streamingStarted(
final StreamingStartEvent event) {
progress.setVisible(true);
progress.setCaption(event.getFileName());
}
#Override
public void streamingFinished(
final StreamingEndEvent event) {
progress.setVisible(false);
}
#Override
public void streamingFailed(final StreamingErrorEvent event) {
progress.setVisible(false);
}
#Override
public boolean isInterrupted() { return false; }
};
html5File.setStreamVariable(streamVariable);
progress.setVisible(true);
}
});
});
setCompositionRoot(layout);
}
}
This code works, but it has terrible performance. In this MWE, the program writes all dropped files to the F:\ drive. It is a flash drive (I wanted to simulate streaming large files and see how much memory is consumed over time). But I found that this program writes out a 40MB file in 20 seconds. That is 2MB/sec speed. The server runs on localhost, the source file and the target F: drive are all on my local machine. If I simply copy the same file to the drive then it takes less than 2 seconds.
I have tried with another (very slow) flash drive too, and had similar results. When tomcat is streaming the file, then it is about 10-20 times slower.
Is there a way to make this faster? What am I doing wrong? I do not see any way to speed this up, because the streaming happens inside the component.
The second important (no related) question is that why can't I get the file size? See the comment in the code: "html5File.getFileSize() always returns zero, but why?" I have checked the POST headers from firefox debugger, and the browser sends the size of the file in an JSON/RPC call, before it sends the actual file data. So the server should know the file size before the first byte arrives.

Java file encoding magic

Strange thing happened in Java Kingdom...
Long story short: I use Java API V3 to connect to QuickBooks and fetch the data form there (services for example).
Everything goes fine except the case when a service contains russian symbols (or probably non-latin symbols).
Here is Java code that does it (I know it's far from perfect)
package com.mde.test;
import static com.intuit.ipp.query.GenerateQuery.$;
import static com.intuit.ipp.query.GenerateQuery.select;
import java.util.LinkedList;
import java.util.List;
import com.intuit.ipp.core.Context;
import com.intuit.ipp.core.ServiceType;
import com.intuit.ipp.data.Item;
import com.intuit.ipp.exception.FMSException;
import com.intuit.ipp.query.GenerateQuery;
import com.intuit.ipp.security.OAuthAuthorizer;
import com.intuit.ipp.services.DataService;
import com.intuit.ipp.util.Config;
public class TestEncoding {
public static final String QBO_BASE_URL_SANDBOX = "https://sandbox-quickbooks.api.intuit.com/v3/company";
private static String consumerKey = "consumerkeycode";
private static String consumerSecret = "consumersecretcode";
private static String accessToken = "accesstokencode";
private static String accessTokenSecret = "accesstokensecretcode";
private static String appToken = "apptokencode";
private static String companyId = "companyidcode";
private static OAuthAuthorizer oauth = new OAuthAuthorizer(consumerKey, consumerSecret, accessToken, accessTokenSecret);
private static final int PAGING_STEP = 500;
public static void main(String[] args) throws FMSException {
List<Item> res = findAllServices(getDataService());
System.out.println(res.get(1).getName());
}
public static List<Item> findAllServices(DataService service) throws FMSException {
Item item = GenerateQuery.createQueryEntity(Item.class);
List<Item> res = new LinkedList<>();
for (int skip = 0; ; skip += PAGING_STEP) {
String query = select($(item)).skip(skip).take(PAGING_STEP).generate();
List<Item> items = (List<Item>)service.executeQuery(query).getEntities();
if (items.size() > 0)
res.addAll(items);
else
break;
}
System.out.println("All services fetched");
return res;
}
public static DataService getDataService() throws FMSException {
Context context = getContext();
if (context == null) {
System.out.println("Context is null, something wrong, dataService also will null.");
return null;
}
return getDataService(context);
}
private static Context getContext() {
try {
return new Context(oauth, appToken, ServiceType.QBO, companyId);
} catch (FMSException e) {
System.out.println("Context is not loaded");
return null;
}
}
protected static DataService getDataService(Context context) throws FMSException {
DataService service = new DataService(context);
Config.setProperty(Config.BASE_URL_QBO, QBO_BASE_URL_SANDBOX);
return new DataService(context);
}
}
This file is saved in UTF-8. And it prints something like
All services fetched
Сэрвыс, отнюдь
But! When I save this file in UTF-8 with BOM.... I get the correct data!
All services fetched
Сэрвыс, отнюдь
Does anybody can explain what is happening? :)
// I use Eclipse to run the code
You are fetching data from a system that doesn't share the same byte ordering as you, so when you save the file with BOM, it adds enough information in the file that future programs will read it in the remote system's byte ordering.
When you save it without BOM, it wrote the file in the remote system's byte ordering without any indication of the stored byte order, so when you read it you read it with the local system's (different) byte order. This jumbles up the bytes within the multi-byte characters, making the output appear as nonsense.

How can I make work an image cache in Android?

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. :)

Categories