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.
Related
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);
Is there a way to "ignore" weather the text of a button fits or not so in the case it doesn't fit, it doesn't display "..."?
I'm making a game that has a grid of buttons and I'm using the chess unicode characters as the text on these buttons. With small fonts they show up but they are really small. But with larger fonts, java "thinks" they wont fit and displays them as "..." even thought they would definitively fit.
The code that generates the buttons:
jPanel.setLayout(new GridLayout(13, 13));
tab = new JButton[13][13]; //Tablero
for (int j = 0; j <= 12; j++) {
for (int i = 0; i <= 12; i++) {
JButton jButton = new JButton();
jButton.setText("♟");
jButton.setBackground(getColor(i, j));
jPanel.add(jButton);
tab[i][j] = jButton;
//jButton.setFont(new Font("TimesRoman", Font.PLAIN, 14));
jButton.setForeground(Color.pink);
}
}
If you see "..." it means that the size of the component is too small to display the text properly. This means you are overriding some property of the button:
You are using a null layout and manually specifying the size
You are using a layout but you have used setPreferredSize()
In these cases the button will not paint properly.
You can have the chess piece occupy more space of the button by changing the margin of the button:
JButton button = new JButton(...);
button.setMargin( new Insets(5, 5, 5, 5) );
but you still have to fix one of the above two problems so that you are using Swing layouts properly.
So i'm creating an array of buttons that is supposed to display and 8,8 grid, instead it displays very small buttons spreading across the window (31 buttons in a row for two rows then two more buttons on the third). If I replace:
gamePanel1.add(buttons[a][b]);
with:
frame.add(buttons[a][b]);
... it display correctly but when initialising the array, I have to resize the window to see the buttons as it does not fit to contents.
Here is the code to create the buttons:
contentPane.setLayout(new BorderLayout());
JPanel gamePanel1 = new JPanel();
buttons = new JButton[boardsize][boardsize];
mineBoard = new int[9][9];
for (int a = 0; a < boardsize; a++)
for (int b = 0; b < boardsize; b++) {
buttons[a][b] = new JButton("");
buttons[a][b].setBounds(30+gridsize*a,30+gridsize*b,gridsize,gridsize);
gamePanel1.add(buttons[a][b]);
buttons[a][b].addMouseListener(new MouseListener(a,b));
setx(a);
sety(b);
settried(false);
setmine(false);
}
contentPane.add(gamePanel1, BorderLayout.CENTER);
Can anyone tell me how I might fix this or show me how with this code I may use a different layout - i tried grid layout for the buttons but could not get it working at all.
First create a Panel as:
JPanel panel=new JPanel();
Then set the layout as
panel.setLayout(new GridLayout(8,8));
Then using a for loop create and add the buttons and the buttons will be displayed in eight by eight grid. Thanks.
I'm creating a simple Minesweeper game in Java. Size 9x9.
I create an array of JPanels and an array of buttons; I add each button to its respective JPanel. then i add the JPanels to the JFrame.
How do i distinguish between each button on the action event?
Here's some of my code:
int gridx = 9;
int gridy = 9;
JButton[] buttons = new JButton[gridx*gridy];
JPanel[] jpanels = new JPanel[gridx*gridy];
public Minesweeper(){
super("Minesweeper");
setLayout(new GridLayout(9,9));
JPanel panel = new JPanel();
int i = 0;
for(i = 0; i<gridx*gridy; i++){
jpanels[i] = new JPanel();
buttons[i] = new JButton();
buttons[i].addActionListener(buttonEvent);
jpanels[i].setLayout(new GridLayout(1,1));
jpanels[i].add(buttons[i]);
add(jpanels[i]);
}
//buttons[67].setEnabled(false);
setSize(300,300);
setVisible(true);
}
The only way i can think about doing this is adding text to the button like so:
buttons[i] = new JButton(i);
Then calling getActionCommand() but i dont want text to show up on the button. Any other ideas?
You can use AbstractButton#setActionCommand.
In your loop:
buttons[i].setActionCommand(i+"");
Then you'll get i back when you use getActionCommand
Note I did mention in a comment on another answer that I would create a new class Mine which extends JButton which I believe to be a better and more complete solution. This however gets the job done rather quickly.
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.