Need help batch adding images with 00 in name of filepath (Java) - java

I'm having trouble batch adding images to a JButton grid. I'm trying to use a for loop who's variable is used in the string name.
The names of the images are like:
32px-Shuffle001.png
32px-Shuffle821.png
etc.
Here's the part of the code that I'm trying to add in images with. The third setIcon works, but the first two don't. I'm confused on why this is.
Additionally, the image files are not consecutive numbers. For example, I have 001,002,003,004,005, but not 007,008, then continuing at 009,010. I'm trying to figure out a good way to make it skip to the next available image.
Overall, this code is for a match 3 puzzle solver, and this is a selection grid for icons to put on the puzzle grid, so I need to be able to call the correct image associated to a button ID.
for (int i = 0; i < 1000; i++) {
JButton selectionClicky = new JButton();
if (i < 10) {
selectionClicky.setIcon(new ImageIcon("src/img/32px-Shuffle" + "00"
+ i + ".png"));
}
if (i < 100){
selectionClicky.setIcon(new ImageIcon("src/img/32px-Shuffle"+ "0"
+ i + ".png"));
}
if (i < 1000){
selectionClicky.setIcon(new ImageIcon("src/img/32px-Shuffle"
+ i + ".png"));
}
selectionClicky.setFocusable(false);
selectionMainPanel.add(selectionClicky);
selectionButtonList.add(selectionClicky);
}

Don't ever use src in any path reference, this is a good indication that things will go wrong, instead use Class#getResource or Class#getResourceAsStream depending on your requirements.
Basically, the general idea would be to test if the resource actually existed before trying to load it, for example...
String path = String.format("/img/32px-Shuffle%03d", i);
URL resource = getClass().getResource(path);
if (resource != null) {
BufferedImage img = ImageIO.read(resource);
selectionClicky.setIcon(new ImageIcon(img));
}
Generally, ImageIO is preferred over using ImageIcon, mostly because ImageIO throws an IOException when the image can't be loaded for some reason (instead of failing silently) and won't return until the image is fully loaded
See Reading/Loading an Image for more details about ImageIO

Related

How to Compare two ImageIcons?

Basically, i'm using 2 images for a board game type of thing, and i change it from time to time,
So i need to be able to check if two has the same imageIcon.
For example if both uses "pirosfigura.png" from the resources folder.
public String malomcheck() {
String pirosicon=lblNewLabel.getIcon().toString();
String pirosfilenev = pirosicon.substring(pirosicon.lastIndexOf("/" ) + 1);
String iconfilenev = labelhely_1.getIcon().toString();
String filenev = iconfilenev.substring(iconfilenev.lastIndexOf("/" ) + 1);
if(filenev==pirosfilenev) {
lblJtkos.setText("piros malom.");
JOptionPane.showMessageDialog(null, "working");
return "lefutott";
}
return "notworking. very sad.";
}
By the way the return value of the getIcon().toString() is javax.swing.ImageIcon#cd7e8021
which is refers to the memory place i guess(?) so it's random with every run and for every image therefore it's seems unusable.
One way you can achieve this, is to keep your own mapping of ImageIcons to files, so that whenever you load an ImageIcon you store it in a Map as a key and its file or some symbolic name/enum as value. This way when you want to compare imIc1 and imIc2 you would write something like:
if (map.get(imIc1).equals(map.get(imIc2)) { ... }
or (if you have descriptive string values )
if (map.get(imIc1).equals("NOT_WORKING_ICON") { ... }
or (if you are using enum values )
if (map.get(imIc1) == NOT_WORKING_ICON ) { ... }
it's so weird for me that there is no method to get to the filepath the Jlabel is using for an image.
Makes perfect sense. A JLabel displays an Icon.
Why should a JLabel know or care about the file path?
You could implement the Icon interface yourself and do the custom painting for the Icon. So not all Icons will have a file path. Only an ImageIcon is created from a file.
The property for the file name belongs to the ImageIcon.
By the way the return value of the getIcon().toString() is javax.swing.ImageIcon#cd7e8021
Image piros=new ImageIcon(this.getClass().getResource("pirosfigura.png")).getImage();
celpont.setIcon(new ImageIcon(piros));
Look at the above code that you are using.
You area creating an Icon from an Image, so the file information is lost.
Instead you should just create the ImageIcon directly:
ImageIcon icon = new ImageIcon( this.getClass().getResource("pirosfigura.png") );
celpont.setIcon( icon );
System.out.println( celpont.getIcon() );
I believe the ImageIcon will then save the filename as the "description" for the ImageIcon. It appears the toString() will return the description.

How to move images in an excel sheet with java

I have an XSSFSheet with images at the end of my used rows. When adding a new row, I would like to shift all images one row down. I have found this similar question about moving charts, and have tried to use the part of the answer that does the actual moving of the charts, because It looked like it would work for images as well.
java.util.List<CTTwoCellAnchor> drawingAnchors = ((XSSFDrawing)sheet.getDrawingPatriarch()).getCTDrawing().getTwoCellAnchorList();
for (CTTwoCellAnchor drawingAnchor : drawingAnchors) {
int fromRow = drawingAnchor.getFrom().getRow();
int toRow = drawingAnchor.getTo().getRow();
if (fromRow >= startRow) {
drawingAnchor.getFrom().setRow(fromRow + n);
drawingAnchor.getTo().setRow(toRow + n);
}
}
but this did not work but throws a NoClassDefFoundError instead.
(Edit: I now found out that this error can be solved by providing the full jar of all of the schemas ooxml-schemas as mentioned in FAQ-N10025. thanks #Axel Richter)
After trying out several different approaches, I found a way to do it. Since it took me so long, and there is no info about this anywhere yet, I decided to post my findings here on SO.
Please find my solution in my own answer. Cheers
The following code gets the Drawing Patriarch of the sheet, iterates over all it's shapes, and if the shape is of type XSSFPicture it modifies the rowindexes through its XSSFClientAnchor.
int moveRowsBy = 1; // 1 will move the images 1 row down. moveRowsBy can be negative to move up
XSSFDrawing drawing = sheet.getDrawingPatriarch();
for (XSSFShape shape : drawing.getShapes()) {
if (shape instanceof XSSFPicture){
XSSFClientAnchor anchor = ((XSSFPicture)shape).getClientAnchor();
anchor.setRow1(anchor.getRow1() +moveRowsBy);
anchor.setRow2(anchor.getRow2() +moveRowsBy);
// if needed you could change column too, using one of these:
// anchor.setCol1(newColumnInt)
// anchor.setCol1(anchor.getCol1() + moveColsBy)
}
}

JavaFX ListView File Save

I'm going to try to keep my post as short as possible;
Here's my custom Object
public class ListItem {
ListItem(String text){
this.text = text;
}
final String text;
final ObjectProperty<Font> font = new SimpleObjectProperty<>();
final ObjectProperty<Color> color = new SimpleObjectProperty(Color.BLACK);
}
It's a cell object for holding: String, Color, Font/int (I just need the Fontsize, might change it to int if needed)
Using it, I created a ListView<ListItem>.
Now I can fill that ListView<ListItem> with a cell which is a ListItem using a CellFactory. That looks like this.
Until here - everything works. (The above code & explanation is for better understanding what I'm trying to do)
but now, I don't know how to do the following:
Saving the ListView-Content to a file. Or a little more clearly; How can I take the whole content of my ListView, filled with custom Objects while saving all of their properties (String, Color, Int)?
A little example of how I'd imagine that to give you a better idea:
"entry_1":
text: "entry text goes here"
color: "web color code goes here (e.g. #ff4d4d)"
fontsize: "16"
"entry_2":
...
Update
I set up a loop, I guess it should work fine but this gives me errors;
My file/it's path:
private final String saveLoc = System.getenv("ProgramFiles")
+ File.separator
+ "simpleNotizen"
+ File.separator
+ "simpleNotizen.properties";
private final File save = new File(saveLoc);
How I call it:
if(!save.exists()){
save.getParentFile().mkdirs();
save.createNewFile();
}
The error (thrown on save.createNewFile();):
Caused by: java.io.IOException: The System can't find the given Path
(Or something similair, had to translate it)
I really don't get why the error is thrown, I tried FileWriter, OutputStream, File, but everytime the same error..
I also tried to give a sysout, which seems perfectly fine:
C:\Program Files\simpleNotizen\simpleNotizen.properties
Solved
If anyone wonders how I fixed it, here it is
For saving my ListView Content, I wrote a loop which repeats itself by the amount of entries there are in the ListView;
for (int i = 0; i < listSize; i++) {
prop.setProperty("entry_" + Integer.toString(i),
listView.getItems().get(i).text
+ "|"
+ listView.getItems().get(i).color.getValue()
+ "|"
+ listView.getItems().get(i).font.getValue().getSize()
);
}
My second problem appeared to be a Permission problem with the C:\Program Files\-Path, fixed it by replacing it w/ APPDATA

Finding best fit from a list of images

I'm using a library called Image4j to load an ico file, choose one of the images from the list, scale it (if necessary) and put it in a JLabel as an ImageIcon.
The library has a method read(File icoFile) which returns a List<BufferedImage> , a list of all the images contained within the ico file.
What I want to be able to do is quickly choose the image from the list that is the closest fit for the size of the label. Both the labels and the ico images will be square.
I've come up with the most naive way, but I suspect there's a faster one. I'd settle for this one, but my program will be doing this routine a lot so I want this part to be as efficient as possible.
public class IconUtil() {
private final List<BufferedImage> list;
public IconUtil(List<BufferedImage> list) {
this.list = list;
}
public BufferedImage getBestFit(int sizeToFit) {
int indexOfBestFit = 0; // assume it's the first image
int bestMargin = Math.abs(list.get(0).getWidth() - sizeToFit);
int margin;
for(int i = 1; i < list.size(); i++) {
margin = Math.abs(list.get(i).getWidth() - sizeToFit);
if(margin < bestMargin) {
bestMargin = margin;
indexOfBestFit = i;
}
}
return list[indexOfBestFit];
}
}
The choice to compare the images by their width was arbitrary because they're all square.
Also, as the main reason for picking the best fit is to try and maintain the quality of the images, should this method discard any images which are smaller than the target size? If so, how would that change the algorithm?
I have little experience with re-scaling images in Java. Is it even necessary to find the closest match in size? Maybe there are ways to re-scale without losing much quality even if the original is much bigger?

How should I do image animation?

I plan to have an animated character (the character's image changing multiple times to make it appear to be moving), and I would like to know the best way to do it. I am currently planning to do something like this:
String fileLocation = "./images/picture";
BufferedImage img;
int numImages = 10;
for(int i = 0; i < numImages; i++){
img = ImageIO.read(new File(fileLocation + i + ".png"));
Thread.sleep(100);
g.drawImage(img, 0, 0, null);
}
This is an incredibly simplified version, missing a few things, but I'm sure you get what I mean. Are there any problems doing it this way? (Note: the for loop would repeat again straight after finishing, and there would be files called "picture0.png", "picture1.png", etc. in the "images" folder)
If the images are not huge and don't require a lot of memory for storing them, I would rather read the images first and cache them. When they need to be displayed, I would read them from memory rather than from disk.

Categories