This creates a jframe with 3 rows and 4 columns. Im trying to achieve a memory game where it matches the letters. As of now the code matches, but the letters aren't randomly placed. I couldn't find anything about this online. I would also like to know if their is a method that i can use to change the background of the GUI.
public class matchinggame implements ActionListener {
JPanel p;
JFrame f;
String[][] matchList = { {"a", "a"}, {"b", "b"},
{"c", "c" }, {"d", "d"}, {"e", "e"},
{"f", "f"}, {"g", "g" }};
JButton[][] buttons;
int i = 0;
boolean flipping = true;
int cardOne;
int secIndex;
public static void main(String[] args) {
//Schedule a job for the event-dispatching thread
//to create application and display its GUI
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
matchinggame app = new matchinggame();
app.makeGUI();
}
});
}
public void dealCards(JPanel panel) {
buttons = new JButton[3][]; // array of buttons used to represent cards
for (int i= 0; i< 3*4; i++) { // initialize 3 rows with 4 columns each
if (i%4 == 0) buttons[i/4] = new JButton[4];
buttons[i/4][i%4] = new JButton("-Match-"); // show face down
buttons[i/4][i%4].addActionListener(this);
panel.add(buttons[i/4][i%4]);
}
}
public void updateMatchList(String a, String b, boolean add) {
int i,j;
String[][] courseList;
int oldLen = matchList.length;
if (add) { // add the new item to the list
courseList = new String[oldLen+1][];
courseList[0] = new String[2];
courseList[0][0] = new String(a); // new first course
courseList[0][1] = new String(b); // new first course num
for (int item=1; item<= oldLen; item++) {
courseList[item][0] = matchList[item-1][0];
courseList[item][1] = matchList[item-1][1];
}
matchList = courseList;
} else { // delete matching item
courseList = new String[oldLen-1][];
courseList[0] = new String[2];
courseList[0][0] = new String(a); // new first course
courseList[0][1] = new String(b); // new first course num
for (int item=0; item<= oldLen; item++) {
if (a != courseList[item][0]) { // no match so OK to copy over
courseList[item][0] = matchList[item][0];
courseList[item][1] = matchList[item][1];
}
}
matchList = courseList;
}
}
/**
* Creates the JFrame and its UI components.
*/
public void makeGUI() {
JFrame frame = new JFrame("CS435F08 - Java Match Game Starter");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
p = new JPanel(new GridLayout(3,4));
p.setPreferredSize(new Dimension(500, 300));
dealCards(p);
frame.getContentPane().setLayout(new BorderLayout());
frame.getContentPane().add(p,BorderLayout.CENTER);
// Display the window.
frame.pack();
frame.setSize(500, 500);
frame.setVisible(true);
}
public void actionPerformed(ActionEvent e) {
int r,c;
if (i<2) { //find the card clicked on and flip it over
for (r=0; r< 3; r++) {
for (c=0; c< 4; c++) {
// if the card is not face down (showing "-Match-") don't flip it
if ((e.getSource()== buttons[r][c]) && buttons[r][c].getText().equals("-Match-")){
// flip the card face-up to show text from matchList
// looks up text based upon indexes
buttons[r][c].setText(matchList[(r*4+c)/2][(r*4+c)%2]);
i++; // increment number of cards flipped
if (i==1) cardOne = (r*4+c)/2; // save which pattern was shown first
else secIndex = (r*4+c)/2; // save the pattern shown second
return;
}
}
}
} else { // 2 cards already flipped, put all cards face down
for (r=0; r< 3; r++) {
for (c=0; c< 4; c++) {
if (cardOne == secIndex) { // first and second cards flipped match
if (!buttons[r][c].getText().equals("-Match-")) // don't change the face down cards
buttons[r][c].setText("*******"); // once matched, show the removed pattern
} else if ((!buttons[r][c].getText().equals("*******")) && (!buttons[r][c].getText().equals("-Match-"))) {
buttons[r][c].setText("-Match-"); // if 2 face up cards didn't match, flip face down again
}
}
i=0; // new turn, no cards flipped face up
}
}
}
}
I changed the matchList to a 1 dimensional array. This way, I could shuffle the text in the shuffleCards method.
Here's the GUI.
I fixed some problems with your action listener.
Here's the formatted code.
package com.ggl.testing;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class MatchingGame implements ActionListener {
JPanel p;
JFrame f;
String[] matchList = { "a", "a", "b", "b", "c", "c", "d", "d", "e", "e",
"f", "f", "g", "g" };
String[] shuffledList;
JButton[][] buttons;
boolean flipping = true;
int i = 0;
int cardOne;
int secIndex;
public static void main(String[] args) {
// Schedule a job for the event-dispatching thread
// to create application and display its GUI
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
MatchingGame app = new MatchingGame();
app.makeGUI();
}
});
}
public void dealCards(JPanel panel) {
buttons = new JButton[3][]; // array of buttons used to represent cards
shuffleCards();
for (int i = 0; i < 3 * 4; i++) { // initialize 3 rows with 4 columns
// each
if (i % 4 == 0)
buttons[i / 4] = new JButton[4];
buttons[i / 4][i % 4] = new JButton("-Match-"); // show face down
buttons[i / 4][i % 4].addActionListener(this);
panel.add(buttons[i / 4][i % 4]);
}
}
public void shuffleCards() {
List<String> list = Arrays.asList(matchList);
Collections.shuffle(list);
shuffledList = list.toArray(new String[list.size()]);
}
public void updateMatchList(String a, String b, boolean add) {
String[] courseList;
int oldLen = matchList.length;
if (add) { // add the new item to the list
courseList = new String[oldLen + 2];
courseList[0] = new String(a); // new first course
courseList[1] = new String(b); // new first course num
for (int item = 2; item <= oldLen; item += 2) {
courseList[item] = matchList[item - 2];
courseList[item + 1] = matchList[item - 1];
}
matchList = courseList;
} else { // delete matching item
courseList = new String[oldLen - 2];
int matchItem = 0;
for (int item = 0; item <= oldLen; item += 2) {
if (a != matchList[item]) { // no match so OK to copy over
courseList[item] = matchList[matchItem];
courseList[item + 1] = matchList[matchItem + 1];
matchItem += 2;
}
}
matchList = courseList;
}
}
/**
* Creates the JFrame and its UI components.
*/
public void makeGUI() {
JFrame frame = new JFrame("CS435F08 - Java Match Game Starter");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
p = new JPanel(new GridLayout(3, 4));
p.setPreferredSize(new Dimension(500, 300));
dealCards(p);
frame.getContentPane().setLayout(new BorderLayout());
frame.getContentPane().add(p, BorderLayout.CENTER);
// Display the window.
frame.pack();
frame.setSize(500, 500);
frame.setVisible(true);
}
public void actionPerformed(ActionEvent e) {
int r, c;
if (i < 2) { // find the card clicked on and flip it over
for (r = 0; r < 3; r++) {
for (c = 0; c < 4; c++) {
// if the card is not face down (showing "-Match-") don't
// flip it
if ((e.getSource() == buttons[r][c])
&& buttons[r][c].getText().equals("-Match-")) {
// flip the card face-up to show text from matchList
// looks up text based upon indexes
buttons[r][c].setText(shuffledList[(r * 4 + c)]);
i++; // increment number of cards flipped
if (i == 1)
cardOne = (r * 4 + c); // save which pattern was
// shown first
else
secIndex = (r * 4 + c); // save the pattern
// shown second
return;
}
}
}
} else { // 2 cards already flipped, put all cards face down
for (r = 0; r < 3; r++) {
for (c = 0; c < 4; c++) {
// first and second cards flipped
if (shuffledList[cardOne].equals(shuffledList[secIndex])) {
// match
// don't change the face down cards
if (!buttons[r][c].getText().equals("-Match-"))
// once matched, show the removed pattern
buttons[r][c].setText("*******");
} else if ((!buttons[r][c].getText().equals("*******"))
&& (!buttons[r][c].getText().equals("-Match-"))) {
// if 2 face up cards didn't match, flip face down again
buttons[r][c].setText("-Match-");
}
}
i = 0; // new turn, no cards flipped face up
}
}
}
}
Related
I just started learning GUI in Java and I was wondering if someone can assist with the problem I'm having. I'm trying to make a calculator, but the problem is whenever I subtract two numbers and click on the equal sign button, it seems to add the 2 numbers instead of subtracting.
import java.util.Scanner;
import javax.swing.JFrame;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JTextField;
import java.awt.event.ActionListener;
import java.awt.Color;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.GridLayout;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import javax.swing.JPanel;
class Colorwindow extends JFrame implements ActionListener {
private JButton clear, addition, subtract, divide, multiply, zero, one, two, three, four, five, six, seven, eight, nine, ten, equal;
private JTextField name, name2, name3;
private String inputing, solution, solution2, solution3, solution4;
private boolean AddStatement, SubtractStatement, MultiplyStatement, DivideStatement, statement;
private JButton SButtonList[] = new JButton[6];
private JButton NButtonList[] = new JButton[10];
private String SymbolList[] = {
"+",
"-",
"/",
"*",
"=",
"C"
};
private String NumberList[] = {
"0",
"1",
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"9"
};
private String NumberList2[] = {
"0",
"1",
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"9"
};
private double result[] = new double[10];
private double number[] = new double[10];
//AddStatement = false;
Colorwindow() {
super();
setSize(500, 500); //sets size of window
getContentPane().setBackground(Color.GRAY); //sets backgroundcolor to yellow
rows 3 column
JPanel textfont = new JPanel();
name = new JTextField(30);
textfont.add(name); //adds textfield
name.setBackground(Color.CYAN);
Font bigFont = name.getFont().deriveFont(Font.PLAIN, 70 f);
name.setFont(bigFont);
name2 = new JTextField(30);
//textfont.add(name2);//adds textfield
add(textfont, BorderLayout.NORTH);
JPanel rows = new JPanel();
rows.setLayout(new GridLayout(2, 4));
for (int i = 0; i < 10; i++) {
NButtonList[i] = new JButton(NumberList[i]);
rows.add(NButtonList[i]); //add's the buttons
NButtonList[i].addActionListener(this);
add(rows, BorderLayout.CENTER);
}
for (int i = 0; i < 6; i++) {
SButtonList[i] = new JButton(SymbolList[i]);
rows.add(SButtonList[i]); //add's the buttons
SButtonList[i].addActionListener(this);
add(rows, BorderLayout.CENTER);
}
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //closes window button when pressing the x(EXIT_ON_CLOSE)
//add(button);//adds a button to the window//adds componenets to jframe//event
setTitle("Calculator"); //sets title on top of window
}
private static double stringToDouble(String stringObject) {
return Double.parseDouble(stringObject.trim());
}
public void actionPerformed(ActionEvent e) {
try {
PassesCorrect(e);
} catch (NumberFormatException e2) {
name.setText("Please re-press on a number");
}
}
public void PassesCorrect(ActionEvent e) {
String ButtonString = e.getActionCommand();
for (int i = 0; i < 10; i++) {
if (e.getSource() == NButtonList[i]) {
name.setText(name.getText() + NumberList[i]); //appends text
}
}
for (int i = 0; i < 6; i++) {
if (e.getSource() == SButtonList[i]) {
//number = Double.parseDouble(name.getText());
name2.setText(SymbolList[i]);
}
}
if (e.getSource() == SButtonList[0]) //checks if it's addition
{
for (int i = 0; i < 10; i++) {
number[i] = Double.parseDouble(name.getText()); //stores the number that has been entered into an array
}
//solution=name.getText();//gets the text and adds it into a string
name.setText("+"); //sets the number from string and input's it on screen
AddStatement = true;
} else if (e.getSource() == SButtonList[1]) //checks if subtraction
{
for (int i = 0; i < 10; i++) {
number[i] = Double.parseDouble(name.getText());
}
//solution=name.getText();//gets the text and adds it into a string
name.setText("-"); //sets the number from string and input's it on screen
SubtractStatement = true;
} else if (e.getSource() == SButtonList[2]) {
for (int i = 0; i < 10; i++) {
number[i] = Double.parseDouble(name.getText());
}
//solution=name.getText();//gets the text and adds it into a string
name.setText("/"); //sets the number from string and input's it on screen
DivideStatement = true;
} else if (e.getSource() == SButtonList[3]) {
for (int i = 0; i < 10; i++) {
number[i] = Double.parseDouble(name.getText());
}
//solution=name.getText();//gets the text and adds it into a string
name.setText("*"); //sets the number from string and input's it on screen
MultiplyStatement = true;
} else if (e.getSource() == SButtonList[5]) {
name.setText("");
SubtractStatement = false;
AddStatement = false;
DivideStatement = false;
MultiplyStatement = false;
} else if (e.getSource() == SButtonList[4]) //checks if it's equal sign
{
for (int i = 0; i < 10; i++) {
result[i] = Double.parseDouble(name.getText());
}
if (SubtractStatement == true) {
for (int i = 0; i < 10; i++) {
result[i] = number[i] - result[i];
name.setText(Double.toString(result[i]));
}
} else if (AddStatement == true) {
for (int i = 0; i < 10; i++) {
result[i] = number[i] + result[i];
name.setText(Double.toString(result[i]));
}
//result+=number;
} else if (MultiplyStatement == true) {
} else if (DivideStatement == true) {
//result=number/result;
//name.setText(Double.toString(result));
}
SubtractStatement = false;
AddStatement = false;
DivideStatement = false;
MultiplyStatement = false;
}
}
}
public class GUI2 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner input = new Scanner(System.in);
Colorwindow W1 = new Colorwindow();
W1.setVisible(true);
}
Your problem is that you're reading in the subtraction sign as part of the second number, and then still subtracting.
E.g. 2-3 is encoded as 2 and -3, and then you do first-second, which turns into 2-(-3) which is essentially addition.
You could change it to do addition in both cases, but this fails once you move on to multiplication and division as as +4 and -4 are valid numbers, but *4 and /4 are not.
Instead, do
else if(e.getSource()==SButtonList[4])//checks if it's equal sign
{
for(int i =0;i<10;i++)
{
if(name.getText().length()>0) //make sure this string isn't empty
result[i] = Double.parseDouble(name.getText().substring(1));
This will get the characters except the first (which is the sign) from your string.
That being I haven't read your entire program, and if there are any cases where a number without a sign is present when this if is entered, you might end up trimming off the first digit, so be careful.
Also, unless there is a very good reason you are doing every calculation 10 times in a for loop, you should remove those. Your program works identically (just tested it) with all number[i] changed to number, result[i] to result, and for loops from 1-10 removed. (You also have to change your declarations for number and result)
http://imgur.com/a/V7LPP
Grid images are in the link
I have 2 main issues with my current connect4 code, sometimes the "AI" places 2 discs in one turn and the player can't fill the entire board without the "AI" entering an infinite loop. Any help is appreciated.
/**
* Auto Generated Java Class.
*/
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class EmptyFrame1 implements ActionListener
{
//Array of JButtons
static JButton [] mnuBtn = new JButton[2];
static JButton [] btnArray = new JButton[7];
static JLabel [][] board = new JLabel[6][7];
static int [][] numBoard = new int[6][7];
static int choice = 0;
static int playerColour = 1;
static int computerColour = 2;
static int computerTurn = 0;
static ImageIcon emptyGrid = new ImageIcon("EmptyGrid.png");
static ImageIcon yellowGrid = new ImageIcon("YellowGrid.png");
static ImageIcon redGrid = new ImageIcon("RedGrid.png");
static JPanel pnlBoard;
static boolean validTurn;
static int pieceCount = 42;
public EmptyFrame1()
{
JFrame game = new JFrame("Connect 4");
//mainFrame panel to hold all components
JPanel mainFrame = new JPanel();
pnlBoard = new JPanel();
pnlBoard.setLayout(new GridLayout(7,6));
//Change mainFrame layout to vertical BoxLayout
mainFrame.setLayout(new BoxLayout(mainFrame, BoxLayout.Y_AXIS));
//For every single button
//Set the button text to its index value, add an action listener and add it to the pnlButtons
for (int i = 0; i < btnArray.length; i++)
{
btnArray[i] = new JButton("place");
btnArray[i].addActionListener(this);
pnlBoard.add(btnArray[i]);
}//end for
for (int r = 0; r < board.length; r++)
{
for (int c = 0; c < board[r].length; c++)
{
board[r][c] = new JLabel(emptyGrid);
board[r][c].setPreferredSize(new Dimension(69, 69));
pnlBoard.add(board[r][c]);
}//end for
}//end for
//Add all the panels to the mainFrame panel
mainFrame.add(pnlBoard);
//add mainFrame to the JFrame
game.add(mainFrame);
game.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // Added this for security
game.pack();
game.setVisible(true);
game.setResizable(false);
}
//*Action listener for all buttons*
public void actionPerformed(ActionEvent e)
{
for (int i = 0; i < btnArray.length; i++)
{
//if the current button was triggered, set the choice to the button index
if (btnArray[i] == e.getSource())
{
choice = i;
colCheck(choice, 1);
//System.out.println("User turn used");
pieceCount--;
for (int j = 0; j < btnArray.length; j++)
{
if (numBoard[0][j] == 0) btnArray[j].setEnabled(true);
}
if (pieceCount > 0)
{
validTurn = false;
while(!validTurn)
{
computerTurn = (int) (Math.random() * 7);
System.out.print(computerTurn + " ");
validTurn = colCheck(computerTurn, 2);
//System.out.println("CPU tried to move");
}
}
System.out.println();
setGrid();
pieceCount--;
System.out.println(pieceCount);
validTurn = false;
}//end if
}//end for
pnlBoard.repaint();
}//end actionPerformed
public static boolean colCheck(int choice, int currentTurn)
{
int row = -1;
for (int r = 5; r >= 0; r--)
{
if (numBoard[r][choice] == 0)
{
row = r;
break;
}
}
//System.out.println("Row That CPU Chooses: " + row);
if (row > -1)
{
numBoard[row][choice] = currentTurn;
if (row == 0)
{
btnArray[choice].setEnabled(false);
return false;
}
return true;
}
return false;
}
public static void setGrid()
{
for (int r = 0; r < numBoard.length; r++)
{
for (int c = 0; c < numBoard[r].length; c++)
{
if (numBoard [r][c] == 0)
{
board[r][c].setIcon(emptyGrid);
}
else if (numBoard [r][c] == 1)
{
board[r][c].setIcon(redGrid);
}
else if (numBoard [r][c] == 2)
{
board[r][c].setIcon(yellowGrid);
}
}
}
}
/**
* Inner helper class that defines the graphics
*/
public static void main(String[] args)
{
new EmptyFrame1();
}
//end constructor
Some problems and suggestions:
Your colCheck method and the while (!validTurn) { loop in the actionPerformed method is where the problem is located.
This method should not set numBoard value or disable buttons. In other words, it should not have any "side effects".
Instead it should only check for validity and then return a boolean value, nothing more or less
You should have another method that is called first, one that checks if no valid columns are available, if the game is effectively over. This should be called before the while loop above and should prevent the while loop from entering. This will end your endless loop problem because it's looping because no valid columns can be found for the computer turn.
You should have another method for setting the numBoard state and for enabling and disabling JButtons.
Change your colCheck to this to see where the loop is coming from:
public static boolean colCheck(int choice, int currentTurn) {
int row = -1;
for (int r = 5; r >= 0; r--) {
if (numBoard[r][choice] == 0) {
row = r;
break;
}
}
// System.out.println("Row That CPU Chooses: " + row);
if (row > -1) {
numBoard[row][choice] = currentTurn;
if (row == 0) {
btnArray[choice].setEnabled(false);
System.out.printf("debug 1 row %d %n", row);
return false;
}
System.out.printf("debug 2 row %d %n", row);
return true;
}
System.out.printf("debug 3 row %d %n", row);
return false;
}
Other issues not directly related to your problem at hand, but which should be addressed
You're grossly over-using the static modifier, and in fact none of your fields should be static. All should be private instance fields.
You've got your program logic code, the model, mixed in the same class as the GUI, the view, making it hard to debug problems and enhance the program. Much better if you could make your model a completely separate class, one that is "view-agnostic" meaning that it is testable on its own and can work with any view, be it a command line or Swing or Android UI.
Your question depends on images, EmptyGrid.png, YellowGrid.png.... that we have no access to, preventing us from testing it.
You're using magic numbers, such as 0, 1, 2 for position values, and need to avoid doing this.
Instead use an enum for empty, user and computer
This is Java not Javascript. You'll want to be clear on the difference because they're two completely different languages.
The title is not my entire question. I know HOW to organize code, theoretically, but i would like some specific, USEFUL, pointers. Please read on before griping.
I'm a beginner to java and OOP (object oriented programming) and I would really like to learn how to better organize my code! Over the course of a month or two, I made a calculator program with little functions I thought of here and there with a few small jokes built into it. After looking at it a second time I realized that it is extremely poorly formatted and almost incomprehensible.If I may, I would like to ask some more experienced programmers to point me in the right direction on what I should do to fix it (for example, what things can I turn into objects, Where can I compartmentalize, etc).
Please note that this is my FIRST time posting on a forum like this so if i need to clarify something for you to help me, I've done something wrong, I'm asking for too much, please tell me so i can resolve it and i can get help. Please dont just mark this as invalid and file it away to oblivion (as often happens in stackoverflow). Also, before anyone asks, NO this is NOT homework, it is the product of my own crack at teaching myself java (probably why its not working too well).
Here is the source code:
// This is the original Calculator code without objects in a single class. not really efficient...
package randomClasses;
import java.awt.*;
import java.awt.event.*;
import java.text.DecimalFormat;
import javax.swing.*;
#SuppressWarnings("serial")
public class CalcClass
extends JFrame
implements ActionListener {
JPanel[] row = new JPanel[6];
JButton[] button = new JButton[21];
String[] buttonString = {"7", "8", "9", "+", "4", "5", "6", "-", "1", "2", "3", "*", ".", "/", "C", "v", "+/-", "=", "0", "Parabola", "x^y"};
int[] dimW = {300, 45, 100, 90, 180};
int[] dimH = {35, 40};
Dimension displayDimension = new Dimension(dimW[0], dimH[0]);
Dimension regularDimension = new Dimension(dimW[1], dimH[1]);
Dimension rColumnDimension = new Dimension(dimW[2], dimH[1]);
Dimension zeroButDimension = new Dimension(dimW[3], dimH[1]);
Dimension parabolaDimension = new Dimension(dimW[4], dimH[0]);
//formatting variables
int var = 0;
double x = 0;
String stor = "";
boolean initial = true;
//variables for Parabola function
int countEquals_parab = 0;
double Angle = 0;
double Vi = 0;
double Vx = 0;
double Vy = 0;
double T_max = 0;
double Y_displ = 0;
double X_displ = 0;
double h = 0;
double k = 0;
double a_parab = 0;
boolean parabComplete = true;
boolean parabola = false;
DecimalFormat df = new DecimalFormat("#######.#####");
//variables for addressing illegal typing issues
boolean typeNum = true;
boolean typeDot = true;
JFrame frame; //for parabolaInstructions
//original calculator variables
boolean[] function = new boolean[5];
double[] temporary = {0, 0}; //store on screen values
double result = 0; //store result
public JTextArea display = new JTextArea(1, 20);
Font font = new Font("Times new Roman", Font.BOLD, 14);
CalcClass() {
super("CalcClass");
setDesign();
setSize(380, 300);
setResizable(false);
setDefaultCloseOperation(EXIT_ON_CLOSE);
GridLayout grid = new GridLayout(6, 5);
setLayout(grid);
for(int i = 0; i < 5; i++) {
function[i] = false;
}
FlowLayout f1 = new FlowLayout(FlowLayout.CENTER);
FlowLayout f2 = new FlowLayout(FlowLayout.CENTER, 1, 1);
for(int i = 0; i < 6; i++) {
row[i] = new JPanel();
}
row[0].setLayout(f1);
for(int i = 1; i < 6; i++) {
row[i].setLayout(f2);
}
for(int i = 0; i < 21; i++) {
button[i] = new JButton();
button[i].setText(buttonString[i]);
button[i].setFont(font);
button[i].addActionListener(this);
}
display.setFont(font);
display.setEditable(false);
display.setPreferredSize(displayDimension);
for(int i = 0; i < 14; i++) {
button[i].setPreferredSize(regularDimension);
}
for(int i = 14; i < 18; i++) {
button[i].setPreferredSize(rColumnDimension);
}
button[18].setPreferredSize(zeroButDimension);
button[19].setPreferredSize(parabolaDimension);
button[20].setPreferredSize(rColumnDimension);
row[0].add(display);
add(row[0]);
for(int i = 0; i < 4; i++) {
row[1].add(button[i]);
}
row[1].add(button[14]);
add(row[1]);
for(int i = 4; i < 8; i++) {
row[2].add(button[i]);
}
row[2].add(button[15]);
add(row[2]);
for(int i = 8; i < 12; i++) {
row[3].add(button[i]);
}
row[3].add(button[16]);
add(row[3]);
row[4].add(button[18]);
for(int i = 12; i < 14; i++) {
row[4].add(button[i]);
}
row[4].add(button[17]);
add(row[4]);
row[5].add(button[19]);
row[5].add(button[20]);
add(row[5]);
setVisible(true);
}
public void getSqrt() {
stor = "";
initial = true;
try {
double value = Double.parseDouble(display.getText());
if(value == -100) {
format("John's Girlfriend");
} else {
value = Math.sqrt(Double.parseDouble(display.getText())); //create a value for variable, and use Maths square root to find the value
format(Double.toString(value)); //Sets display to new value
}
} catch(NumberFormatException e) {
}
typeDot = false;
typeNum = false;
}
public void getPosNeg() {
stor = "";
initial = true;
try {
double value = Double.parseDouble(display.getText()); //again creating a variable for current value
if(value != 0) { //if value is not equal to zero
value = (-1) * value; //multiplied by -1 to change the sign
format(Double.toString(value)); //Sets display to new value
} else {
}
} catch(NumberFormatException e) {
}
}
public void getResult() {
temporary[1] = Double.parseDouble(display.getText());
String temp0 = Double.toString(temporary[0]);
String temp1 = Double.toString(temporary[1]);
try {
if(temp0.contains("-")) {
String[] temp00 = temp0.split("-", 2);
temporary[0] = (Double.parseDouble(temp00[1]) * -1);
}
if(temp1.contains("-")) {
String[] temp11 = temp1.split("-", 2);
temporary[1] = (Double.parseDouble(temp11[1]) * -1);
}
} catch(ArrayIndexOutOfBoundsException e) {
}
try {
functions();
clear();
format(Double.toString(result));//display has a result
for(int i = 0; i < 5; i++) {
function[i] = false; //set all functions to false
}
} catch(NumberFormatException e) {
}
typeNum = false;
}
public void functions() {
if(function[2] == true) { //multiplication
result = temporary[0] * temporary[1];
} else if(function[3] == true) { //division
result = temporary[0] / temporary[1];
} else if(function[0] == true) { //addition
result = temporary[0] + temporary[1];
} else if(function[1] == true) { //subtraction;
result = temporary[0] - temporary[1];
} else if(function[4] == true) {
result = Math.pow(temporary[0], temporary[1]);
} else {
result = temporary[1];
}
}
double a_quadratic = 0;
double b = 0;
double c = 0;
double x1 = 0;
double x2 = 0;
double discr = 0;
int countEquals_quadratic = 0;
public void quadraticFormula() {
if(countEquals_parab == 0) {
a_quadratic = Double.parseDouble(display.getText());
clear();
display.setText("b = ");
}
if(countEquals_parab == 1) {
b = Double.parseDouble(display.getText());
display.setText("c = ");
}
if(countEquals_parab == 2) {
c = Double.parseDouble(display.getText());
discr = (Math.pow(b, 2) - 4 * a_quadratic * c); //stores the value of the discriminant
if(discr >= 0) {
x1 = (-b + Math.sqrt(b * b - 4 * a_quadratic * c)) / (2 * a_quadratic);
x2 = (-b - Math.sqrt(b * b - 4 * a_quadratic * c)) / (2 * a_quadratic);
}
}
}
public void parabolaButton() {
double G = 9.81;
if(countEquals_parab == 0) {
Vi = Double.parseDouble(display.getText());
clear();
display.setText("Angle of release: ");
}
if(countEquals_parab == 1) {
Angle = Double.parseDouble(display.getText());
if((Angle > 90.0) || (Angle < 0.0)) {
display.setText("Sorry, not a valid angle");
countEquals_parab = 3;
} else {
Angle = (Math.PI / 180.0) * Angle; //converting degrees into radians
Vx = Vi * Math.cos(Angle); //Calculating x component
Vy = Vi * Math.sin(Angle); //Calculating y component
//Finding time
T_max = Vy / G; //time to max height
//Calculating vertex coordinates
Y_displ = (Vy * Vy / (2 * G));
X_displ = Vx * T_max;
//finding a
a_parab = (-Y_displ) / (X_displ * X_displ);
display.setText("The equation of the parabola is \ny = " + df.format(a_parab) + "(x - " + df
.format(h) + ")^2 + " + df.format(k));
}
}
if(countEquals_parab == 2) {
display.setText("Time to get to max height = " + df.format(T_max));
}
if(countEquals_parab == 3) {
clearFunction();
countEquals_parab = -1;
parabola = false;
parabComplete = true;
}
countEquals_parab++;
}
public void var() {
var++;
if(var > 8) {
var = 1;
}
if(var == 1) {
format("x");
}
}
public final void setDesign() {
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
} catch(Exception e) {
}
}
public void format(String get) {
//get stores the incoming values temporarily
//get is transferred to a new value for permanent storage
//print the permanent storage value
//new number is added, stored temporarily in get
//get is added to permanent storage
//print permanent storage value
double spaceFix = 0;
if(initial == true) {
stor = get;
initial = false;
} else if(initial == false) {
stor = stor + get;
}
spaceFix = stor.length() / 4;
int numberOfSpaces = 56 - stor.length() + (int) spaceFix;
String format = String.format("%" + numberOfSpaces + "s", stor);
display.setText(format);
}
#Override
public void actionPerformed(ActionEvent ae) {
if(ae.getSource() == button[0]) {
numberButtons("7");
}
if(ae.getSource() == button[1]) {
numberButtons("8");
}
if(ae.getSource() == button[2]) {
numberButtons("9");
}
if(ae.getSource() == button[3]) {
operatorButtons(0); //add function[0]
}
if(ae.getSource() == button[4]) {
numberButtons("4");
}
if(ae.getSource() == button[5]) {
numberButtons("5");
}
if(ae.getSource() == button[6]) {
numberButtons("6");
}
if(ae.getSource() == button[7]) {
operatorButtons(1); //subtract function[1]
}
if(ae.getSource() == button[8]) {
numberButtons("1");
}
if(ae.getSource() == button[9]) {
numberButtons("2");
}
if(ae.getSource() == button[10]) {
numberButtons("3");
}
if(ae.getSource() == button[11]) {
operatorButtons(2); //multiplication function[2]
}
if(ae.getSource() == button[12]) {
if(typeDot == false) {
} else {
numberButtons(".");
typeDot = false;
}
}
if(ae.getSource() == button[13]) {
operatorButtons(3); //divide function[3]
}
if(ae.getSource() == button[14]) {
clearFunction();
parabola = false;
parabComplete = true;
}
if(ae.getSource() == button[15]) {
getSqrt();
}
if(ae.getSource() == button[16]) {
getPosNeg();
}
if((ae.getSource() == button[17]) && display.getText().equals("")) {
} else if((ae.getSource() == button[17]) && (parabola == false)) {
getResult();
} else if((ae.getSource() == button[17]) && (parabola == true)) {
parabolaButton();
}
if(ae.getSource() == button[18]) {
numberButtons("0");
}
if(ae.getSource() == button[19]) {
clearFunction();
parabolaInstructions();
parabola = true;
parabComplete = false;
display.setText("Initial velocity: ");
}
if(ae.getSource() == button[20]) {
operatorButtons(4);//powerFunction();
}
}
public void parabolaInstructions() {
//Create the dialog.
final JDialog dialog = new JDialog(frame, "How to use the Parabola function");
//Add contents to it. It must have a close button,
//since some L&Fs (notably Java/Metal) don't provide one
//in the window decorations for dialogs.
JLabel label = new JLabel("<html><p align=center>" + "Step 1: Type in the initial velocity and press the \"=\" button<br>" + "Step 2: Type in the angle of Release (make sure that it is between 0 and 90)<br>" + "Step 3: Press the \"=\" button to scroll through the results<br>" + "Step 4: Profit");
label.setHorizontalAlignment(JLabel.CENTER);
Font font = label.getFont();
label.setFont(label.getFont().deriveFont(font.PLAIN, 14.0f));
JButton closeButton = new JButton("Ok");
closeButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
dialog.setVisible(false);
dialog.dispose();
}
});
JPanel closePanel = new JPanel();
closePanel.setLayout(new BoxLayout(closePanel, BoxLayout.LINE_AXIS));
closePanel.add(Box.createHorizontalGlue());
closePanel.add(closeButton);
closePanel.setBorder(BorderFactory.
createEmptyBorder(0, 0, 5, 5));
JPanel contentPane = new JPanel(new BorderLayout());
contentPane.add(label, BorderLayout.CENTER);
contentPane.add(closePanel, BorderLayout.PAGE_END);
contentPane.setOpaque(true);
dialog.setContentPane(contentPane);
//Show it.
dialog.setSize(new Dimension(400, 200));
dialog.setLocationRelativeTo(frame);
dialog.setVisible(true);
}
public void numberButtons(String i) {
if(typeNum == false) {
display.setText("");
format(i);
} else {
format(i);
}
typeNum = true;
}
public void operatorButtons(int funct) {
if(display.getText().equals("")) {
} else {
temporary[0] = Double.parseDouble(display.getText());
function[funct] = true;
clear();
}
}
public void clearFunction() {
clear();
try {
for(int i = 0; i < 5; i++) {
function[i] = false;
}
for(int i = 0; i < 2; i++) {
temporary[i] = 0;
}
} catch(NullPointerException e) {
}
//For parabola()
Vi = 0;
Vx = 0;
Vy = 0;
T_max = 0;
Y_displ = 0;
X_displ = 0;
h = 0;
k = 0;
a_parab = 0;
}
public void clear() {
display.setText("");
stor = "";
typeDot = true;
initial = true;
}
public static void main(String[] arguments) {
CalcClass c = new CalcClass();
}
}
Ok so now you've seen my mess... I sort-of know what I should do and YES I did some research but I feel it would be much easier to learn organization through example or a nice push than it would be from reading articles that tell you ultra-hypothetical or loosely-analogous examples of what objects are. Note: I tried using methods to organize and my class looks much better than what it did (I also made the whole thing an object to be called upon at the bottom which is pretty much useless).
If you use eclipse, try:
Window > Prefferences > Java > Editor > Save Actions
Check "perform the selected actions on save", "Additional Actions" and click "Configure".
Using eclipse's Save Actions can be really useful in real life coding, but you will probably learn some neat java tricks going through the Save Actions wizard.
Java is an Object Oriented language. You need to take advantage of that fact.
Use classes to separate your code into different logical / structural components. Learn how to use OOP. Follow SOLID design and use design patterns.
Another important thing is to know your language. Start by reading basic classes javadocs and relevant sections of the java spec. I would begin with deeply understanding the different types of java (class, interface, enum and inner / nested / anonymous types) and the different modifiers (private, public, protected, static, abstract, final, default).
Some other eclipse's short cuts:
CTRL-A, CTRL-I ("indentation") will fix your code indentation.
CTRL-SHIFT-O ("organize imports") will omit redundant imports.
You might consider taking a look at Code Complete, which deals with the issues that you're concerned with here, and otherwise is just a classic in our field that every serious developer should read.
In general, when you're organizing code you should do so with a few things in mind: readability and atomicity. These two factors apply to code on every level of an application, from variable naming, routines, methods, classes, packages, and so on.
Readability is a simple idea: can a human being read this code and understand it? To gauge the readability of the code all you have to do is read it! Do variable names help the reader understand what something is? Are routines and classes properly formatted and not needlessly complex? Have you removed all code that isn't being used? Is your code written in a logical progression?
Atomicity is the idea that everything should have one purpose. A function or method should (usually) do one thing and one thing only. A class should usually be a logical grouping of related methods and fields serving some type of unique purpose, and NOT a mish-mash of unrelated stuff. A package should also contain a set of related files. Same with a project, and so on.
The main benefit of atomicity is that once you get into more involved applications it's actually much easier to debug and isolate issues in your code because you know where stuff is. For instance: I have a database access error! Good thing I have a package that's specifically defined for my database access objects.
I know when I was just getting started in the field this was something that threw me off too. It might not be until you do a lot of coding within more significant apps that you really start to understand best practices and why people build stuff a certain way.
Thanks to everyone who contributed to my problem, I completely scrapped this garbage and made it 1000 times better. I knew from the beginning it was poorly made and I wanted to fix it, I just didn't know where to start. After reading all the advice that was given, watching a few tutorials and brushing up on some simple java concepts (modifiers, jswing, etc), I ended up making a new one that is in MVC format (Yay, order and efficiency). Now all my new variables are actually meaningful (Thanks #maaartinus for helping me realize that many of my variables were poorly named and made my whole program unnecessarily complicated). Also, I tried to work on SRP (Not 100% sure if I completely did it but with the program organized it will be easy to change things) and I plan on adding units later for good practice (Thank you, #Robert Snyder). This new GUI is ugly but that can always be changed later and since It is now in MVC format the job will be easier.
Here is what I did (not finished and far from perfect but a step in the right direction):
CalcGui.java
package com.Calculator;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class CalcGui extends JFrame {
private static final long serialVersionUID = 1L;
private String[] operatorsList = { "+", "-", "*", "/", "^" };
// Row 1
private JTextField firstNumber = new JTextField(10);
private JComboBox<String> operator = new JComboBox<>(operatorsList);
private JTextField secondNumber = new JTextField(10);
private JButton calculateButton = new JButton("Calculate");
private JTextField calcSolution = new JTextField(20);
// Row 2
private JLabel sqrtSymbol = new JLabel("√");
private JTextField sqrtNumber = new JTextField(10);
private JButton sqrtCalcButton = new JButton("Calculate");
private JTextField sqrtCalcSolution = new JTextField(20);
// Row 3
private JLabel quadraticLabel1 = new JLabel("A = ");
private JTextField quadraticFirstNumber = new JTextField(5);
private JLabel quadraticLabel2 = new JLabel("B = ");
private JTextField quadraticSecondNumber = new JTextField(5);
private JLabel quadraticLabel3 = new JLabel("C = ");
private JTextField quadraticThirdNumber = new JTextField(5);
private JButton quadraticCalcButton = new JButton("Calculate");
private JLabel quadraticTextBefore = new JLabel("x =");
private JTextField firstQuadraticCalcSolution = new JTextField(3);
private JLabel quadraticTextMiddle = new JLabel("and x =");
private JTextField secondQuadraticCalcSolution = new JTextField(3);
CalcGui() {
JPanel calcPanel = new JPanel(new BorderLayout());
FlowLayout Default = new FlowLayout(FlowLayout.LEFT);
JPanel row1 = new JPanel(Default);
JPanel row2 = new JPanel(Default);
JPanel row3 = new JPanel(Default);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(650, 150);
row1.add(firstNumber);
row1.add(operator);
row1.add(secondNumber);
row1.add(calculateButton);
row1.add(calcSolution);
row2.add(sqrtSymbol);
row2.add(sqrtNumber);
row2.add(sqrtCalcButton);
row2.add(sqrtCalcSolution);
row3.add(quadraticLabel1);
row3.add(quadraticFirstNumber);
row3.add(quadraticLabel2);
row3.add(quadraticSecondNumber);
row3.add(quadraticLabel3);
row3.add(quadraticThirdNumber);
row3.add(quadraticCalcButton);
row3.add(quadraticTextBefore);
row3.add(firstQuadraticCalcSolution);
row3.add(quadraticTextMiddle);
row3.add(secondQuadraticCalcSolution);
calcPanel.add(row1, BorderLayout.NORTH);
calcPanel.add(row2, BorderLayout.CENTER);
calcPanel.add(row3, BorderLayout.SOUTH);
this.add(calcPanel);
}
// basic calculations methods
public double getFirstNumber() {
return Double.parseDouble(firstNumber.getText());
}
public String getOperator() {
return (String) operator.getSelectedItem();
}
public double getSecondNumber() {
return Double.parseDouble(secondNumber.getText());
}
public void setCalcSolution(double solution) {
calcSolution.setText(Double.toString(solution));
}
void addCalculateListener(ActionListener listenForCalcButton) {
calculateButton.addActionListener(listenForCalcButton);
}
void displayErrorMessage(String errorMessage) {
JOptionPane.showMessageDialog(this, errorMessage);
}
// Square root function methods
public double getSqrtNumber() {
return Double.parseDouble(sqrtNumber.getText());
}
public void setSqrtCalcSolution(double solution) {
sqrtCalcSolution.setText(Double.toString(solution));
}
void addSqrtCalcListener(ActionListener listenForSqrtCalcButton) {
sqrtCalcButton.addActionListener(listenForSqrtCalcButton);
}
// Quadratic formula Methods
public double getQuadraticFirstNumber() {
return Double.parseDouble(quadraticFirstNumber.getText());
}
public double getQuadraticSecondNumber() {
return Double.parseDouble(quadraticSecondNumber.getText());
}
public double getQuadraticThirdNumber() {
return Double.parseDouble(quadraticThirdNumber.getText());
}
public void setFirstQuadraticCalcSolution(double solution) {
firstQuadraticCalcSolution.setText(Double.toString(solution));
}
public void setSecondQuadraticCalcSolution(double solution) {
secondQuadraticCalcSolution.setText(Double.toString(solution));
}
void addQuadraticCalcListener(ActionListener listenForQuadraticCalcButton) {
quadraticCalcButton.addActionListener(listenForQuadraticCalcButton);
}
}
CalcModel.java
package com.Calculator;
public class CalcModel {
private double calcValue;
public void calculate(double firstNumber, double secondNumber,
String operator) {
if (operator.equals("+")) {
calcValue = firstNumber + secondNumber;
}
if (operator.equals("-")) {
calcValue = firstNumber - secondNumber;
}
if (operator.equals("*")) {
calcValue = firstNumber * secondNumber;
}
if (operator.equals("/")) {
calcValue = firstNumber / secondNumber;
}
if (operator.equals("^")) {
calcValue = Math.pow(firstNumber, secondNumber);
}
}
public double getCalcValue() {
return calcValue;
}
}
SqrtCalcModel.java
package com.Calculator;
public class SqrtCalcModel {
private double sqrtCalcValue;
public void sqrt(double number) {
sqrtCalcValue = Math.sqrt(number);
}
public double getSqrtCalcValue() {
return sqrtCalcValue;
}
}
QuadraticCalcModel.java
package com.Calculator;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
public class QuadraticCalcModel {
private double firstQuadraticCalcValue;
private double secondQuadraticCalcValue;
public void quadraticFormula(double a, double b, double c) {
double discriminant = (b * b) - (4 * a * c);
if (discriminant >= 0) {
firstQuadraticCalcValue = (Math.sqrt((b * b) - (4 * a * c)) + (-b))
/ (2 * a);
secondQuadraticCalcValue = (Math.sqrt((b * b) - (4 * a * c)) - (-b))
/ (2 * a);
}
else {
JFrame parent = new JFrame();
JOptionPane.showMessageDialog(parent,
"This function has no real roots.");
}
}
public double getFirstQuadraticValue() {
return firstQuadraticCalcValue;
}
public double getSecondQuadraticValue() {
return secondQuadraticCalcValue;
}
}
CalculatorControler.java
package com.Calculator;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class CalculatorController {
private CalcGui theGui;
private CalcModel theCalcModel;
private SqrtCalcModel theSqrtCalcModel;
private QuadraticCalcModel theQuadraticCalcModel;
public CalculatorController(CalcGui theGui, CalcModel theCalcModel,
SqrtCalcModel theSqrtCalcModel,
QuadraticCalcModel theQuadraticCalcModel) {
this.theGui = theGui;
this.theCalcModel = theCalcModel;
this.theSqrtCalcModel = theSqrtCalcModel;
this.theQuadraticCalcModel = theQuadraticCalcModel;
this.theGui.addCalculateListener(new CalcListener());
this.theGui.addSqrtCalcListener(new SqrtCalcListener());
this.theGui.addQuadraticCalcListener(new QuadraticCalcListener());
}
class CalcListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
double firstNumber, secondNumber = 0;
String operator;
try {
firstNumber = theGui.getFirstNumber();
operator = theGui.getOperator();
secondNumber = theGui.getSecondNumber();
theCalcModel.calculate(firstNumber, secondNumber, operator);
theGui.setCalcSolution(theCalcModel.getCalcValue());
}
catch (NumberFormatException ex) {
System.out.println(ex);
theGui.displayErrorMessage("You Need to Enter 2 Numbers");
}
}
}
class SqrtCalcListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
double number = 0;
try {
number = theGui.getSqrtNumber();
theSqrtCalcModel.sqrt(number);
theGui.setSqrtCalcSolution(theSqrtCalcModel.getSqrtCalcValue());
}
catch (NumberFormatException ex) {
System.out.println(ex);
theGui.displayErrorMessage("You Need to enter a Number");
}
}
}
class QuadraticCalcListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
double a, b, c = 0;
try {
a = theGui.getQuadraticFirstNumber();
b = theGui.getQuadraticSecondNumber();
c = theGui.getQuadraticThirdNumber();
theQuadraticCalcModel.quadraticFormula(a, b, c);
theGui.setFirstQuadraticCalcSolution(theQuadraticCalcModel
.getFirstQuadraticValue());
theGui.setSecondQuadraticCalcSolution(theQuadraticCalcModel
.getSecondQuadraticValue());
}
catch (NumberFormatException ex) {
System.out.println(ex);
theGui.displayErrorMessage("You need to enter 3 numbers.");
}
}
}
}
MVCCalculator.java
package com.Calculator;
public class MVCCalculator {
public static void main(String[] args) {
CalcGui theGui = new CalcGui();
CalcModel theCalcModel = new CalcModel();
SqrtCalcModel theSqrtCalcModel = new SqrtCalcModel();
QuadraticCalcModel theQuadraticCalcModel = new QuadraticCalcModel();
new CalculatorController(theGui, theCalcModel, theSqrtCalcModel,
theQuadraticCalcModel);
theGui.setVisible(true);
}
}
I am adding JLabel objects to a JPanel. Each label has a different tool tip text that I use to identify each label afterwards, the problem is that the tool tip is always showing on hover and I need it to always be hidden.
Each label has a different image icon that's why I can't use the label text.
I can't find any documentation on the label API for some function like .hidetooltip.
Edit
Each of many JLabel objects on a GridLayout holds an Image. I need to know the line and column of each image.
To hide the tool tip text to null
myComponent.setToolTipText(null);
This is described in the API for this method: "param - the string to display; if the text is null, the tool tip is turned off for this component"
EDIT: In response to your actual issue that you describe in one of your comments, there are a variety of ways association information with a JLabel. You could a) extend the class and keep instance variables defining the grid values b) use a Map key'd with the JLabel and value'd with the row/col c) use the Name of the JLabel
Each of many JLabel objects on a GridLayout holds an Image. I need to know the line and column of each image.
One way to achieve this is to store a BufferedImage[][] to check images against. E.G.
import java.awt.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.net.URL;
import java.util.Random;
import javax.imageio.ImageIO;
public final class ImageArray {
int r = 8;
int c = 8;
// The images in the chess board, used to check which
// image was chosen for this place on the board.
final private BufferedImage[][] chessBoardImages = new BufferedImage[r][c];
private final int rowSprite = 2;
private final int colSprite = 6;
// Holds the tile sheet images
private final BufferedImage[] chessPieceImages =
new BufferedImage[colSprite * rowSprite];
private JComponent ui = null;
private final BufferedImage chessSpriteSheet;
ImageArray(BufferedImage chessSpriteSheet) {
this.chessSpriteSheet = chessSpriteSheet;
initUI();
}
private int getImageIndex(Image img) {
for (int i = 0; i < chessPieceImages.length; i++) {
if (chessPieceImages[i].equals(img)) {
return i;
}
}
return -1;
}
public void initUI() {
if (ui != null) {
return;
}
ui = new JPanel(new BorderLayout(4, 4));
ui.setBorder(new EmptyBorder(4, 4, 4, 4));
int w = chessSpriteSheet.getWidth();
int h = chessSpriteSheet.getHeight() / rowSprite;
int wStep = chessSpriteSheet.getWidth() / colSprite;
int hStep = chessSpriteSheet.getHeight() / rowSprite;
for (int x = 0; x < colSprite; x++) {
for (int y = 0; y < rowSprite; y++) {
chessPieceImages[x + (y * colSprite)]
= chessSpriteSheet.getSubimage(
x * wStep, y * hStep, wStep, h);
}
}
JPanel grid = new JPanel(new GridLayout(r, c));
ui.add(grid, BorderLayout.CENTER);
Random rand = new Random();
for (int x = 0; x < r; x++) {
boolean oddRow = x % 2 == 0;
for (int y = 0; y < c; y++) {
boolean oddCol = y % 2 == 0;
BufferedImage img = chessPieceImages[
rand.nextInt(colSprite * rowSprite)];
JLabel l = new JLabel(new ImageIcon(img));
chessBoardImages[x][y] = img;
l.setOpaque(true);
if ((oddRow && oddCol) || (!oddRow && !oddCol)) {
l.setBackground(Color.WHITE);
} else {
l.setBackground(Color.LIGHT_GRAY);
}
grid.add(l);
}
}
JLabel htmlLabel = new JLabel(getHtml());
htmlLabel.setHorizontalTextPosition(SwingConstants.CENTER);
htmlLabel.setVerticalTextPosition(SwingConstants.BOTTOM);
ui.add(htmlLabel,
BorderLayout.LINE_END);
}
private String getHtml() {
String style = "<style type='text/css'>"
+ "body {"
+ "font-size: 36px;"
+ "}"
+ ".white {"
+ "background-color: #FFFFFF;"
+ "}"
+ ".black {"
+ "background-color: #BBBBBB;"
+ "}"
+ "</style>";
String pre = "<html><head>%1s</head><body><table border=1 cellspacing=0>";
StringBuilder sb = new StringBuilder(String.format(pre, style));
for (int y = 0; y < r; y++) {
sb.append("<tr>");
for (int x = 0; x < c; x++) {
Image img = chessBoardImages[y][x];
final int index = getImageIndex(img);
// hack to convert index to unicode codepoint..
int unicodeOffset = ((index/colSprite)*colSprite)==0 ? colSprite : -colSprite;
int unicodeIndexOffset;
switch (index) {
case 3:
unicodeIndexOffset = 4;
break;
case 4:
unicodeIndexOffset = 3;
break;
case 9:
unicodeIndexOffset = 10;
break;
case 10:
unicodeIndexOffset = 9;
break;
default:
unicodeIndexOffset = index;
}
int unicode = 9812 + unicodeIndexOffset + unicodeOffset;
// end: hack to convert index to unicode index..
String cssClass;
boolean oddCol = x%2==1;
boolean oddRow = y%2==1;
if ((oddRow && oddCol) || (!oddRow && !oddCol)) {
cssClass = "white";
} else {
cssClass = "black";
}
sb.append(String.format(
"<td class='%1s'>&#%2s;</td>", cssClass, unicode));
}
sb.append("</tr>");
}
sb.append("</table></body></html>");
return sb.toString();
}
public JComponent getUI() {
return ui;
}
public static void main(String[] args) throws Exception {
String urlString = "http://i.stack.imgur.com/memI0.png";
final BufferedImage img = ImageIO.read(new URL(urlString));
Runnable r = new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception useDefault) {
}
ImageArray o = new ImageArray(img);
JFrame f = new JFrame("Image Array");
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setLocationByPlatform(true);
f.setContentPane(o.getUI());
f.pack();
f.setMinimumSize(f.getSize());
f.setVisible(true);
}
};
SwingUtilities.invokeLater(r);
}
}
You should consider storing the information elsewhere. One way would be to make a class deriving from JLabel with the purpose of storing the line and column information. Then use instances of this subclass rather than use JLabel instances. They will render as a regular JLabel would, but you can retrieve the line and column information in a way that does not pop up that information in a tooltip.
I want to add a JComboBox to my main panel and fill it with an ArrayList I made in a different method named rectSizeList (which right now prints the ArrayList to the console), this method gets its parameters from another static method named actionPerformed. I cant figure a way to take the filled array after user input to fill my ComboBox. Any help will be appreciated.
All comment is this format are to aid question:
/*
* Like so
*
*/
All other comments are to help whomever my want to compile and run, so that they might understand what is going on.
Main class
import javax.swing.*;
public class ductulatorApp
{
public static void main(String[] args)
{
JFrame frame = new DuctulatorFrame();
frame.setVisible(true);
}
}
Frame class
import javax.swing.*;
import java.awt.*;
public class DuctulatorFrame extends JFrame
{
private static final long serialVersionUID = 1L;
public DuctulatorFrame()
{
setTitle("Test Scores");
setSize(267, 200);
centerWindow(this);
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new DuctulatorPanel();
this.add(panel);
}
private void centerWindow(Window w)
{
Toolkit tk = Toolkit.getDefaultToolkit();
Dimension d = tk.getScreenSize();
setLocation((d.width-w.getWidth())/2, (d.height-w.getHeight())/2);
}
}
Panel class
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.text.*;
import java.util.ArrayList;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class DuctulatorPanel extends JPanel implements ActionListener
{
private static final long serialVersionUID = 1L;
private JTextField staticTextField,
cfmTextField,
rductTextField,
sqductTextField;
private JLabel staticLabel,
cfmLabel,
rductLabel,
sqductLabel;
private JButton calculateButton,
exitButton,
clearButton;
private JComboBox ductSizes; //JComboBox instance
private String[] ductList; //Array to fill JComboBox
double staticP; //static pressure entered by user
double cfm; //cfm entered by user
double deSQ;
double de; //round duct diameter
double pi = 3.14;
double ca; //round duct surface area
double radious;
double sqrA; //rectangular duct area
//two sides of rectangular duct
double a = 4;
double b = 4;
String squareduct;
public DuctulatorPanel()
{
// Creates main panel for labels and text fields
JPanel displayPanel = new JPanel();
displayPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
staticLabel = new JLabel("Static pressure:");
displayPanel.add(staticLabel);
staticTextField = new JTextField(10);
displayPanel.add(staticTextField);
cfmLabel = new JLabel(" CFM:");
displayPanel.add(cfmLabel);
cfmTextField = new JTextField(10);
displayPanel.add(cfmTextField);
rductLabel = new JLabel("Round Duct:");
displayPanel.add(rductLabel);
rductTextField = new JTextField(15);
rductTextField.setEditable(false);
rductTextField.setFocusable(false);
displayPanel.add(rductTextField);
sqductLabel = new JLabel("Square Duct:");
displayPanel.add(sqductLabel);
/*
* This is where I want to add my JComboBox problem is I want to populate ductList arr
* with the array inside rectSizeList(int number) BELOW
* right now this method only prints my array to the console
* this method takes its parameters from the value assigned to
* actionperformed(ActionEvent e)
* below is comboBox commented out
*/
//ductList = new String[list.size]; THIS IS ASSUMING I COULD SOME HOW TRANSFER
//ductList = list.toArray(ductList); ARRAYLIST UP HERE AND NAME IT LIST AND USE IT
//ductSizes = new JComboBox(ductList);
//ductSizes.setSelectedIndex(1);
//displayPanel.add(ductSizes);
sqductTextField = new JTextField(10);
sqductTextField.setEditable(false);
sqductTextField.setFocusable(false);
displayPanel.add(sqductTextField);
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
calculateButton = new JButton("Calculate");
calculateButton.addActionListener(this);
buttonPanel.add(calculateButton);
clearButton = new JButton("Clear");
clearButton.addActionListener(this);
buttonPanel.add(clearButton);
exitButton = new JButton("Exit");
exitButton.addActionListener(this);
buttonPanel.add(exitButton);
this.setLayout(new BorderLayout());
this.add(displayPanel, BorderLayout.CENTER);
this.add(buttonPanel, BorderLayout.SOUTH);
}
public void actionPerformed(ActionEvent e)
{
NumberFormat number = NumberFormat.getNumberInstance();
number.setMaximumFractionDigits(1);
Object source = e.getSource();
if(source == exitButton)System.exit(0);
else if(source == clearButton)
{
staticTextField.setText("");
cfmTextField.setText("");
rductTextField.setText("");
sqductTextField.setText("");
staticP = 0;
cfm = 0;
deSQ = 0;
}
else if(source == calculateButton)
{
try
{
staticP = Double.parseDouble(staticTextField.getText());
cfm = Double.parseDouble(cfmTextField.getText());
}
catch(NumberFormatException nfe)
{
staticTextField.setText("Invalid input");
staticP = 0;
cfm = 0;
deSQ = 0;
de = 0;
}
deSQ = staticP * (0.109136 * Math.pow(cfm, 1.9)); //Calculate round duct
de = Math.pow(deSQ, 0.199) * 2.5; //diameter
// Calculate round duct surface area
radious = de/2;
ca = (radious * radious) * pi;
ca = (int)ca;
rectSizeList((int)ca);
double i = 0;
for(i=0; i<ca; i++)
{
a = a + 0.5;
b = b + 0.5;
i = a * b; // convert round duct to rectangular duct
}
sqrA = i;
a = (int)a;
b = (int)b;
rductTextField.setText(number.format(de));
squareduct = (a + " x " + b);
sqductTextField.setText(squareduct);
}
}
public ArrayList<String> rectSizeList(int number)
{
if (number <= 0) throw new IllegalArgumentException("The number should be greater than 0.");
int i = 0;
int j = 0;
/*
* This is the array list I am hoping to use in order to fill array for
* comboBox
*/
ArrayList<String> rectangularDucts = new ArrayList<String>(); //Create array for rectangular duct
// Fill array for rectangular duct using nested for loop
/*
* If statement will ensure the result is with in range of surface
* area of duct
*/
for(i=4; i<=50; i++)
{
for(j=4; j<=50; j++)
{
if(number == i*j || (i*j)+1 == number || (i*j)-2 == number)
{
rectangularDucts.add(i + " x " + j);
}
}
if(number == i*j || (i*j)+1 == number || (i*j)-2 == number)
{
rectangularDucts.add(i + " x " + j);
}
}
System.out.println(rectangularDucts);
return rectangularDucts;
}
}
I think that your problem is easily solved with just a DefaultComboBoxModel object, or in your situation (I guess), a DefaultComboBoxModel<String> object. Give your class this field, create your JComboBox with this as its model, by passing it into the constructor, and then fill this model object as the need arises.
For example:
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.*;
public class ComboModelEg extends JPanel {
private DefaultComboBoxModel<String> comboModel = new DefaultComboBoxModel<>();
private JComboBox<String> comboBox = new JComboBox<>(comboModel);
private JTextField textField = new JTextField(5);
public ComboModelEg() {
// so combo box is wide enough
comboBox.setPrototypeDisplayValue(" ");
add(comboBox);
add(textField);
add(new JButton(new AddToComboAction("Add Text", KeyEvent.VK_A)));
}
// AbstractAction is like a *super* ActionListener
private class AddToComboAction extends AbstractAction {
public AddToComboAction(String name, int mnemonic) {
super(name); // button's text
putValue(MNEMONIC_KEY, mnemonic); // button's mnemonic key
}
#Override
public void actionPerformed(ActionEvent e) {
String text = textField.getText(); //get text from text field
comboModel.addElement(text); // and put it into combo box's model
}
}
private static void createAndShowGui() {
ComboModelEg mainPanel = new ComboModelEg();
JFrame frame = new JFrame("ComboModelEg");
frame.setDefaultCloseOperation(JFrame.DISPOSE_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();
}
});
}
}
Translated to your code, it could look something like:
for (i = 4; i <= 50; i++) {
for (j = 4; j <= 50; j++) {
if (number == i * j || (i * j) + 1 == number
|| (i * j) - 2 == number) {
// rectangularDucts.add(i + " x " + j); //!!
comboModel.addElement(i + " x " + j); //!!
}
}
if (number == i * j || (i * j) + 1 == number || (i * j) - 2 == number) {
// rectangularDucts.add(i + " x " + j);
comboModel.addElement(i + " x " + j); //!!
}
}
this is how i do it
ArrayList<String> myList = new ArrayList<>();
//some code to populate the list
jComboBox.removeAllItems();
for(int i=0;i<myList.size();i++){
jComboBox.addItem(myList.get(i));
}