Comparing ImageIcons in 2 JButtons - java

I wonder why am getting null in my comparison that checks if two JButtons have the same ImageIcon? Here is my class
public class Card extends JButton{
// Instance Variables
private ImageIcon icon;
private static final int CARD_SIZE = 165;
public Card(ImageIcon icon){
setIcon(ResizeIcon(icon));
this.icon = icon;
setOpaque(true);
setBorder(new EmptyBorder(0,0,0,0));
// Preferred card size
setPreferredSize(new Dimension(CARD_SIZE, CARD_SIZE));
}
public boolean SameIcon(Card card){
System.out.println(((ImageIcon)this.getIcon()).getDescription());
return getIcon() == card.getIcon();
}
// Resize the image to fit into JButton regardless of its original dimensions
private ImageIcon ResizeIcon(ImageIcon imagIcon){
Image img = imagIcon.getImage();
Image newimg = img.getScaledInstance(CARD_SIZE - 5, CARD_SIZE - 5, java.awt.Image.SCALE_SMOOTH);
return new ImageIcon(newimg);
}
}
My question is basically why i get null when i do (ImageIcon)this.getIcon().getDescription(). It seems like setIcon only sets only ImageIcon and not the Icon. Because it shows on the JButton that an ImageIcon is present but when i try to retrieve it, it get null

I changed to Resize method to return an Image instead so it looked as follows
private Image ResizeIcon(ImageIcon imagIcon){
return (imagIcon.getImage()).getScaledInstance(
CARD_SIZE - 5,
CARD_SIZE - 5,
java.awt.Image.SCALE_SMOOTH);
}
then when calling the setIcon() Method of any specific JButton, i say
setIcon(new ImageIcon(ResizeIcon(icon), icon.toString()));
Remember, icon is an ImageIcon variable so its easier to get the location string. I compare the strings instead.
I know its a bit not wise to compare strings, but it proved to be a way out forthe time being

Related

loading great amount of buffered images slows down the program a lot java [duplicate]

This question already has answers here:
How to set icon in a column of JTable?
(3 answers)
Closed 7 months ago.
i'm setting up a custom cell renderer for a JTable, that has to contain an album cover image, that is from a byte[] taken with another library, the problem is that converting to a BufferedImage is so slow that in earlier version of the code the program wouldn't even start.
Now the situation is better, but the lag is very noticeable nonetheless. Here is the code:
public class ImageCellRenderer extends DefaultTableCellRenderer {
JLabel lbl = new JLabel();
public Image[] getAlbumart() throws IOException {
Image[] albumArt = new Image[allmymusic.size()];
for (int i = 0; i < allmymusic.size(); i++) {
byte[] data = allmymusic.get(i).albumImageData;
ImageIO.setUseCache(false);
if(allmymusic.get(i).albumImageData != null){
BufferedImage bImage;
try(ByteArrayInputStream bis = new ByteArrayInputStream(data)) {
bImage = ImageIO.read(bis);
}
ImageIcon icon = new ImageIcon(bImage);
Image image = icon.getImage().getScaledInstance(50, 50, Image.SCALE_SMOOTH);
// ImageIcon iconscaled = new ImageIcon(image);
albumArt[i] = image;
} else {
albumArt[i] = null;
}
}
return albumArt ;
}
#Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
ImageIcon icon = new
ImageIcon(getClass().getResource("/images/defaultimage.png"));
Image image = icon.getImage().getScaledInstance(50, 50, Image.SCALE_SMOOTH);
Image[] albumArt;
try {
albumArt = getAlbumart();
if(albumArt[row] == null){
lbl.setIcon(new ImageIcon(image));
} else {
lbl.setIcon(new ImageIcon(albumArt[row]));
}
} catch (IOException ex) {
Logger.getLogger(ImageCellRenderer.class.getName())
.log(Level.SEVERE, null, ex);
}
return lbl;
}
}
I accept alternative solutions.
On a first glimpse, I deem it unnecessary instantiating a ImageIcon object to get a scaled image of the BufferedImage, since that can be done directly from the BufferedImage itself:
Image image = bImage.getScaledInstance(50, 50, Image.SCALE_SMOOTH);
A second smell lies in this line:
ImageIcon icon = new ImageIcon(getClass().getResource("/images/defaultimage.png"));
Image image = icon.getImage().getScaledInstance(50, 50, Image.SCALE_SMOOTH);
Since the image is being read from a constant static resource, you should avoid repeating performing the same operation again and again: Better read the resource and build the image just once, and store it in a static variable:
private static final Image MY_STATIC_ICON=readStaticIcon();
private static Image readStaticIcon()
throws IOException
{
ImageIcon icon = new ImageIcon(MyClass.class.getResource("/images/defaultimage.png"));
Image image = icon.getImage().getScaledInstance(50, 50, Image.SCALE_SMOOTH);
return image;
}
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
Image image = MY_STATIC_ICON;
Image[] albumArt;
try {
albumArt = getAlbumart();
...
why you always instantiate a new ImageIcon like this, can't you use one instance:
#Override
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected,
boolean hasFocus, int row, int column) {
ImageIcon icon = new
ImageIcon(getClass().getResource("/images/defaultimage.png"));
Image image = icon.getImage().getScaledInstance(50, 50, Image.SCALE_SMO
2.This is very processor expensive , can you create thubnails and load ready images instead of generating it on the fly like this:
Image image = icon.getImage().getScaledInstance(50, 50, Image.SCALE_SMOOTH);
Do you really need to load everything in single method "public Image[] getAlbumart()",
can't you make it so it loads the images when they are needed to be displayed? Probable you could use a SwingWorker https://docs.oracle.com/javase/7/docs/api/javax/swing/SwingWorker.html
There is great book that will help you to desing and use Swing GUI in java: Filthy Rich Clients: Developing Animated and Graphical Effects for Desktop Java¿ Applications
Your_JTable.getColumnModel().getColumn(0).setCellRenderer((JTable jtable, Object value, boolean bln, boolean bln1, int i1, int i2) -> {
JLabel label = new JLabel();
label.setIcon((ImageIcon) value);
return label;
});
With this the trick should be done. It just sets the selected column to Have a JLabel inside of it with an imageIcon. Thank you #camickr for suggesting the solution.

Java Constructor with ImageIcon

I created a small program that inserts an ImageIcon (resized in another class) into a JLabel through a constructor
I am struggling to return the icon in the JLabel
Here's my code:
Main Class:
traforma imageObj = new traforma("image1.png"); //traforma is another class
ImageIcon Icon11 = new ImageIcon(imageObj.Icon11);
imageLabel.setIcon(Icon11); //Here he gives me error, he can't find my ' Icon11 '
traforma Class:
public class traforma {
public traforma(String image) {
ImageIcon Icon1 = new ImageIcon(getClass().getClassLoader().getResource(image));
Image image = Icon1.getImage();
Image newimg = image.getScaledInstance(470, 360, java.awt.Image.SCALE_SMOOTH);
ImageIcon Icon11 = new ImageIcon(newimg);
}
Object Icon11 = this.Icon11; // i guess the problem is here
}
I am new to Java,
Hope I have been clear
This code makes no sense:
Object Icon11 = this.Icon11;
The problem is, that the variable "Icon11" that you initialized within the method is not used anywhere. After method completed, it will be thrown away. What you can do, is to assign the created icon object to the member variable, not to the local variable.
Thy style of your code is not perfect: the usage of lower and upper case, the usage of ImageIcon instead of directly loading image, etc. But if we keep it as close to your code as possible and try to do minimal changes, the working code may look as follows:
public class traforma {
public traforma(String image) {
ImageIcon Icon1 = new ImageIcon(getClass().getClassLoader().getResource(image));
Image image = Icon1.getImage();
Image newimg = image.getScaledInstance(470, 360, java.awt.Image.SCALE_SMOOTH);
this.Icon11 = new ImageIcon(newimg);
}
public ImageIcon Icon11;
}

Java - cover all JButtton size with ImageIcon

How do I cover all my JButton with the ImageIcon given?
my JButtoon size is 90x90 and my Image as well
I also set a text to my JButton (the text is necessary for the program to work)
Code: (I get a padding inside mi button)
btnBoton[i][j].setText(Integer.toString(i)+","+Integer.toString(j));
btnBoton[i][j].setIcon(new ImageIcon("img//"+num+".jpg"));
(When I comment my setText):
//btnBoton[i][j].setText(Integer.toString(i)+","+Integer.toString(j));
btnBoton[i][j].setIcon(new ImageIcon("img//"+num+".jpg"));
I'm trying to acomplish as the second image but without commenting my setText
you can use these two methods to place text at the center of buttons
btnBoton[i][j].setHorizontalTextPosition(JButton.CENTER);
btnBoton[i][j].setVerticalTextPosition(JButton.CENTER);
and texts will be placed in center of buttons,
if you want to assign a value to buttons and don't showing any text, instead of .setText(),create a new class like MJButton which extends JButton and create a String field to it named tag or data or etc. then encapsulate the field and use .setTag() and .getTag() to do so.
class MJButton extends JButton {
private String tag;
public MJButton(String tag, Icon icon) {
super( icon);
this.tag = tag;
}
public MJButton() {
super();
}
public String getTag() {
return tag;
}
public void setTag(String tag) {
this.tag = tag;
}
}
so use this new class to create buttons, in two ways:
1: btnBoton[i][j] = new MJButton();
and call .setTag() for them:
btnBoton[i][j].setTag(Integer.toString(i)+","+Integer.toString(j));
2: assign icon and tag to button in one line using second constructor
btnBoton[i][j] = new MJButton((Integer.toString(i)+","+Integer.toString(j)), new ImageIcon("img//"+num+".jpg"));

Specify required text in jTextField based on icon set to jLabel?

I am working on a simple image guessing game. Instead of having a jLabel for each image, I'm using only one jLabel and it changes its icon using arrays when a button is clicked after the image has been guessed correctly.
But how can I code it so that the answer required in the jTextField (txtAnswer) is determined by the icon set in the jLabel?
So for instance, if the current icon is of the Aston Martin DBS and the user guesses correctly, the icon will then change to the Ferrari 458. What must I do then to ensure that the txtAnswer will now require the user to enter "Ferrari 458" to guess correctly based on the image icon that is set?
Here is the code I currently have:
private static String[] imageList = {"/carGuessPackage/2010 Aston Martin DBS.jpg", "/carGuessPackage/2010 Ferrari 458 Italia.jpg"};
//This method is called in the constructor to set the first image on startup
public void firstIcon()
{
ImageIcon image;
image = new javax.swing.ImageIcon(getClass().getResource(imageList[0]));
lblImage.setIcon(image);
}
private void btnCheckActionPerformed(java.awt.event.ActionEvent evt) {
ImageIcon image;
if(imageList[0].equals(true))
{
if("Aston Martin DBS".equals(txtAnswer.getText()))
{
image = new javax.swing.ImageIcon(getClass().getResource(imageList[1]));
lblImage.setIcon(image);
}
else
{
JOptionPane.showMessageDialog(this, "Incorrect");
}
}
}
Check out the JLabel.setIcon() method. You would need and array of Icon objects, and they would be passed to the existing JLabel.

I want to simplify things in my Java program

I made a game using NetBeans design tool, called WordHunt. It looks like this:
I need to make a class that will apply a mouseover effect to those 16 labels I have. This is the code that changes the icon B when enter the mouse:
private void b1MouseEntered(java.awt.event.MouseEvent evt) {
b1.setIcon(new javax.swing.ImageIcon(getClass().getResource("/ip/imag/" +B+ ".png")));
}
I had applied a default icon to the label.
After making that class, instead of writing:
b1.setIcon(new javax.swing.ImageIcon(getClass().getResource("/ip/imag/" +B+ ".png")));
to write className(b1 ,B);
For the next label, the same thing
className(b2 ,C);
Observation: b1 is a label and I have all letters icon in .png format from A to Z.
Can anybody give me an idea of how I can do that?
If I understand what you want to do, you can use this method:
public void setRolloverIcon(Icon rolloverIcon)
defined in the class JButton to configure the rollover icon.
Just create a simple class like this:
class HoverEffectButton extends JButton{
HoverEffectButton(Image img1, Image img2) {
super(new ImageIcon(img1));
this.setRolloverIcon(new ImageIcon(img2));
}
}
Hope this will help.
And of course you can create a helper class that permits to load an image according to the image name
class AssetsHelper{
private static final String DEFAULT_ASSETS_ROOT = "assets/";
private static final String DEFAULT_IMAGE_SUBFIX = ".png";
public static Image loadImage(String name){
BufferedImage img = null;
try {
img = ImageIO.read(new File(DEFAULT_ASSETS_ROOT + name + DEFAULT_IMAGE_SUBFIX));
} catch (IOException e) {
....
}
return img;
}
}
How about something like this: (rough draft)
// for storage so we don't load it for each mouse-over
HashMap<String, ImageIcon> images = new HashMap<String, ImageIcon>();
void setIcon(JLabel button, String image)
{
if (images.containsKey(image))
return images.get(image);
else
{
String path = "/ip/imag/" + image + ".png";
ImageIcon icon = new ImageIcon(getClass().getResource(path));
images.put(image, icon);
return icon;
}
}
And then:
setIcon(b1, "B");
But you should probably consider using buttons so you can use setRolloverIcon rather than MouseEntered.
public class MyButton extends JButton {
private ImageIcon normalIcon;
private ImageIcon hoverIcon;
public MyButton(String normalURL) {
String hoverURL = normalURL.replaceFirst("\\.png$", "-hover.png");
normalIcon = new ImageIcon(getClass().getResource("/ip/imag/" +B+ ".png"); // or so
hoverICon = ...
}
private void b1MouseEntered(MouseEvent evt) {
setIcon(hoverIcon);
}
}
Firstly at the top of your code add this import:
import javax.swing.ImageIcon;
//Then you only need to write
new ImageIcon(...);
Instead of:
new javax.swing.ImageIcon(...)
Already shorter :)
Then you can create a hashmap of the images preloaded where each instance of B is the key and the loaded icon is the value.
if i get u well i think you want just an image and not evry image to chang when mouse is on it right. if that is the case what u should do is to get the position of each image in a buffer and compare it with the mouse x n y position to know wc image to change. I hope this solve your problem

Categories

Resources