I'm new to Java so I'm sure my code is abysmal in comparison to cleaner/organized code.
Link to full code: http://pastebin.com/UXJzU2ax
What it looks like when ran.
Image
I'm attempting to add a number onto the end of a variable via a number in an array. I'm unsure as to how this can be achieved.
I have created a 10x10 grid of buttons with randomly generated colors, I wish to change the adjacent buttons color on click, but only if the color is the same.
Color generation.
int[] squares;
squares = new int[101];
for (int i = 1; i <= 100; i++){
squares[i] = i;
JButton button = new JButton("" + squares[i]);
int color = (int) (Math.random() * 4); //rand 1 to 4
if (color == 1){
button.setBackground(Color.red);
} else if (color == 2){
button.setBackground(Color.green);
} else if (color == 3){
button.setBackground(Color.yellow);
} else {
button.setBackground(Color.blue);
}
button.setName("button" + (Integer.toString(squares[i])));
button.addActionListener(new ActionListener()
{
My way of knowing where directions are.
right = Integer.parseInt(button.getText()) + 1;
up = Integer.parseInt(button.getText()) - 10;
down = Integer.parseInt(button.getText()) + 10;
right2 = squares[right];
up2 = squares[up];
down2 = squares[down];
This is where I'm running into troubles.
if (btnSelectedColor.getBackground() == button.getBackground()){
//Where I need the change in "button", like "button[right].getBackground", or something similar.
if (button.getBackground() == btnSelectedColor.getBackground()){
}
}
Here's how you can access the other buttons.
Note: I will not write all the logic here. I will leave the method of getting the neighbors to you.
In the actionPerformed callback, you need somehting like this:
public void actionPerformed(ActionEvent e)
{
// get all components of the panel
Component[] comp = panel.getComponents();
// loop through all components
for (int i = 0; i < comp.length; i++)
{
// if it's a button...
if (comp[i] instanceof JButton)
{
JButton b = (JButton) comp[i];
// if b is a neighbor of button (e.g. the one clicked),
// then change its background color
// I leave this logic to you (seems like you wrote most if it already)
// Hint: Convert the text of b to an int and convert the
// text of button to an int and compare the ints to see if
// they are neighbors. You can convert the int of
// button.getText once outside of the loop. No sense in
// doing the conversion every time since it will be the same.
}
}
// Rest of code in your actionPerformed method...
}
Good luck!
I would extend JButton
public class BuddyButton extends JButton {
The new BuddyButton would have 4 fields
private BuddyButton north;
private BuddyButton south;
private BuddyButton east;
private BuddyButton west;
Initerate buttons[][]
BuddyButton buttons[][] = new BuddyButton[10][10];
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
BuddyButton buddy = new BuddyButton();
buttons[i][j] = buddy;
panel.add(buddy);
buddy.addActionListener(listener);;
}
}
Loop through buttons[][] again linking all the BuddyButtons
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
BuddyButton buddy = new BuddyButton();
buttons[i][j] = buddy;
panel.add(buddy);
buddy.addActionListener(listener);
}
}
public static void linkBuddies(int i, int j) {
if (i > 0)
buttons[i][j].setNorth(buttons[i - 1][j]);
if (i < 10)
buttons[i][j].setSouth(buttons[i + 1][j]);
if (j > 0)
buttons[i][j].setWest(buttons[i + 1][j - 1]);
if (j > 10)
buttons[i][j].setEast(buttons[i + 1][j + 1]);
}
When a BuddyButton is clicked cast e.getSource() back to a BuddyButton
listener = new ActionListener() {
public void actionPerformed(ActionEvent e) {
BuddyButton buddy = (BuddyButton) e.getSource();
BuddyButton north = buddy.getNorth();
BuddyButton south = buddy.getSouth();
BuddyButton east = buddy.getEast();
BuddyButton west = buddy.getWest();
//Check for nulls and talk to the neighbors!!!!
}};
Related
I'm creating a game like jeopardy where you have the buttons from each row worth points ranging from 500 - 100. What I'm stuck on his how to add these points to the current score. Here's what I have:
public class GUIWindow implements ActionListener{
Players p1 = new Players();
private int p1Score = 0;
private int p2Score = 0;
public void actionPerformed(ActionEvent e){
int points = 0;
for(int i = 0; i < 5; i++){
if(e.getSource() == boardButtonsRow1[i]){
points = 500;
}else if(e.getSource() == boardButtonsRow2[i]){
points = 400;
}else if(e.getSource() == boardButtonsRow3[i]){
points = 300;
}else if(e.getSource() == boardButtonsRow4[i]){
points = 200;
}else if(e.getSource() == boardButtonsRow2[i]){
points = 100;
}
}
if(e.getSource() == submitBtn){
String answer = answerEntry.getText();
if(answer.equalsIgnoreCase(q1.getAnswer())){
System.out.println("Correct");
System.out.println(points);
p1Score = p1Score + points;
p1.setPoints(p1Score);
showP1ScoreLbl.setText(""+p1.getScore());
}
}
The buttons are stored in rows and setup in arrays. I have a player class that stores the points (p1). When the user presses the submit button it checks if the answer is correct and adds this number of points to the label on my GUI. I don't know what I'm missing here but even when the answer is right it still shows 0.
So I have a Sudoku grid which consists of one large 3x3 GridLayout and each of its elements consists of a smaller 3x3 GridLayout of JTextFields. My issue here is that my Sudoku will be in the form of a 2D array but the layout structure does not look the same. The image below shows how the coordinates look like in the layout form. My question is if and then how I can "translate" the coordinates from array form to "layout"-form?
(I guess a problem could be that the outer GridLayout loops 9 times linearly while the inner ones loop 3x3 in 2D)
int[][] matrix = s.getMatrix();
JPanel p1 = new JPanel();
gl.setHgap(4);
gl.setVgap(4);
p1.setBackground(Color.black);
p1.setSize(WIDTH, (HEIGHT - PANEL_HEIGHT));
p1.setLayout(gl);
for(int i = 0; i < 9; i++) {
JPanel p = new JPanel();
GridLayout local_gl = new GridLayout(3,3);
local_gl.setHgap(2);
local_gl.setVgap(2);
p.setBackground(Color.black);
p.setSize(WIDTH / 3, (HEIGHT - PANEL_HEIGHT) / 3);
p.setLayout(local_gl);
p1.add(p);
for(int row = 0; row < 3; row++) {
for(int col = 0; col < 3; col++) {
JTextField jtf = new JTextField(" " + Integer.toString(matrix[row][col]));
if(jtf.getText().trim().equals("0")) {
jtf.setText(" ");
}
jtf.setFont(new Font("Times New Roman", Font.BOLD, 30));
p.add(jtf);
}
}
}
This solution works.
JTextField jtf = new JTextField(" " + Integer.toString(matrix[translateRowToY(i, row)][translateColToX(i, col)]));
private int translateColToX(int i, int col) {
if(i == 2 || i == 5 || i == 8) {
return col + 6;
}else if(i == 1 || i == 4 || i == 7) {
return col + 3;
}else if(i == 0 || i == 3 || i == 6) {
return col;
}else {
return -1;
}
}
private int translateRowToY(int i, int row) {
if(i >= 0 && i < 3) {
return row;
}else if(i >= 3 && i < 6) {
return row + 3;
}else if(i >= 6 && i < 9) {
return row + 6;
}else {
return -1;
}
}
I would not use 9 panels with 9 inputs each; instead, I would use single panel with 81 inputs, arranged in a 9x9 grid. Instead of JTextFields, I would define a public static class SudokuCell extends JTextField, so that, each time you create a new cell, you can keep all its tracking information inside:
public static class SudokuCell extends JTextField {
public final int block; // 0 to 9, you call it `i`
public final int row; // 0 to 9 again
public final int col; // again 0-9
public SudokuCell(int block, int row, int col) {
// ... assign to attributes
}
}
The advantage is that interpreting clicks is now trivial: if you add a MouseListener to each of those cells, c.row will tell you the row it is on, c.block will reply with the block, and so on and so forth.
Initializing those cells is also very easy:
for (int row=0; row<DIM; row++) {
for (int col=0; col<DIM; col++) {
SudokuCell c = new SudokuCell((row/3)*3 + col/3, row, col);
// add to panel for display, and to internal DIMxDIM array too.
}
}
For a project I am working on I would like to be abbe to "scroll" an array like so:
Here is the code I have so far:
private boolean[][] display = this.parseTo8BitMatrix("Here");
private int scroll = 0;
public void scroll() {
this.scroll++;
}
//sets the clock's display
public void setDisplay(String s) {
this.display = this.parseTo8BitMatrix(s);
}
//determines the current frame of the clock
private boolean[][] currentFrame() {
boolean[][] currentFrame = new boolean[8][32];
int length = this.display[0].length;
if(length == 32) { //do nothing
currentFrame = this.display;
} else if(length <= 24) { //center
for(int i = 0; i < 8; i++) {
for(int j = 0; j < length; j++) {
currentFrame[i][j+((32-length)/2)] = this.display[i][j];
}
}
this.display = currentFrame; //set display to currentFrame so the display doesn't get centered each time
} else { //scroll
for(int i = 0; i < 8; i++) {
for(int j = 0; j < length; j++) {
if(this.scroll+j <= 32) {
currentFrame[i][j] = this.display[i][j+this.scroll];
} else {
//?
}
}
}
}
return currentFrame;
}
The code I have is effective up until the the array needs to "wrap around" to the other side. Where have I gone wrong?
I'm assuming that you're looking for a formula that would work for the else.
Usually Modulos are very helpful for wrapping around.
What you are looking for is basically
currentFrame[i][j]= this.display[i][(j+this.scroll)%length];
which works even when it's not wrapped around.
I am making a game where move across a gridlayout of jbuttons, only allowing movement to adjacent grid jbuttons. The goal is to try and make it to the topleft (From the btm right). I think this is all that is relevant:
//Here is my method to determine whether it is a valid move (i dont want you to be able to move anywhere but adjacent spots
public boolean goodMove(int x, int y) {
int val = Math.abs(current.x - x) + Math.abs(current.y - y);
return val == 1;
}
//Here is the logic in the actionlister, a big if else loop that is now referencing only the jbuttons in my gridlayout (the game panel)
public void actionPerformed(ActionEvent e) {
JButton clicked = (JButton) e.getSource();
if (clicked == SHOWMINES) {
if (SHOWMINES.getText().equals("Show Mines")) {
showMines();
SHOWMINES.setText("Hide Mines");
} else {
hideMines();
}
} else {
if (clicked == NEWGAME) {
newGame();
} else {
if (clicked == SHOWPATH) {
if (SHOWPATH.getText().equals("Show Path")) {
showPath();
SHOWPATH.setText("Hide Path");
} else {
hidePath();
}
} else {
if (clicked == OKAY) {
resetGridSize(Integer.parseInt(gridSizeInput.getText()));
newGame();
} else {
}
int gs = Integer.parseInt(gridSizeInput.getText());
for (int i = 0; i < gs - 1; i++) {
for (int j = 0; j < gs - 1; j++) {
if (clicked == grid[i][j]) {
if (goodMove(i, j)) {//debug tester ,this is where the problem is.
System.out.println("TEST");
current = new Point(i, j);
grid[i][j].setBackground(Color.green);
grid[i][j].setText("=");
}else{System.out.println("TEST2");}
}
}
}
}
}
}
}// end of action listener
Grid[][] is my array of grid buttons, gridSizeInput is the textfield that you can adjust the gridsize in.
Thanks in advance (I'm new to programming, so keep it simple if you can :)
EDIT: I forgot to mention, it is not recognizing my if(goodMove()) loop, its just printing out TWO for my else.
EDIT: My question is why is not working, no buttons will are be recognized as clicked in my grid, I guess I am asking to see if something I have written is glaringly obviously wrong. thanks.
EDIT: Okay here is my entire action listener for all my buttons. This is my first post, sorry I am not more helpful- let me know if anything else I can add.
Your problem may be as simple as your not extending your for loops out far enough. Try changing this:
for (int i = 0; i < gs - 1; i++) {
for (int j = 0; j < gs - 1; j++) {
to this:
for (int i = 0; i < gs; i++) {
for (int j = 0; j < gs; j++) {
Edit
This was the minimal code example that I created to test the concept:
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.event.*;
import javax.swing.*;
public class Foo extends JPanel {
public static final int GRID_SIZE = 10;
private Point current;
private JButton[][] grid;
public Foo() {
ButtonListener listener = new ButtonListener();
setLayout(new GridLayout(GRID_SIZE, GRID_SIZE));
grid = new JButton[GRID_SIZE][GRID_SIZE];
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[i].length; j++) {
grid[i][j] = new JButton(" ");
grid[i][j].addActionListener(listener);
add(grid[i][j]);
}
}
current = new Point(GRID_SIZE - 1, GRID_SIZE - 1);
}
private class ButtonListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
JButton clicked = (JButton) e.getSource();
// !! int gs = Integer.parseInt(gridSizeInput.getText());
int gs = GRID_SIZE;
// !! for (int i = 0; i < gs - 1; i++) {
// for (int j = 0; j < gs - 1; j++) {
for (int i = 0; i < gs; i++) {
for (int j = 0; j < gs; j++) {
if (clicked == grid[i][j]) {
if (goodMove(i, j)) {
System.out.println("TEST");
current = new Point(i, j);
grid[i][j].setBackground(Color.green);
grid[i][j].setText("=");
} else {
System.out.println("TEST2");
}
}
}
}
}
}
public boolean goodMove(int x, int y) {
int val = Math.abs(current.x - x) + Math.abs(current.y - y);
return val == 1;
}
private static void createAndShowGui() {
Foo mainPanel = new Foo();
JFrame frame = new JFrame("Foo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
This question already has an answer here:
Java: GUI - JButton opening new JPanel and reading the JTextFields
(1 answer)
Closed 9 years ago.
I need to have
1.the JButton open the JTable in the Journal class
2.transfer the ints in the JTextFields to the variables a and b in the Journal Class
I used netbeans to create the Main class and my own methods to create the table class please help! Thanks! This is the part of the Main class Netbeans tells me to edit when I right click > Events > Action > Action Performed
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
int data1 = Integer.parseInt(jTextField1.getText());
int data2 = Integer.parseInt(jTextField2.getText());
}
Here is my Code:
package Components;
/**
*
* #author dustinpx2014
*/
import java.awt.*;
import java.util.*;
import javax.swing.*;
import javax.swing.table.*;
public class Journal extends JPanel
{
private JTable table;
private int a;//Number of Students
private int b;// Length of Trip
public Journal()
{
String colN1 = "Date";
String colN2 = "Student";
int c = a*2/b; // Determining # of Journals
int col = c*2; // Creating two columns for every journal(Day and Student)
String[] columnNames = new String[col]; //For Loop: inserting column names
for(int colF = 0; colF < col; colF++)
{
if(colF%2 == 0)
{
columnNames[colF] = colN1;
}
else
{
columnNames[colF] = colN2;
}
}
int row = b; //row = number of days
int d = 1; //day number
int s = 1; //student number
int x = 0; //counter for the # of times students write
int z = 1; // student number(no limit)
int z1 = a/2; // student number 2
int x1 = 0; // counter for the # of times students write 2
int x2 = 0;
int w = 1;
Object[][] data = new Object[row][col];
for (int col1 = 0; col1 < data[0].length; col1++)
{
for (int row1 = 0; row1<data.length; row1++)//goes through the table by column
{
if(d > b) //reseting the date
{
d = 1;
}
if(s > a && x <= 2) //reseting student number and adds count
{
s = 1;
x++;
}
if(z > a)
{
z = 1;
}
if(z1 > a && x1 <= 2)
{
z1 = 1;
x1++;
}
if (w>a)
{
w++;
}
if(col1%2 == 0) //inserts the day
{
data[row1][col1]= "Day " + d;
d++;
}
else if (s!=data[row1][col1])//inserts student number
{
data[row1][col1]= s;
s++;
z++;
w++;
}
for (int col2 = 1; col2 < data[0].length; col2++)
{
for (int row2 = 0; row2<data.length; row2++)//goes through the table by column
{
if(z == data[row2][col2] && col2%2!=0)//checks for repeats and replaces them
{
for (int y = 0; y < col; y++) //checking all columns
{
if (z1 == a/2 && x1 <= 5) //adds count
{
x1++;
}
else if(z1 > a && x1 <= 5)
{
z1 = 1;
x1++;
}
if(z == data[row2][y])
{
data[row2][col2] = z1;
z1++;
w++;
}
}
}
}
}
for (int row3 = 1; row3 < data.length; row3++)
{
for (int col3 = 0; col3<data[0].length; col3++)//goes through the table by rows
{
if(w == data[row3][col3] && col3%2!=0)//checks for repeats and replaces them
{
for(int y2 = 0; y2 < col; y2++)
{
if(
row3<row-1 &&
row3> 1 &&
w==data[row3+1][y2] &&
w==data[row3-1][y2] &&
w==data[row3][y2]
) //checks rows
{
data[row3][col3] = 0;
}
}
}
}
}
}
}
JTable table = new JTable(data, columnNames);
table.setPreferredScrollableViewportSize(table.getPreferredSize());
JScrollPane scrollPane = new JScrollPane(table);
add(scrollPane);
}
public JTable getTable() {
return table;
}
private static void gui()
{
JFrame gui = new JFrame();
gui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
gui.setTitle("Journal List");
gui.setSize(700,200);
gui.setLocationRelativeTo(null);
gui.setVisible(true);
gui.add(new Journal());
}
Please help! thanks :)
I have two classes Main with JTextFields and Jbutton and Journal with a Jtable extending JPanel. I need to use the Main class to operate the Journal class how do you use JButton to open up the JPanel and how do you use the variables in JTextField and apply them to variables a and b?
I assume that your Main class has a Journal field, say called journal, and that this JPanel has been added to your main. To call methods of your Journal instance, simply call methods on the journal variable. For instance Journal should have public getter methods that would allow Main to query the data held by its fields.
Note that I don't see any JTextFields in Journal, but if Journal were my class, again, I'd give it a public method to allow it to get information out of the JTable, and in that method, I'd call one of JTable's methods to get the information that your Journal method could return. A decent JTable method you could use is the getValueAt(int row, int column). In fact your Journal method could simply wrap that method:
public class Journal {
private JTable table;
// ...... lots more code
public Object getValueAt(int row, int column) {
// first check that row and column are not out of bounds, and deal with it
return table.getValueAt(row, column);
}
}
Now if you're also looking to display this JTable on button press, then you will need to add it to one of the containers in your Main class, and then call revalidate and repaint on the same container after changing its contents. It's important to know and understand the layout manager used by that container as well since some accept new components with greater ease than others.