Java Gui GridLayout- accessing objects - java

I am trying to make a connect four gui.
I have a class Gui which creates a board ( an array[][] ints) and a method move- which accepts the player(int) and column(int)- and a method to check if there is a winner.
I created a gui with the gridLayout and I have a row of buttons and 7 arrays of JLabels (that are an ImageIcon of empty slot) I need to now access the bottommost JLabel of a specific array if a player chooses that column.
I created the buttons in a loop:
A) how do I access each button- they do not have unique names.
B) how do I access each JLabels- they were also created in a loop
C) where am I suppose to instantiate my Board Class?
D) when I am adding each new object in the gui I have
this.add(JLabel)--
how do I put all that into a new Panel so I can have a title bar on top of my grid?
my code for the gui
import java.awt.Color;
import java.awt.Font;
import java.awt.GridLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingConstants;
public class ConnectFourGui extends JFrame {
private JLabel title;
private JButton button;
ImageIcon[] emptySlot;
ImageIcon arrow;
public ConnectFourGui() {
this.setTitle("Connect Four");
this.setSize(800, 800);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//JPanel panel = new JPanel();
//Container container = this.getContentPane();
this.setLayout(new GridLayout(7, 7));
this.title = new JLabel("Connect Four");
title.setForeground(Color.RED);
title.setFont(new Font("Sans-Serif", Font.BOLD, 50));
title.setHorizontalAlignment(SwingConstants.CENTER);
for (int i = 0; i < 7; i++){
arrow = new ImageIcon("arrowButton.png");
this.button = new JButton(arrow);
this.add(button);
}
for (int i = 0; i < 7; i++){
emptySlot = new ImageIcon[6];
for (int j = 0; j<6;j++){
emptySlot[j] = new ImageIcon("emptySlot.png");
this.add(new JLabel(emptySlot[j]));
}
}

Try making seperate arrays for each column like this (see code below). Also make your array an array of JLabels instead of ImageIcons. And create each button with a unique name.
column1 = new JLabel[6];
column2 = new JLabel[6];
column3 = new JLabel[6];
column4 = new JLabel[6];
column5 = new JLabel[6];
column6 = new JLabel[6];
column7 = new JLabel[6];
for (int j = 0; j < 6; j++) {
column1[j] = new JLabel(emptySlot);
column2[j] = new JLabel(emptySlot);
column3[j] = new JLabel(emptySlot);
column4[j] = new JLabel(emptySlot);
column5[j] = new JLabel(emptySlot);
column6[j] = new JLabel(emptySlot);
column7[j] = new JLabel(emptySlot);
this.add(column1[j]);
this.add(column2[j]);
this.add(column3[j]);
this.add(column4[j]);
this.add(column5[j]);
this.add(column6[j]);
this.add(column7[j]);
}
To accces an element in the array per the button on top do something like this
buttonName.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent a) {
column1[3].setIcon(newIcon);
}
}
you would be using a variable instead of the number 3 I used as an example
Instantiate your board class in your constructor.

Related

Array of JLabel ImageIcon

I am attempting to create a game of Sudoku. I am wanting to use the JSwing API. So, I am using an array of JLabels to display the grid. I have a picture drawn of a 3x3 grid, and I would like to display that in a 3x3 grid. My problem is it will not display the image. Can someone help me resolve the problem?
My Current Code looks like this, split into two class.
Main.class
package com.brendenbunker;
import javax.swing.*;
import java.awt.*;
public class Main{
FileMaker fileMaker;
void init() {
fileMaker = new FileMaker();
}
public static void main(String args[]){
ScreenGenerator gui = new ScreenGenerator();
gui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
double width = gui.gridPic.getIconWidth();
double height = gui.gridPic.getIconHeight();
int h = (int) height*4;
int w = (int) width*3;
gui.setSize(w,h);
gui.setTitle("Suduko");
gui.setVisible(true);
}
}
ScreenGenerator.class
package com.brendenbunker;
import javax.swing.*;
import java.awt.*;
public class ScreenGenerator extends JFrame{
//Intro Components
//JLabel temp;
JLabel[] gridLabel;
ImageIcon gridPic;
//intro Vars
public ScreenGenerator() {
setLayout(new FlowLayout());
gridPic = new ImageIcon(getClass().getResource("/Grid_Unified.png"));
gridLabel = new JLabel[8];
for (int i=0; i>=9; i++) {
gridLabel[i] = new JLabel("Hello");
}
for (int i=0; i>=9; i++) {
gridLabel[i].setIcon(gridPic);
add(gridLabel[i]);
}
}
}
All helped Appericiated
change you for loop, it will not enter into loop as per your condition.
change loop to this..
for (int i=0; i<8; i++) {
gridLabel[i] = new JLabel("Hello");
}
for (int i=0; i<8; i++) {
gridLabel[i].setIcon(gridPic);
add(gridLabel[i]);
}
it will work..
package com.brendenbunker;
import javax.swing.*;
import java.awt.*;
public class ScreenGenerator extends JFrame{
//Intro Components
//JLabel temp;
JLabel[] gridLabel;
ImageIcon gridPic;
//intro Vars
public ScreenGenerator() {
setLayout(new FlowLayout());
gridPic = new ImageIcon(getClass().getResource("/Grid_Unified.png"));
gridLabel = new JLabel[8];
//for (int i=0; i>=9; i++) {
//gridLabel[i] = new JLabel("Hello");
// }
for (int i=0; i>=9; i++) {
gridLabel[i] = new JLabel(gridPic);
add(gridLabel[i]);
}
}
}
if you need icon then use the above code if you want text and icon then the following change will help you
gridLabel[i] = new JLabel("hello", gridPic, JLabel.CENTER);
hopefully that help
Have a look at this: Displaying Image in Java
I used to program in Java. I have moved on to Python but I remember many difficulties with this! Use the IO file system to display it. You will find examples here.
Correct me if I am wrong, this is Java?

Why am I getting the error: Incompatible types; JButton cannot be converted to a JTextfield

So I'm getting this error and I'm confused. I'm not even trying to do that..Here's what I have:
import javax.swing.JFrame;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
public class Answerfinder extends JFrame {
private static final int WIDTH = 400;
private static final int HEIGHTH = 300;
private JLabel Ial, Ratelabel,earn1, earn2, earn3, earn4, earn5, earn10;
private JLabel equalabel;
private JTextField ratein,initialamin, earn1out, earn2out, earn3out, earn4out, earn5out, earn10out;
private JButton calculatebut;
private CalculateButtonHandler cbhandler;
public Answerfinder() {
// adding the labels
Ial = new JLabel("Enter your initial amount:",SwingConstants.RIGHT);
Ratelabel = new JLabel("Enter growth percentage (just numbers):",SwingConstants.RIGHT);
earn1 = new JLabel("Total by year 1:",SwingConstants.RIGHT);
earn2 = new JLabel("Total by year 2:",SwingConstants.RIGHT);
earn3 = new JLabel("Total by year 3:",SwingConstants.RIGHT);
earn4 = new JLabel("Total by year 4:",SwingConstants.RIGHT);
earn5 = new JLabel("Total by year 5:",SwingConstants.RIGHT);
earn10 = new JLabel("Total by year 10:",SwingConstants.RIGHT);
equalabel = new JLabel("Press this to calculate: ");
//adding the textfields
ratein = new JTextField();
initialamin = new JTextField();
earn1out =
//adding button
calculatebut = new JButton("Calculate");
cbhandler = new CalculateButtonHandler();
calculatebut.addActionListener(cbhandler);
// Sets title of program
setTitle("Exponential Growth Calculator");
// Sets size of frame, whether or not it's visible, and what do on close
setSize(WIDTH, HEIGHTH);
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
// establishes container and sets the layout
Container pane = getContentPane();
pane.setLayout(new GridLayout (8,2));
pane.add(Ial);
pane.add(initialamin);
pane.add(Ratelabel);
pane.add(ratein);
pane.add(equalabel);
pane.add(calculatebut);
pane.add(earn1);
}
private class CalculateButtonHandler implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
double rate, initamount, returns1, returns2, returns3, returns4, returns5, returns10;
rate = Double.parseDouble(ratein.getText());
if (rate > 1) {
rate = (rate / 100) + 1;
} else {
rate = rate +1;
}
initamount = Double.parseDouble(initialamin.getText());
returns1 = initamount * Math.pow(rate, 1);
returns2 = initamount * Math.pow(rate, 2);
returns3 = initamount * Math.pow(rate, 3);
returns4 = initamount * Math.pow(rate, 4);
returns5 = initamount * Math.pow(rate, 5);
returns10 = initamount * Math.pow(rate, 10);
}
}
}
I'm making a program which will find the exponential growth of numbers entered by the user. It is an extra credit project for an Algebra course. Please ignore the ugly ugly code, I'm a high school student who's just starting out.
You appear to have some half-written code in there:
initialamin = new JTextField();
earn1out =
//adding button
calculatebut = new JButton("Calculate");
You should either finish that earn1out = line, or remove it.
I assume it's this unfinished line in your code:
earn1out =
This gets mingled into the next statement, which is the JButton initialization statement.
//adding button
calculatebut = new JButton("Calculate");
You're missing the right-hand side value of the assignment (plus semi-colon termination)
earn1out =
which is causing the variable earn1out to be assigned to the a JButton. It should be
earn1out = new JTextField();

a simple GUI multiplication table

I'm supposed to create a simple multiplication table using GUI and for the most part, it's doing what it is supposed to do. But I just can't figure out the bottom portion of it where if you click on a specific button, a text will say what the two numbers are being multiplied and the answer.
No matter what button I click, it'll only tell me the numbers I input and multiply them together. Here is my code:
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JOptionPane;
public class MultiplicationTable {
int clickedCount;
int rowCount;
int colCount;
JFrame frame;
JPanel buttonPanel, countPanel;
JLabel countLabel;
private void createAndShowGui(){
rowCount = Integer.parseInt(JOptionPane
.showInputDialog("How many rows do you want your multiplication table to be? "));
colCount = Integer
.parseInt(JOptionPane
.showInputDialog("How many columns do you want your multiplication table to be? "));
frame = new JFrame ("Simple Multiplication Table");
frame.setLayout(new BorderLayout());
buttonPanel = new JPanel();
buttonPanel.setLayout(new GridLayout(rowCount, colCount));
countPanel = new JPanel();
countLabel = new JLabel("? x ? = ?");
for(int rowCounter = 1; rowCounter <= rowCount; rowCounter++)
for(int colCounter = 1; colCounter <= colCount; colCounter++){
final JButton j = new JButton(Integer.toString(rowCounter * colCounter));
j.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent event) {
for(int rc = 1; rc <= rowCount; rc++)
for(int cc = 1; cc <= colCount; cc++){
countLabel.setText(rc + " x " + cc + " = " + String.valueOf(rc * cc));
}
}
});
buttonPanel.add(j);
}
frame.add(buttonPanel, BorderLayout.NORTH);
countPanel.add(countLabel);
frame.add(countPanel, BorderLayout.SOUTH);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args){
MultiplicationTable c = new MultiplicationTable();
c.createAndShowGui();
}
}
Your current ActionListener has no context, it doesn't know what two values were used to generate the value you gave the button.
What you could do is create a ActionListener which takes the values used to produce the button's text, this would then be capable of updating the label accordingly. For example...
public class MultiplerActionListener implements ActionListener {
private int[] values;
private JLabel label;
public MultiplerActionListener(JLabel label, int... valuesToMultiple) {
values = valuesToMultiple;
this.label = label;
}
#Override
public void actionPerformed(ActionEvent event) {
int answer = 1;
StringBuilder sb = new StringBuilder(64);
for (int value : values) {
if (sb.length() > 0) {
sb.append(" x ");
}
sb.append(value);
answer *= value;
}
sb.append(" = ");
sb.append(answer);
label.setText(sb.toString());
}
}
Then you would simply need to apply it when you create the buttons
for(int rowCounter = 1; rowCounter <= rowCount; rowCounter++) {
for(int colCounter = 1; colCounter <= colCount; colCounter++){
final JButton j = new JButton(Integer.toString(rowCounter * colCounter));
j.addActionListener(new MultiplerActionListener(countLabel, rowCounter, colCounter));
buttonPanel.add(j);
}
}

Java GUI, organizing a dialog box to get data from the user

I am designing a GUI for my research project. I want to create a dialog box that gets information from the user. Here is the screenshot:
Here is the code for the screenshot above:
JTextField projnameField = new JTextField(10);
JTextField nField = new JTextField(5);
JTextField mField = new JTextField(5);
JTextField alphaField = new JTextField(5);
JTextField kField = new JTextField(5);
JFileChooser inputfile = new JFileChooser();
inputfile.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
File file = inputfile.getSelectedFile();
String fullpath = file.getAbsolutePath();
JPanel myPanel = new JPanel();
myPanel.add(new JLabel("Project Name:"));
myPanel.add(projnameField);
myPanel.add(new JLabel("Number of instances:"));
myPanel.add(nField);
myPanel.add(new JLabel("Number of attributes:"));
myPanel.add(mField);
myPanel.add(new JLabel("Alpha:"));
myPanel.add(alphaField);
myPanel.add(new JLabel("Number of patterns:"));
myPanel.add(kField);
myPanel.add(new JLabel("Please select your datset:"));
myPanel.add(inputfile);
myPanel.setLayout(new BoxLayout(myPanel, BoxLayout.Y_AXIS));
int result = JOptionPane.showConfirmDialog(
null, myPanel, "CPM Program", JOptionPane.OK_CANCEL_OPTION);
double alpha = Double.parseDouble(alphaField.getText());
int numpat = Integer.parseInt(kField.getText());
int num_inst = Integer.parseInt(nField.getText());
int num_attr = Integer.parseInt(mField.getText());
String projname = (projnameField.getText());
In reference to the above image I have two questions:
Notice the labels are centered. How can I put those in the left side like this:
Project name: --textbox--
Number of instances: --textbox--
In the label, "Please select you dataset", I want to browse the file, select it and copy the full path in a blank box in the front of "Please select you dataset" label, but I do not know how I should do it.
1- The first problem is that all of the labels such as project name or number of instances are centered (it seems!). How can I put those in the left side?
JLabel has a constructor that takes an int as one of the parameters, and you can use it to position your text held in the JLabel.
2- The second problem is that text fields are not in the front of labels and are below of them. I want to have each text field in the front of the label such as:
Layouts are the key here. Consider using GridBagLayout (which can be somewhat difficult to use initially) or MigLayout (easier to use but you have to download it first) to allow use of a more tabular structure for your GUI.
For example, please have a look at my code in this answer for an example of tabular structure using GridBagLayout.
You might use a GroupLayout for that first section. E.G.
import java.awt.*;
import java.util.HashMap;
import java.util.Map;
import javax.swing.*;
class TwoColumnLayout {
/**
* Provides a JPanel with two columns (labels & fields) laid out using
* GroupLayout. The arrays must be of equal size.
*
* Typical fields would be single line textual/input components such as
* JTextField, JPasswordField, JFormattedTextField, JSpinner, JComboBox,
* JCheckBox.. & the multi-line components wrapped in a JScrollPane -
* JTextArea or (at a stretch) JList or JTable.
*
* #param labels The first column contains labels.
* #param fields The last column contains fields.
* #param addMnemonics Add mnemonic by next available letter in label text.
* #return JComponent A JPanel with two columns of the components provided.
*/
public static JComponent getTwoColumnLayout(
JLabel[] labels,
JComponent[] fields,
boolean addMnemonics) {
if (labels.length != fields.length) {
String s = labels.length + " labels supplied for "
+ fields.length + " fields!";
throw new IllegalArgumentException(s);
}
JComponent panel = new JPanel();
GroupLayout layout = new GroupLayout(panel);
panel.setLayout(layout);
// Turn on automatically adding gaps between components
layout.setAutoCreateGaps(true);
// Create a sequential group for the horizontal axis.
GroupLayout.SequentialGroup hGroup = layout.createSequentialGroup();
GroupLayout.Group yLabelGroup = layout.createParallelGroup(GroupLayout.Alignment.TRAILING);
hGroup.addGroup(yLabelGroup);
GroupLayout.Group yFieldGroup = layout.createParallelGroup();
hGroup.addGroup(yFieldGroup);
layout.setHorizontalGroup(hGroup);
// Create a sequential group for the vertical axis.
GroupLayout.SequentialGroup vGroup = layout.createSequentialGroup();
layout.setVerticalGroup(vGroup);
int p = GroupLayout.PREFERRED_SIZE;
// add the components to the groups
for (JLabel label : labels) {
yLabelGroup.addComponent(label);
}
for (Component field : fields) {
yFieldGroup.addComponent(field, p, p, p);
}
for (int ii = 0; ii < labels.length; ii++) {
vGroup.addGroup(layout.createParallelGroup().
addComponent(labels[ii]).
addComponent(fields[ii], p, p, p));
}
if (addMnemonics) {
addMnemonics(labels, fields);
}
return panel;
}
private final static void addMnemonics(
JLabel[] labels,
JComponent[] fields) {
Map<Character, Object> m = new HashMap<Character, Object>();
for (int ii = 0; ii < labels.length; ii++) {
labels[ii].setLabelFor(fields[ii]);
String lwr = labels[ii].getText().toLowerCase();
for (int jj = 0; jj < lwr.length(); jj++) {
char ch = lwr.charAt(jj);
if (m.get(ch) == null && Character.isLetterOrDigit(ch)) {
m.put(ch, ch);
labels[ii].setDisplayedMnemonic(ch);
break;
}
}
}
}
/**
* Provides a JPanel with two columns (labels & fields) laid out using
* GroupLayout. The arrays must be of equal size.
*
* #param labelStrings Strings that will be used for labels.
* #param fields The corresponding fields.
* #return JComponent A JPanel with two columns of the components provided.
*/
public static JComponent getTwoColumnLayout(
String[] labelStrings,
JComponent[] fields) {
JLabel[] labels = new JLabel[labelStrings.length];
for (int ii = 0; ii < labels.length; ii++) {
labels[ii] = new JLabel(labelStrings[ii]);
}
return getTwoColumnLayout(labels, fields);
}
/**
* Provides a JPanel with two columns (labels & fields) laid out using
* GroupLayout. The arrays must be of equal size.
*
* #param labels The first column contains labels.
* #param fields The last column contains fields.
* #return JComponent A JPanel with two columns of the components provided.
*/
public static JComponent getTwoColumnLayout(
JLabel[] labels,
JComponent[] fields) {
return getTwoColumnLayout(labels, fields, true);
}
public static String getProperty(String name) {
return name + ": \t"
+ System.getProperty(name)
+ System.getProperty("line.separator");
}
public static void main(String[] args) {
Runnable r = new Runnable() {
#Override
public void run() {
JTextField projnameField = new JTextField(10);
JTextField nField = new JTextField(5);
JTextField mField = new JTextField(5);
JTextField alphaField = new JTextField(5);
JTextField kField = new JTextField(5);
JTextField[] components = {
projnameField,
nField,
mField,
alphaField,
kField
};
String[] labels = {
"Project Name:",
"Number of instances:",
"Number of attributes:",
"Alpha:",
"Number of patterns:"
};
JOptionPane.showMessageDialog(null,
getTwoColumnLayout(labels,components));
}
};
// Swing GUIs should be created and updated on the EDT
// http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html
SwingUtilities.invokeLater(r);
}
}

Adding JButton by loop causes ArrayIndexOutOfBoundsException

I have a swing application which I have declared a JButton array inside it's constructor inside that class I have created a for loop in order to add a number of 114 JButton to class container.
but when that class runs it gives the exception
java.lang.ArrayIndexOutOfBoundsException: 0
On the statement that adding the Buttons to Container.
Can someone see the problem?
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Main extends JFrame implements ActionListener
{
public Main()
{
Container pane = getContentPane();
JPanel panel = new JPanel();
JButton b[];
int i;
for (i = 0; i < 114; i++)
{
b = new JButton[i];
panel.add(b[i]);
}
pane.add(panel);
}
public void actionPerformed(ActionEvent ae)
{
}
public static void main(String[] args)
{
Main m = new Main();
m.setSize(500, 500);
m.setVisible(true);
}
}
You can't made expression like that
for(i=0; i<114;i++)
{
b = new JButton[i];
panel.add(b[i]);
}
In first execution it is new JButton[0], so your array size is 0.
You should use Collection (fe. ArrayList) or fixed size JButton array.
JButton[] b = new JButton[114];
for(i=0; i<114;i++)
{
b[i] = new JButton();
panel.add(b[i]);
}
At i = 0, b = new JButton[i]; creates an array of size 0, so trying to reference b[0] (i.e. the first element) will be out of bounds.
And you never construct b[i].
You probably want to move the array construction outside the loop, something like:
b = new JButton[114];
for (i = 0; i < 114; i++)
{
b[i] = new JButton();
panel.add(b[i]);
}
since b is an array type which holding collection of JButton objects.So you need to create
one JButton object for each location of that array. The code what Dukeling is given is
correct approach. And also one thing you have forgotten,You need to define the size of
your array like JButton b[]=new JButton[size];

Categories

Resources