Add image in a GridLayout of Labels with resizing - java

I am new to Java and I want to make a simple game of chess perhaps later will add sockets. First I wanted to start designing the board to which use GridLayout JLabel as shown . My problem is that I want to add to each Label an image to simulate the " chip " of the game but do not know how, I tried many things but does not leave me, I want help please.
This code generated my table of 8x8
public class Ventana extends javax.swing.JFrame {
private static final int COLUMNAS = 8;
private static final int FILAS = 8;
public Ventana() {
initComponents();
ImageIcon fNegra = new ImageIcon("Images/FichaNegra.png");
ImageIcon fRoja = new ImageIcon("Images/FichaRoja.png");
jPanel1.setLayout(new GridLayout(FILAS, COLUMNAS));
JLabel [][] jLabel = new JLabel[FILAS][COLUMNAS];
for (int i=0;i<FILAS;i++)
for (int j=0;j<COLUMNAS;j++)
{
jLabel[i][j] = new JLabel();
jLabel[i][j].setOpaque(true);
if((i+j)%2 == 0)
{
jLabel[i][j].setBackground(Color.WHITE);
jPanel1.add(jLabel[i][j]);
}
else
{
jLabel[i][j].setBackground(Color.GRAY);
jPanel1.add(jLabel[i][j]);
}
}
this.add(jPanel1);
this.setVisible(true);
}

Related

Unable to show JTable in JPanel from dynamically retrieved data

I haven't been able to show a JTable inside a JPanel from dynamically generated data. I have even tried adding a layout manager so that I don't end up with a null layout manager and no table. Here is the code I'm using.
public void setReferencePanel(ArrayList<Item> items, String refFile) {
String[] columns = {"first", "last"};
String[][] data = {{"Adam", "Smith"}, {"Jon", "Bon Jovi"},{"John", "Doe"}};
JTable sample = new JTable(data, columns);
refListingPanel.add(sample);
refListingPanel.setBorder(BorderFactory.createTitledBorder("Reference File - " + refFile));
}
and earlier in the same file.
private JMenuBar menuBar;
private JPanel testListingPanel;
private JScrollPane testScroller;
private JPanel refListingPanel;
private JScrollPane refScroller;
private static Dimension listingDefault = new Dimension(350, 230);
private IDiffPresenter presenter;
private boolean allItems;
private boolean unChangedItems;
private boolean changedItems;
private JTable refTable;
private JTable testTable;
public MasterFrame (IDiffPresenter presenter) {
super("Magic Diff - Under Construction");
this.presenter = presenter;
menuBar = new JMenuBar();
setupFileMenu(presenter);
setupExportMenu(presenter);
setupDisplayChangedMenu();
setupAboutMenu();
setupReferencePanel();
setupTestPanel();
getContentPane().setLayout(new GridLayout(1,2));
setJMenuBar(menuBar);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize((int)listingDefault.getWidth() + 10, (int)listingDefault.getHeight() + 60);
Dimension DimMax = Toolkit.getDefaultToolkit().getScreenSize();
this.setMaximumSize(DimMax);
this.setExtendedState(JFrame.MAXIMIZED_BOTH);
...
}
private void setupReferencePanel() {
refListingPanel = new JPanel();
refListingPanel.setLayout(new BorderLayout());
refListingPanel.setBorder(BorderFactory.createTitledBorder("Reference File"));
refScroller = new JScrollPane(refListingPanel);
getContentPane().add(refScroller);
}
What am I missing or failing to do? I have even tried some sample data, what is currently in the code, and I get the same issue.
This is based on what cmickr and Andrew Thompson posted. I modified the following functions to work.
public void setReferencePanel(ArrayList<Item> items, String refFile) {
DefaultTableModel model = new DefaultTableModel(vectorize(items), makeHeaderVector());
refTable.setModel(model);
refListingPanel.setBorder(BorderFactory.createTitledBorder("Reference File - " + refFile));
}
private Vector vectorize(ArrayList<Item> items) {
Vector results = new Vector();
for (int i = 0; i < items.size(); i++) {
results.addElement(items.get(i).vectorize());
}
return results;
}
private Vector makeHeaderVector() {
String[] cols = { ... }; // hid application specific string array
Vector<String> results = new Vector<String>(Arrays.asList(cols));
return results;
}
This is my basic understanding of vectors, since I do not use them much. Also, this may not be the fastest way of approaching the problem, but my first goal is to get it working, then improve it. The important part was to use a TableModel, in my case DefaultTableModel, and then setModel() of the the JTable to the new model, like was referenced.

How to assign or initiate an integer into JButton?

package javaapplication3;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
class BattleShip2 extends JFrame implements ActionListener {
JButton[][] array2dtop = new JButton[10][10];
BattleShip2(String title) { //Board Display
super(title);//show Title
setLayout(new FlowLayout()); // button posistion
for(int x = 0; x < array2dtop.length; x++) {
for(int y = 0; y < array2dtop.length; y++) {
array2dtop[x][y] = new JButton(String.valueOf((x * 10) + y)); //display
array2dtop[x][y].setBounds(20,40,140,20);
array2dtop[x][y].setActionCommand("x"); //itself value
array2dtop[x][y].addActionListener(this);
add(array2dtop[x][y]);
}
}
}
public void actionPerformed(ActionEvent evt) { //operation
String cmd = evt.getActionCommand();
if(cmd == "x") {
System.out.println("x");
}
}
}
public class pratice3 {
public static void main(String[] args) {
BattleShip2 board = new BattleShip2("BattleShip");
board.setSize(500, 400);
board.setLocation(250, 250);
board.setDefaultCloseOperation(board.EXIT_ON_CLOSE); //Press x to EXIT
board.setVisible(true);
}
}
Hi, i am creating a battleship game, and my idea is when the user or AI hit the button, it could show ship size
For example, there have 3 ships: ship1(size = 3), ship2(size = 2), ship3(size = 1), and when the user/AI hit the ship1, and they see 3, they will know they hit ship1
but I am having troubles on the setActioncommand
on the code,
array2dtop[x][y].setActionCommand("x")
I want to assign or declare a integer(the size of the ship) into array2dtop[x][y]
but I have no idea but assign a string and how can I use it in the actionPerformed
I want to assign or declare a integer(the size of the ship) into array2dtop[x][y]
You can just parse the string to an integer using Integer.parseInt:
class BattleShip2 extends JFrame implements ActionListener {
JButton[][] array2dtop = new JButton[10][10];
BattleShip2(String title) {
super(title);
setLayout(new GridLayout(10, 10, 5, 5));
for (int x = 0; x < array2dtop.length; x++) {
for (int y = 0; y < array2dtop.length; y++) {
array2dtop[x][y] = new JButton(String.valueOf((x * 10) + y));
array2dtop[x][y].setActionCommand(String.valueOf(3));
array2dtop[x][y].addActionListener(this);
// Force buttons to be square.
Dimension dim = array2dtop[x][y].getPreferredSize();
int buttonSize = Math.max(dim.height, dim.width);
array2dtop[x][y].setPreferredSize(new Dimension(buttonSize, buttonSize));
add(array2dtop[x][y]);
}
}
}
public void actionPerformed(ActionEvent evt) {
int cmd = Integer.parseInt(evt.getActionCommand());
if (cmd == 3) {
System.out.println(3);
}
}
}
public class pratice3 {
public static void main(String[] args) {
BattleShip2 board = new BattleShip2("BattleShip");
board.pack();
board.setLocationRelativeTo(null);
board.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
board.setVisible(true);
}
}
Notes:
I changed the layout to GridLayout with the same vertical and horizontal gaps as FlowLayout's defaults. It will assure that all button have the same size.
Don't use setBounds, let the layout manager take care of that.
I added 3 lines that make the buttons square, you can remove that.
Instead of using setSize for a JFrame, use pack.
Setting the location using board.setLocationRelativeTo(null) (After the call to pack) is usually a better idea since you don't know the size of the screen.
board.EXIT_ON_CLOSE should be accessed in a static way: JFrame.EXIT_ON_CLOSE (for example).
When calling Integer.parseInt, you might want to catch NumberFormatException.
With that being said, there are other ways to achieve this, such as using setClientProperty on the buttons, or just passing the number to the ActionListener's constructor.

Passing variables to another classes (Java)

I have a Java program that contains multiple classes, all of which extend JPanel (except for the class containing the main method). I am trying to pass int variables from one class to another and, using some previously asked questions, came up with this:
Class RollPanel
public int getbrainCount()
{
return brainCount;
}
Class BrainsPanel (where I am trying to send the variable)
void setbrainCount()
{
RollPanel rollpanel = new RollPanel();
brainCount = rollpanel.getbrainCount();
}
This doesn't give any errors, but when I add brainCount to a label to see its value, it is always 0.
brainCount is declared at the class level of RollPanel, then given a value with this code which is in a button listener:
value1 = generator.nextInt(3) + 1;
value2 = generator.nextInt(3) + 1;
value3 = generator.nextInt(3) + 1;
//rollTotal++;
//Counts how many brains were rolled.
if (value1 == 1)
brainCount++;
if (value2 == 1)
brainCount++;
if (value3 == 1)
brainCount++;
I understand that just declaring a variable will automatically mean its value will be zero at first(which I assume is why it is displayed as zero), but how can I pass its updated value after the above code to brainsPanel so I can add its value to a label in brainsPanel? Would getBrainCount() come after the button listener? I feel like I'm overlooking something simple here...
EDIT:
I think the problem isn't with the setter as it is the getter. Since in RollPanel(where the getter is) I declare brainCount as an int its initial value is 0, so when the getter gets the value it always remains at 0 even though brainCount should be altered in the button listener. Here is RollPanel in its entirety. How can I make the getter get the updated value of brainCount instead of its initial 0?
package zombiedice;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
public class RollPanel extends JPanel
{
JLabel die1Label, die2Label, die3Label, testLabel;
JButton rollButton, sortButton;
JPanel dicePanel, buttonPanel;
ImageIcon die1, die2, die3;
int rollTotal, value1, value2, value3;
int brainCount, blastCount;
Random generator = new Random();
public RollPanel()
{
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
setBackground(Color.black);
dicePanel = new JPanel();
dicePanel.setBackground(Color.black);
//Creates blank ImageIcons to be used later to display dice.
die1 = new ImageIcon();
die2 = new ImageIcon();
die3 = new ImageIcon();
//A panel just to hold the buttons.
buttonPanel = new JPanel();
//Creates and links roll button to RollListener.
rollButton = new JButton("Roll");
rollButton.addActionListener(new RollListener());
buttonPanel.add(rollButton);
//After a roll, this button will need to be clicked so brain and blast
//die can be sorted into their proper catergories.
sortButton = new JButton("Sort");
sortButton.addActionListener(new SortListener());
//Creates labels out of the dice images.
die1Label = new JLabel(die1);
die2Label = new JLabel(die2);
die3Label = new JLabel(die3);
//Adds image labels to the panel that holds the dice.
dicePanel.add(die1Label);
dicePanel.add(die2Label);
dicePanel.add(die3Label);
add(dicePanel);
add(buttonPanel);
} //Closes constructor
//Roll button listener.
private class RollListener implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
rollButton.setEnabled(false);
repaint();
buttonPanel.add(sortButton);
repaint();
sortButton.setEnabled(true);
repaint();
value1 = generator.nextInt(3) + 1;
value2 = generator.nextInt(3) + 1;
value3 = generator.nextInt(3) + 1;
//rollTotal++;
//Counts how many brains were rolled.
if (value1 == 1)
brainCount++;
if (value2 == 1)
brainCount++;
if (value3 == 1)
brainCount++;
//Updates the dice
die1Label.setIcon(new ImageIcon(value1 + ".png"));
die2Label.setIcon(new ImageIcon(value2 + ".png"));
die3Label.setIcon(new ImageIcon(value3 + ".png"));
} //Closes actionPerformed
} //Closes the listener for the roll button
//Sort button listener.
private class SortListener implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
sortButton.setEnabled(false);
repaint();
rollButton.setEnabled(true);
repaint();
} //Closes actionPerformed.
}//Closes sort button listener.
public int getBrainCount()
{
return brainCount;
}
} //Closes class
BrainsPanel
package zombiedice;
import javax.swing.*;
import java.awt.*;
public class BrainsPanel extends JPanel
{
ImageIcon icon1 = new ImageIcon();
ImageIcon icon2 = new ImageIcon();
JLabel brainTotal, label1, label2;
JPanel brainPanel;
int brainCount;
void setbrainCount(int count)
{
// RollPanel rollpanel = new RollPanel();
brainCount = count;
//brainCount = count;
}
public BrainsPanel()
{
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
setBackground(Color.black);
icon1 = new ImageIcon("1.png");
icon2 = new ImageIcon("1.png");
label1 = new JLabel(icon1);
label2 = new JLabel(icon2);
brainTotal = new JLabel ("Brains eaten: " + brainCount);
add(label1);
add(label2);
add(brainTotal);
} //Closes constructor
} //Closes class
In this peace of code:
void setbrainCount() {
RollPanel rollpanel = new RollPanel();
brainCount = rollpanel.getbrainCount();
}
You always create a new RollPanel object before getting brainCount. Of course it is 0 if it is declared as field in RollPanel. The variable was newly initialized with the object creation just the line before.
You should make sure you always use the same RollPanel object, e.g. keep it as field in BrainsPanel. It's hard to say for sure with the given code.
I believe you should try the following:
void setbrainCount(RollPanel rollPanel)
{
brainCount = rollpanel.getbrainCount();
}
This way you won't try to use the newly initialized value which is always 0.
Althozuh technically, it would make more sense to just send the count over and set that
void setbrainCount(int brainCount)
{
this.brainCount = brainCount;
}

Dynamically initializing JButtons with unique ImageIcons

This is my first attempt at using a GUI layout in Java. I am trying to create a simple memory card game, where the user flips over two cards, and tries to get a match, and if there's no match they flip back over, if there's a match they stay flipped until you get all the matches. I might have made it hard on myself though in that I made the whole game dynamic to the constructor variables that define the number of columns and rows of cards. I thought this was better than hard-coding a certain value in, but now I'm having trouble putting the images in my img folder onto my cards.
I understand that variables of variables are not permitted in Java & this is really hard for me to adapt to as a ColdFusion developer. Can you help me think of ways to accomplish this this the proper way in Java?
Here is a simplified version of my code.
import javax.swing.JFrame;
public class MemoryApp
{
public static void main(String args[])
{
//Creates a new game with 3 columns and 4 rows
final CardGame myGame = new CardGame(3, 4);
javax.swing.SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI(myGame.getCols(), myGame.getRows());
}
});
}
private static void createAndShowGUI(int c, int r) {
//Create and set up the window.
Window frame = new Window("GridLayoutDemo", c, r);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Set up the content pane.
frame.addComponentsToPane(frame.getContentPane());
//Display the window.
frame.pack();
frame.setVisible(true);
}
}
Card game class:
public class CardGame
{
private int cols, rows;
public CardGame(int c, int r)
{
cols = c;
rows = r;
}
public int getCols(){
return cols;
}
public int getRows(){
return rows;
}
}
The window with the grid layout:
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.GridLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSeparator;
public class Window extends JFrame
{
private int cols, rows;
GridLayout windowGrid = new GridLayout(1,1);
public Window(String t, int c, int r)
{
super(t);
cols = c;
rows = r;
windowGrid.setColumns(c);
windowGrid.setRows(r);
}
public void addComponentsToPane(final Container pane)
{
final JPanel compsToExperiment = new JPanel();
compsToExperiment.setLayout(windowGrid);
JPanel controls = new JPanel();
controls.setLayout(new GridLayout(cols,rows));
int countCard = (cols * rows) / 2;
/**
* Add buttons to experiment with Grid Layout.
* This is where I'd like to be able to loop through
* countCard and create the required number of buttons
* as well as put images on the buttons like so:
*
* ImageIcon image1 = new ImageIcon(getClass().getResource("card1.png"));
* through
* ImageIcon image1 = new ImageIcon(getClass().getResource("card" & cardCount & ".png"));
*
* Below is how I would attempt this in ColdFusion- I know
* the variable of variables syntax is invalid, it is just
* to show you what I mean.
*/
// for(int i = 0; i < countCard; i++;)
// {
// compsToExperiment.add(new JButton("../img/card" & i & ".png"));
// ImageIcon variables["image" & i] = new ImageIcon(getClass().getResource("card" & i & ".png"));
// imageButton.setIcon(variables["image" & i]);
// etc. with ButtonClickEventHandler, haven't gotten that far yet
// }
pane.add(compsToExperiment, BorderLayout.NORTH);
pane.add(new JSeparator(), BorderLayout.CENTER);
}
}
Based on the code commented-out code that you posted so far, one approach could be like this:
public class Window extends JFrame
{
...
// A java.util.List that stores all the buttons, so
// that their icons may be changed later
private List<JButton> buttons = new ArrayList<JButton>();
// A java.util.List that stores all the ImageIcons that
// may be placed on the buttons
private List<ImageIcon> imageIcons = new ArrayList<ImageIcon>();
public void addComponentsToPane(final Container pane)
{
...
for(int i = 0; i < countCard; i++;)
{
// String concatenation is done with "+" in Java, not with "&"
String fileName = "card" + i + ".png";
// Create the icon and the button containing the icon
ImageIcon imageIcon = new ImageIcon(getClass().getResource(fileName));
JButton button = new JButton(imageIcon);
// Add the button to the main panel
compsToExperiment.add(button);
// Store the button and the icon in the lists
// for later retrieval
imageIcons.add(imageIcon);
buttons.add(button);
// Attach an ActionListener to the button that will
// be informed when the button was clicked.
button.addActionListener(createActionListener(i));
}
}
private ActionListener createActionListener(final int cardIndex)
{
return new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
clickedCardButton(cardIndex);
}
};
}
private void clickedCardButton(int cardIndex)
{
System.out.println("Pressed button for card "+cardIndex);
// Here you can change the icons of the buttons or so...
JButton button = buttons.get(cardIndex);
ImageIcon imageIcon = imageIcons.get(cardIndex);
....
}
You mentioned that this is your first attempt to build a GUI with Java. So I assume that this is only intended for "practicing". If your intention was to build a "real application", you should rather consider some Model-View-Controller (MVC) approach for this.

How do I make an ImageIcon (or any kind of image really) visible without a JButton?

I'm working on a minesweeper game and I want to make the bomb (or in this case a panda image I created) to show up under the game space when it's pressed. At this point I just want to make it show up under every single space, I know how to do the randomizing of where it shows up after that, the problem is making it show up.
Right now the parts of my code that apply to this topic are in 2 different classes:
1st class
public class MSBoard extends JPanel implements ActionListener
{
int x = 8;
int y = 8;
public GridLayout gl = new GridLayout(x,y,0,0);
public MSBoxes boxarray[][] = new MSBoxes[x][y];
MSBoard()
{
super();
setLayout(gl);
for(int i=0;i<x;i++)
for (int j=0;j<y;j++)
{
boxarray[i][j] = new MSBoxes();
add(boxarray[i][j]);
}
}
public void actionPerformed(ActionEvent ae){}
}
2nd one
public class MSBoxes extends JPanel implements ActionListener
{
public JButton b1;
ImageIcon panda;
MSBoxes()
{
super();
panda = new ImageIcon("panda.gif");
b1 = new JButton();
add(b1);
b1.addActionListener(this);
b1.setVisible(true);
}
public void actionPerformed(ActionEvent ae)
{
if(b1 == ae.getSource())
{
b1.setVisible(false);
}
}
}
use JToggleButton for Minesweeper game
use putClientProperty
use ItemListener for JToggleButton

Categories

Resources