I want to be able to do something similar to resize canvas in gimp
I want to generate a bunch of images to a certain width.
I used
int width = (int)(size * fraction);
int height =(int)(size*icon.getIconHeight()/icon.getIconWidth()*fraction);
miniature = new ImageIcon(i.getScaledInstance(width, height, Image.SCALE_SMOOTH));
this goes well while I'm doing fraction 1 but I have 3 images that have the same source but are different size (1, 2/3, 1/3)
the problem is
I have and image A
I want to create B, C and D such as the drawing inside respect the follow ratio
B = A
C = 2/3 A
D = 1/3 A
but the image stays the same dimension A = B = C = D
Assuming I'm following what you are trying to do...
Create a JLabel for each image:
JLable l = new JLabel(miniture);
Create a JLabel with a GridLayout:
JPanel p = new JPanel(new GridLayout());
Add the labels to the panel:
p.add(l);
The GridLayout will ensure that all the JLabels will have the same height and width.
Related
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);
}
}
I'm trying to fill a JPanel with a neat grid containing as many JLabels as will fit into the JPanel. The size of the JPanel can vary, and the size of the JLabels depends on the label text, the icon included in the JLabel, and the font being used to render the label text.
GridLayout myLayout = new GridLayout();
JPanel myPanel = new JPanel(myLayout);
List<JLabel> myLabels = ...
int panelWidth = myPanel.getWidth();
int panelHeight = myPanel.getHeight();
if (panelWidth == 0 || panelHeight == 0) return;
int maxLabelWidth = 0, maxLabelHeight = 0;
for (JLabel label : myLabels) {
int labelWidth = ???
int labelHeight = ???
if (labelWidth > maxLabelWidth) maxLabelWidth = labelWidth;
if (labelHeight > maxLabelHeight) maxLabelHeight = labelHeight;
}
// Use panelHeight, panelWidth, maxLabelHeight and maxLabelWidth to compute
// rows and columns available for myLayout
myLayout.setRows(nRows); myLayout.setColumns(nColumns);
for (JLabel label : myLabels) {
myPanel.add(label);
// stop if we reach nRows*nColumns labels
}
I've tried myPanel.getGraphics().getFontMetrics().getHeight() to get the height of text, but when the font is large and myPanel is small, the text is taller than labelHeight, and the bottom and top get cut off.
I've tried label.getIcon().getIconHeight() to get the height of the icon, but using this value always cuts off the top and bottom of the icons.
I've tried label.getSize() to get the height and width of the JLabel, but that usually returns 0 height and 0 width. I've tried label.getPreferredSize() but that generally returns a value that's too small.
I've tried label.getGraphics().getFontMetrics().stringWidth(label.getText()) to get the width of the string, and then added that to label.getIcon().getIconWidth() and label.getIcon().getIconTextGap() but that comes up with a value a little larger or smaller than label.getPreferredSize(), and in any case still too small - sometimes the label text is cut off at the end.
At one point I tried adding a constant to each width and height; that prevented cut-off text and icons, but of course it left too much blank space around the JLabels. Is there a way to get an accurate size for each JLabel for this usage?
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);
I want to know how to nest JPanels using a GridLayout. This is how it should look like.
I approached this problem by 2 ways so far,
using JPanels and
using JLabels,
and none of them worked (only the first panel created is shown).
Here is the code for the JPanel approach:
int x=20, y=20;
JPanel [] panels = new JPanel[3];
JLabel animal = new JLabel(new ImageIcon(getClass().getResource("Pictures/animal.gif")));
JLabel map = new JLabel(new ImageIcon(getClass().getResource("Pictures/map.gif")));
JLabel mountain = new JLabel(new ImageIcon(getClass().getResource("Pictures/mountain.gif")));
for(int i=0;i<panels.length;i++)
{
if(i>0)
{
x+=x;
y+=y;
}
panels[i] = new JPanel(new GridLayout(2,2));
panels[i].setPreferredSize(new Dimension(x,y));
if(i==0)
panels[i].add(new JPanel());
else
panels[i].add(panels[i-1]);
panels[i].add(mountain);
panels[i].add(map);
panels[i].add(animal);
}
add(panels[2]);
One option is to create a class that will represent a panel divided into the grid with the images. The only issue would be the top left quadrant which would usually contain the nested panel, at some point you want this to contain just a blank panel. So maybe something like this (barring various optimizations):
class GridPanel extends JPanel{
JLabel mountain, map, animal;
public GridPanel(JPanel panel){
super();
setLayout(new GridLayout(2, 2));
animal = new JLabel(new ImageIcon(getClass().getResource("pictures/animal.gif")));
map = new JLabel(new ImageIcon(getClass().getResource("pictures/map.gif")));
mountain = new JLabel(new ImageIcon(getClass().getResource("pictures/mountain.gif")));
add(panel);
add(mountain);
add(map);
add(animal);
}
}
Notice that it accepts the panel that is to be displayed in the top left corner of the grid. This coud then be called with the panel specified. So at the point where you want to create the main panel:
JPanel grid = new GridPanel(new JPanel()); //initial
for(int i = 1; i <= 5; i++){
grid = new GridPanel(grid);
}
add(grid);
The initial grid is created with a blank JPanel. And every subsequent grid will contain the previous one as the top left panel. You have to resize your images and such and maybe even avoid loading the images multiple times etc. But that is another question. This example shows 5 nested panels.
Just to be clear, you should use ImageIO to load the images once and reuse the images. For example You can create a BufferedImage like this in your main class:
BufferedImage mointainImg = ImageIO.read(new File("pictures/mountain.gif"));
And when you want to create the JLabel you can do this:
mountain = new JLabel(new ImageIcon(mountainImg));
And the advantage is that you can manipulate the image a bit if you want.
One issue that you have is that the images are not scaled. To scale images, use Image.getScaledInstance(). Proper scaling would at least fix the problem of the visible images being cut off. It also might cause the other images to be shown as they might just be hiding behind the visible images because they are too big.
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.