Fit setIcon to JButton Array - java

I know this has been asked a ton of times, but I've searched everywhere and still haven't found an answer. I'm relatively new to Java. I have
JButton b[][];
Later, I assign b[3][3].setIcon(path). However, the image at path is always a small section of the actual image the size of the JButton. What I want is to re-size the image to fit the size of the JButton. Is there any way to do this? By the way, here's some code that's (I think) is important:
int n = 8;
int m = 8;
...
b = new JButton[n][m];
setLayout(new GridLayout(n,m));
for (int y = 0;y<m;y++){
for (int x = 0;x<n;x++){
b[x][y] = new JButton(" ");
b[x][y].addActionListener(this);
add(b[x][y]);
b[x][y].setEnabled(true);
}
}

What I want is to re-size the image to fit the size of the JButton.
You can use the Stretch Icon class.
It will allow you to automatically resize the Icon:
to fill the space of the button, or
keep the Icon proportion and fill the space of the button
The resizing is done dynamically so you don't need scaled images.

What you obviously need is a Icon Resizer method, something in the way of what I have provided below:
public static Icon resizeIcon(ImageIcon icon, int resizedWidth, int resizedHeight) {
Image img = icon.getImage();
Image img = img.getScaledInstance(resizedWidth, resizedHeight, java.awt.Image.SCALE_SMOOTH);
return new ImageIcon(img);
}
You can call this method after the image has already been applied to the JButton and after it has been added to whatever panel:
b[3][3].setIcon(path)
b[3][3].setIcon(resizeIcon((ImageIcon) b[3][3].getIcon(),
b[3][3].getWidth() - 15, b[3][3].getHeight() - 15));
or you could do it this way:
ImageIcon img = new ImageIcon("MyImage.png");
Icon icn = resizeIcon(img, b[3][3].getWidth() - 15, b[3][3].getHeight() - 15);
b[3][3].setIcon(icn);

Related

How to make my JFrame components dynamically scale when resizing the window, without hard-coding position and size values?

I'm learning java through university and I've been taught the basics of making a java program and designing GUIs. Maximizing a window after running my program makes all the JFrame components stay in place while grey fills the rest of the space. Here's an example of how it looks like:
JFrame window normally, Maximized window before "fix".
After failing to find a solution I came up with a band-aid solution which is to get the component locations and just move them with hard-coded values when the jframe is maximized. This was not an elegant solution and every jframe in my java course project increased in the number of elements on screen. Is there any piece of code to make my components move and resize automatically and dynamically?
Here's what I've tried so far:
First I obtained the positions of components through 2D points:
Point managementLoginBtnLocation, empLogLocation, logoLocation, customerBtnLocation, welcomeLblLocation, contactBtnLocation, aboutBtnLocation, mainMenuBtnLocation;
//Constructor and rest of code...
public final void getOriginalComponentLocations()
{
managementLoginBtnLocation = managementLoginBtn.getLocation();
empLogLocation = empLoginBtn.getLocation();
logoLocation = shopLogo.getLocation();
customerBtnLocation = customerBtn.getLocation();
welcomeLblLocation = welcomeLbl.getLocation();
contactBtnLocation = contactBtn.getLocation();
aboutBtnLocation = aboutBtn.getLocation();
mainMenuBtnLocation = mainMenuBtn.getLocation();
}
//This method is called within the constructor.
I implemented the ComponentListener Interface and added a component listener to my jframe. Then I made it so when the jframe's size changes, it changes the size of the jlabel used for background art. And if the label's width is greater than 800 (the default I used while designing) it moves the components and doubles their size and font size. When the jframe is minimized the label will go back to the default size so I made a method to revert the font sizes, because I found the component sizes and locations reset automatically.
public void componentResized(ComponentEvent e)
{
//Resizing the background label and setting its icon to a resized version of its current icon.
backgroundMainArt.setSize(this.getWidth() - 16, this.getHeight() - 21);
ImageIcon icon = new ImageIcon("C:\\Program Files\\OMOClothingStore\\Resources\\Main menu\\main menu background art.jpg");
Image img = icon.getImage();
Image newImage = img.getScaledInstance(backgroundMainArt.getWidth(), backgroundMainArt.getHeight(), Image.SCALE_FAST);
icon = new ImageIcon(newImage);
backgroundMainArt.setIcon(icon);
if(backgroundMainArt.getWidth() > 800) //When the size of the label is greater than default
{
//I move the components, enlarge the buttons and zoom the font size
moveComponents();
enlargeBtns();
zoomBtnsFontSize();
}
else //When the label is back to its original size
{
//I revert the font sizes as button sizes and positions reset automatically
revertBtnsFontSize();
setLogoIconAndBackgroundArtAndWelcomeLbl();
}
}
public void moveComponents()
{
moveLogo();
moveManagementLoginBtn();
moveEmployeeLoginBtn();
moveCustomerBtn();
moveWelcomeLbl();
moveContactInfoBtn();
moveAboutBtn();
moveMainMenuBtn();
}
public void moveLogo()
{
ImageIcon logoIcon = new ImageIcon("C:\\Program Files\\OMOClothingStore\\Resources\\Shared resources\\OMO Clothing Store logo.png");
Image logoImg = logoIcon.getImage();
Image newLogoImage = logoImg.getScaledInstance(250, 250, Image.SCALE_DEFAULT);
logoIcon = new ImageIcon(newLogoImage);
shopLogo.setIcon(logoIcon);
Point newLogoLocation = new Point();
newLogoLocation.x = (logoLocation.x * 2) + 200;
newLogoLocation.y = (logoLocation.y * 2) + 30;
shopLogo.setLocation(newLogoLocation);
}
//The rest of the "moveX" methods follow the same pattern as moveLogo()
public void enlargeBtns()
{
managementLoginBtn.setSize(410, 94);
empLoginBtn.setSize(410, 94);
customerBtn.setSize(410, 94);
}
public void zoomBtnsFontSize()
{
customerBtn.setFont(sizeBtn.getFont());
//sizeBtn is a JButton that has a font size of 24. I found that just creating a new Font object with bigger size here made the font way larger for some reason.
empLoginBtn.setFont(sizeBtn.getFont());
managementLoginBtn.setFont(sizeBtn.getFont());
}
public void revertBtnsFontSize()
{
empLoginBtn.setFont(new Font("Segoe UI", Font.PLAIN, 14));
managementLoginBtn.setFont(new Font("Segoe UI", Font.PLAIN, 14));
customerBtn.setFont(new Font("Segoe UI", Font.PLAIN, 14));
}
I split the moving of the components into many methods inside other methods because I found it easier to keep up with.
This worked. Here's how it looks like when running the JFrame: Maximized window after "fix". But moving on to other JFrames, they are more intricate and have many more components - extra buttons, panels with other components in them, menu bars, etc.
Is there a better approach to fixing this? Or do I just remove the ability to resize and move on?

How can I get my JLabel Icon Images to be high resolution?

I want to make an application with a small jLabel(50x50) in its corner.
The Problem I now have is that the Image the Label displays is looking really bad.
I also added the same Image as an Icon to a shortcut in windows on my desktop just as a comparison.
Windows on the left side and Java JLabel on the right.
How can I archive a similar scaling result in Jave with no loss in quality?
It does not need to use JLabel.
Code:
ImageIcon imgIcon = new ImageIcon(path);
Image img = imgIcon.getImage();
Image imgScaled = img.getScaledInstance((int) (getWidth()), (int) (getHeight()),
Image.SCALE_SMOOTH);
ImageIcon image = new ImageIcon(imgScaled);
label.setIcon(image);
EDIT:
If you look at these Google Chrome Icons, they are extremely tiny but still sharp and high resolution, how can I archive this in Java?
Your can to use in BufferedImage, this is much higher resolution the JLabel.
You can to create BufferedImage from .png file with ImageIO class.
I see two options, or maybe a combination of this:
You're using a weird resolution image for your ImageIcon
Ratio of width to height is not equal, thus skewed scaling
EDIT In case 2, make sure the JComponent you're using to fetch dimensions from (the one you're calling getWidth and getHeight on) has equal dimensions for both width and height.
I cut your left image, at 62px width/height. First row shows that image scaled, second row shows what happens when I scale the source image down to 32px in graphics program first:
Dimensions, as you can see below, go from 62px up by increments of 10px. Code was run on Java 1.8, Windows 10:
void addSeries(Image srcImg, JPanel targetPanel) {
for (int i = 0; i < 50; i += 10) {
int dimension = 62 + i;
Image imgScaled = srcImg.getScaledInstance(dimension, dimension, Image.SCALE_SMOOTH);
ImageIcon scaledIcon = new ImageIcon(imgScaled);
JLabel label = new JLabel();
label.setIcon(scaledIcon);
targetPanel.add(label);
}
}

How to input a different value in each space on a grid

Hey im new to java in grade 10 and I came through a small problem. I'm creating the game 4 pics on word and I can't seem to put a different image in each square of my grid.
Here is the grid
The decleration:
int row = 4;
int col = 4;
JButton a[] = new JButton [row * col];
And here's the array:
card4 = new Panel ();
Panel g = new Panel (new GridLayout (row, col));
for (int i = 0 ; i < a.length ; i++)
{
a[i] = new JButton ("Hi");
a[i].setPreferredSize (new Dimension (50,50));
g.add (a[i]);
}
How would I call out each individual button on the grid and assign a different image to it?
When you run new JButton("Hi"), you are invoking (one of) the constructor(s) for the class. JButton has several different constructors taking different parameters. One of those constructors is JButton(String text, Icon icon), that allows specifying an Icon to draw in the button. So, first you would have to create an Icon and then create the button using it, like:
Icon icon = new ImageIcon("name/of/file/containing/icon/image");
a[i] = new JButton("Button Text", icon);
If you only want an icon and no text, then just use:
Icon icon = new ImageIcon("name/of/file/containing/icon/image");
a[i] = new JButton(icon);
The file containing the image can be a jpg, png, gif. Look in Java Tutorial on now to use images and controls.

Setting JButton Icon

I want a JButton to have an icon on it. So far I have this.
ImageIcon ii = new ImageIcon("Button.png");
width = ii.getIconWidth();
height = ii.getIconHeight();
Toolkit tk = Toolkit.getDefaultToolkit();
windowW = (int) tk.getScreenSize().getWidth();
windowH = (int) tk.getScreenSize().getHeight();
play = new JButton("Play");
play.setSize(width, height);
play.setLocation(windowW / 2 - 165,windowH / 2 - 165);
play.setIcon(ii);
play.addActionListener(this);
It get the icon's width and height and then set the JButton to the icon's width and height but for some reason the icon will be a little to the left so that you still can see some of the JButton's default texture. This is an image of how it looks like:
How would I make it so that the image covers the whole JButton like it's supposed to?
This is because you add Play text to the button like that new JButton("Play");
if you delete Play you will see
image covers the whole JButton

How to get the coordinate of Gridlayout

I set my JPanel to GridLayout (6,6), with dimension (600,600)
Each cell of the grid will display one pictures with different widths and heights.
The picture first add to a JLabel, and the JLabel then added to the cells.
How can retrieved the coordinate of the pictures in the cells and not the coordinate of cells? So far the out give these coordinate which equal height and width even on screen the pictures showed in different sizes.
e.g.
java.awt.Rectangle[x=100,y=100,width=100,height=100]
java.awt.Rectangle[x=200,y=100,width=100,height=100]
java.awt.Rectangle[x=300,y=100,width=100,height=100]
The reason why I used GridLayout instead of gridBagLayout is that, I want each pictures to have boundary. If I use GridBagLayout, the grid will expand according to the picture size.
I want grid size to be in fix size.
JPanel pDraw = new JPanel(new GridLayout(6,6));
pDraw.setPreferredSize(new Dimension(600,600));
for (int i =0; i<(6*6); i++)
{
//get random number for height and width of the image
int x = rand.nextInt(40)+(50);
int y = rand.nextInt(40)+(50);
ImageIcon icon = createImageIcon("bird.jpg");
//rescale the image according to the size selected
Image img = icon.getImage().getScaledInstance(x,y,img.SCALE_SMOOTH);
icon.setImage(img );
JLabel label = new JLabel(icon);
pDraw.add(label);
}
for(Component component:components)
{
//retrieve the coordinate
System.out.println(component.getBounds());
}
EDITED: I have tried this but not working :-(
for(Component component: pDraw.getComponents()){
System.out.println(((JLabel)component).getIcon());
}
How can I get output like these?
java.awt.Rectangle[x=300,y=100,width=50,height=40]
java.awt.Rectangle[x=400,y=400,width=60,height=50]
Do your images appear at the desired size ?
i think so.
Anyway, from what your code seems to do, I guess it gets the labels size, and not the icons size. JLabel, like any JComponent, are in fact Container instance. As such, their size depends upon constraints. As a consequence, in a GridLayout, a JLabel will have the size of a cell, whereas the contained Icon will have the size of the image.
As a consquence, to get image size, you have to call ((JLabel) component).getIcon() to be able to retrieve effective image dimension.

Categories