How to Compare two ImageIcons? - java

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.

Related

Comparing icons as strings always returning false?

I'm currently working on a Tic-Tac-Toe game with java swing and figuring out how to create a checkWin method. The Tic-Tac-Toe board is initialized as a 2D array of buttons. Each button is assigned an image when clicked (alternating x's and o's).
The problem is, even when comparing two icons with the same string description, it returns false. Here's my code for
The Image assignment
public ImageIcon getImage(){
BufferedImage img = null;
String name="";
try{
if(this.num()== 1){
img = ImageIO.read(new FileInputStream(new File("x.jpg")));
name="x";
}else{
img = ImageIO.read(new FileInputStream(new File("o.jpg")));
name="o";
}
}catch(Exception e){
System.out.println(e);
System.out.println("null :(");
return null;
}
Image scaledImage = img.getScaledInstance(40, 40,Image.SCALE_SMOOTH);
ImageIcon imageIcon = new ImageIcon(scaledImage,name);
return imageIcon;
}
Here's the code snippet for equality comparison (also I have no idea why, but my 2d array prints out column major order rather than row major order)
buttons[i][j].getIcon().equals(buttons[i-1][j].getIcon()));
comparing the two o's below returns false
This is my first time posting on overflow please be patient with me :)
You should use integers instead, to represent 'x's and 'o's(like 1 and 0). And then, show them as images on the screen?
It'd be better to use an enumeration to compare, rather than the icons or integers as others have suggested. Why not integers? Because they're not as readable as using constants from an enumeration - you have to remember what 1 or 0 mean. There are other reasons to prefer an enumeration, too:
An integer field allows any value that fits, but there are only a limited set of possibilities. It's misleading for a reader. Strings would have the same problem.
Since the enumeration is a limited set of possibilities, an IDE can automatically suggest them all when you do want to compare, or otherwise use the values.

Android: How do I compare ImageSpan drawable to XML resource drawable?

I have a question which I cannot find an answer for too long and I would appreciate if you can help.
I have a TextEdit which I add icons (Emojis) into it between the text.
The Icons are stored in an ImageSpan[] array named imagesInTxt.
Then I loop through the ImageSpan[] and I am trying to compare its drawable or whatever constant value that it can offer to the resource from the XML, Eg: R.Drawable.Smiley that was used as icons in the first place.
The problem is that the unique identifier that returns from getResources().getDrawable(R.Drawable.smiley) does not match the identifier than I get from imagesInTxt[x].getDrawable(), although we are talking about the same icon exactly.
I don't want and don't see a way to use .SetTag() and .GetTag() because I am dealing with ImageSpan[] from within the EditText and not the button itself, so this solution is not helping me.
I don't want to compare the ImageSpan[] directly to the ImageView button. I need to compare it to the original resource that I used (Eg: R.Drawable.xxxx) in any way possible.
How can I achieve that ?
If it is impossible, what can you suggest as an alternative solution ?
ImageSpan[] imagesInTxt = txt.getSpans(0, txt.length(), ImageSpan.class);
for (int x = 0; x < itemSpans.length; x++) { // Go through the ICONS
Drawable myIcon = getResources().getDrawable(R.Drawable.smiley);
if(imagesInTxt[x].getDrawable().equals(myIcon)) {
Icon = ";-)";
}
myIcon = getResources().getDrawable(R.drawable.sad);
if(imagesInTxt[x].getDrawable().equals(myIcon)) {
Icon = ";-(";
}
}

Need help batch adding images with 00 in name of filepath (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

Java Swing Image Not Displaying?

I have written an applet in Java as a part of my programming class that takes a person's birthday and finds the day of the week on which they were born. As per the assignment specifications, we are to put this applet on our Amazon EC2 virtual servers as well.
Now, when the person is selected from a JTable, the program takes their information as well as the path to an image file also located in the JTable beside their info. So, for example, you could have the selection consisting of:
| John Doe | 17 | 02 | 2013 | /images/John.jpg |
When I run this on my local machine, everything works as expected - the date is calculated and the image is displayed. However, when I put it on my server, one of two things happens:
If I put the "display date" code before the "display image" code, then when I press the "Calculate" button, only the text displays and the image does not.
If I put the "display image" code before the "display date" code, nothing happens when I press the "Calculate" button.
What might be happening here? My images are still in the "images/Name.jpg" path, and I even tried using the entire path ("https://myUsername.course.ca/assignment/images/Name.jpg"). Neither works! Would there be any obvious reason for this odd behaviour?
/**
* Method that handles the user pressing the "Calculate" button
*/
private class btnCalculateHandler implements ActionListener {
public void actionPerformed(ActionEvent e) {
int result;
name = (String)table.getValueAt(table.getSelectedRow(), 0);
day = Integer.parseInt((String)table.getValueAt(table.getSelectedRow(), 1));
month = Integer.parseInt((String)table.getValueAt(table.getSelectedRow(), 2));
year = Integer.parseInt((String)table.getValueAt(table.getSelectedRow(), 3));
result = calculateDayOfWeek(day, month, year);
writeToFile();
ImageIcon imgPerson = new javax.swing.ImageIcon((String)table.getValueAt(table.getSelectedRow(), 4));
Image person = imgPerson.getImage();
Image personResized = person.getScaledInstance(75, 100, java.awt.Image.SCALE_SMOOTH);
ImageIcon imgPersonResized = new ImageIcon(personResized);
image.setIcon(imgPersonResized);
outputValue.setText(name + " was born on a " + days[result] + ".");
}
}
The first problem I see is this....
ImageIcon imgPerson = new javax.swing.ImageIcon((String)table.getValueAt(table.getSelectedRow(), 4))
ImageIcon(String) is used to specify a file name of the image. This should be used for loading images of a local disk, not a network path.
If the images are loaded relative to the to the applet, you would use Applet#getImage(URL, String) passing it a reference of Applet#getDocumentBase()
Something like getImage(getDocumentBase(), (String)table.getValueAt(table.getSelectedRow(), 4))
A better choice would be to use ImageIO. The main reason for this is that it won't use a background thread to load the image and will throw a IOException if something goes wrong, making it easier to diagnose any problems...
Something like...
BufferedImage image = ImageIO.read(new URL(getDocumentBase(), (String)table.getValueAt(table.getSelectedRow(), 4)));

Example text in JTextField

I am looking for a way to put example text into a swing JTextField and have it grayed out. The example text should then disappear as soon as any thing is entered into that text field. Some what similar to what stackoverflow does when a user is posting a question with the title field.
I would like it if it was already a extended implementation of JTextField so that I can just drop it in as a simple replacement. Anything from swingx would work. I guess if there is not an easy way to do this my option will probably be to override the paint method of JTextField do something that way maybe.
Thanks
The Text Prompt class provides the required functionality without using a custom JTextField.
It allows you to specify a prompt that is displayed when the text field is empty. As soon as you type text the prompt is removed.
The prompt is actually a JLabel so you can customize the font, style, colour, transparency etc..:
JTextField tf7 = new JTextField(10);
TextPrompt tp7 = new TextPrompt("First Name", tf7);
tp7.setForeground( Color.RED );
Some examples of customizing the look of the prompt:
If you can use external librairies, the Swing components from Jide software have what you are looking for; it's called LabeledTextField (javadoc) and it's part of the JIDE Common Layer (Open Source Project) - which is free. It's doing what mklhmnn suggested.
How about initialize the text field with default text and give it a focus listener such that when focus is gained, if the text .equals the default text, call selectAll() on the JTextField.
Rather than overriding, put a value in the field and add a KeyListener that would remove the value when a key stroke is registered. Maybe also have it change the foreground.
You could wrap this up into your own custom JTextField class that would take the default text in a constructor.
private JLabel l;
JPromptTextField(String prompt) {
l = new JLabel(prompt, SwingConstants.CENTER);
l.setForeground(Color.GRAY);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (this.getText().length() == 0) {
// Reshape the label if needed, then paint
final Rectangle mine = this.getBounds();
final Rectangle its = l.getBounds();
boolean resized = (mine.width != its.width) || (mine.height != its.height);
boolean moved = (mine.x != its.x) || (mine.y != its.y);
if (resized || moved)
l.setBounds(mine);
l.paint(g);
}
}
You can't do that with a plain text field, but you can put a disabled JLabel on top of the JTextField and hide it if the text field gets the focus.
Do it like this:
Define the string with the initial text you like and set up your TextField:
String initialText = "Enter your initial text here";
jTextField1.setText(initialText);
Add a Focus Listener to your TextField, which selects the entire contents of the TextField if it still has the initial value. Anything you may type in will replace the entire contents, since it is selected.
jTextField1.addFocusListener(new java.awt.event.FocusAdapter() {
public void focusGained(java.awt.event.FocusEvent evt) {
if (jTextField1.getText().equals(initialText)) {
jTextField1.selectAll();
}
}
});

Categories