I am working on an assignment, but I cannot seem to get my text to print out in the TextArea. I'm working on using recursive methods,and I need to send the result from the recursive method to the TextArea. I have tried multiple things and it has not worked, and searched the web to no avail. Please help!
public class Sheppard_Week5 extends Application {
Button convert = new Button("Convert");
Button clear = new Button("Clear");
Button exitBtn = new Button("Exit");
Label enterInt = new Label("Enter Number:");
TextField enterText = new TextField();
TextArea binaryText = new TextArea();
ImageView mCEscher = new ImageView("sheppard_week5/M.C.Escher.jpg");
ArrayList<String> remainderList = new ArrayList();
ScrollPane scrollPane = new ScrollPane(binaryText)
#Override
public void start(Stage primaryStage) throws Exception {
BorderPane bPane = new BorderPane();
GridPane gPane = new GridPane();
gPane.setStyle("-fx-background-color: #fffaf0;");
bPane.setStyle("-fx-background-color: #fffaf0;");
bPane.setCenter(gPane);
Scene scene = new Scene(bPane);
bPane.setBottom(buttonBox());
bPane.setTop(titleBox());
mCEscher.setFitHeight(300);
mCEscher.setFitWidth(300);
for (int i = 0; i <= 3; i++) {
ColumnConstraints column = new ColumnConstraints();
column.setPercentWidth(25);
gPane.getColumnConstraints().add(column);
}
/*Gridpane
*GridPane.setConstraints(node, column Index, row Index, column span, row span);
*/
gPane.add(enterInt, 0, 0);
gPane.add(enterText, 1, 0);
gPane.add(binaryText, 2, 0);
GridPane.setConstraints(binaryText, 2, 0, 2, 4);
gPane.add(mCEscher, 0, 1);
GridPane.setColumnSpan(mCEscher, 2);
binaryText.setEditable(false);
scrollPane.setContent(binaryText);
primaryStage.setTitle("Binary Converter");
primaryStage.setScene(scene);
primaryStage.show();
}
private VBox titleBox() throws Exception{
VBox titlesBox = new VBox();
Text title = new Text("Welcome to GUI #5");
title.setStyle("-fx-text-fill: #000000");
title.setFont(Font.font("Monospace",FontWeight.NORMAL, FontPosture.REGULAR, 30));
Text subtitle = new Text("I think this class will be the death of me, "
+ "\nI really wish I could get one thing right...");
subtitle.setFont(Font.font("Monospace", FontWeight.NORMAL, FontPosture.ITALIC, 10));
subtitle.setStyle("-fx-text-fill: #000000");
Text subsubtitle = new Text("Please enter an integer.");
subsubtitle.setFont(Font.font("Monospace", FontWeight.NORMAL, FontPosture.ITALIC, 7));
subsubtitle.setStyle("-fx-text-fill: #000000");
Text subsubsubtitle = new Text("Please dear God work");
subsubsubtitle.setFont(Font.font("Monospace", FontWeight.NORMAL, FontPosture.ITALIC, 3));
subsubsubtitle.setStyle("-fx-text-fill: #000000");
titlesBox.setAlignment(Pos.TOP_CENTER);
titlesBox.getChildren().addAll(title, subtitle, subsubtitle, subsubsubtitle);
return titlesBox;
}
private HBox buttonBox() throws Exception{
HBox buttbox = new HBox();
buttbox.getChildren().addAll(convert, clear, exitBtn);
buttbox.setAlignment(Pos.CENTER);
buttbox.setMargin(clear,new Insets(10,10,10,10));
convert.setOnAction(new convertHandler());
clear.setOnAction(new resetHandler());
exitBtn.setOnAction(e ->{
Platform.exit();
});
return buttbox;
}
class convertHandler implements EventHandler<ActionEvent>{
#Override
public void handle(ActionEvent event){
if (enterText.getText().trim().isEmpty()){
Alert alert = new Alert(Alert.AlertType.WARNING);
alert.setTitle("Warning");
alert.setHeaderText("Required Fields Empty");
alert.setContentText("You must enter an integer.\n"
+ "Please try again.");
alert.showAndWait();
}
else if (!enterText.getText().trim().isEmpty()){
try {
Integer.parseInt(enterText.getText());
} catch (NumberFormatException nfe){
Alert alert = new Alert(Alert.AlertType.WARNING);
alert.setTitle("Warning");
alert.setHeaderText("Field is not an integer");
alert.setContentText("The entered text is not an integer.\n"
+ "Please try again.");
alert.showAndWait();
}
} else {
int enteredNumb = Integer.parseInt(enterText.getText());
ToBinary(enteredNumb);
Collections.reverse(remainderList);
binaryText.appendText("-------------------------------\n");
for (int i = 0; i < remainderList.size(); i++){
binaryText.setText(remainderList.get(i));
}
}
}
}
class resetHandler implements EventHandler<ActionEvent>{
#Override
public void handle(ActionEvent event){
remainderList.clear();
binaryText.clear();
enterText.clear();
}
}
public int ToBinary(int number) {
/* Define variable required in method */
if (number == 0) {
return 0;
} else {
int remainder = number - 2 * (number / 2);
String remainderString = Integer.toString(remainder);
String numberString = Integer.toString(number);
remainderList.add(remainderString);
String number2String = Integer.toString(number);
binaryText.appendText(numberString + "/2= " + number2String + " Remainder "
+ remainderString + "\n");
ToBinary(number / 2); //Recurrsive call to method
}
return number;
}
} //End Class Sheppard_Week5
You simply never reach the call of the ToBinary method in convertHandler.handle:
if (enterText.getText().trim().isEmpty()){
doA();
}
else if (!enterText.getText().trim().isEmpty()){
doB();
} else {
doC();
}
can have exactly 3 outcomes:
An exception is thrown by enterText.getText().trim().isEmpty(), e.g. a NullPointerException and the code proceeds with the next surrounding catch block with an appropriate catch clause.
enterText.getText().trim().isEmpty() yields true and doA() is executed
enterText.getText().trim().isEmpty() yields false and doB() is executed
since your call to toBinary is in the doC() part, it's never executed. If you need to proceed if parsing succeeds you need to do this in the try block or exit the method in the catch block and put the logic from the last else right behind the last catch:
try {
int enteredNumb = Integer.parseInt(enterText.getText());
ToBinary(enteredNumb);
Collections.reverse(remainderList);
binaryText.appendText("-------------------------------\n");
for (int i = 0; i < remainderList.size(); i++){
binaryText.setText(remainderList.get(i));
}
} catch (NumberFormatException nfe){
Alert alert = new Alert(Alert.AlertType.WARNING);
alert.setTitle("Warning");
alert.setHeaderText("Field is not an integer");
alert.setContentText("The entered text is not an integer.\n"
+ "Please try again.");
alert.showAndWait();
}
or
int enteredNumb;
try {
enteredNumb = Integer.parseInt(enterText.getText());
} catch (NumberFormatException nfe){
Alert alert = new Alert(Alert.AlertType.WARNING);
alert.setTitle("Warning");
alert.setHeaderText("Field is not an integer");
alert.setContentText("The entered text is not an integer.\n"
+ "Please try again.");
alert.showAndWait();
return;
}
ToBinary(enteredNumb);
Collections.reverse(remainderList);
binaryText.appendText("-------------------------------\n");
for (int i = 0; i < remainderList.size(); i++){
binaryText.setText(remainderList.get(i));
}
Additional notes:
int remainder = number - 2 * (number / 2);
there already is a way to do this in a single operation:
int remainder = number % 2;
In this case assuming non-negative number it can also be optimized using a binary operator which should be a bit faster than the remainder operator:
int remainder = number & 1; // extract least significant bit
I guess you're supposed to return something different from the ToBinary method. Otherwise you could easily use void as return type.
If you want the remainders to be ordered from the most significant to the least significant bits, you need to do the recursive call before adding to the list. This way you don't need to reverse the list after the initial call to toBinary.
You need to call remainderList.clear() unless you require the user to click the clear button between clicks on the convert button. Otherwise the list will still contain the last results.
Related
So I have a user field that they can type in 1-10 for number of players:
playersFld.setTextFormatter(new TextFormatter<String>(playersValidator));
custartBtn.addEventHandler(MouseEvent.MOUSE_CLICKED, actionEvent4 -> {
Integer playersNum = Integer.valueOf(playersFld.getText());
if (!playersNum.equals("")) {
System.out.println("Got the values");
try {
FXMLLoader loader = new FXMLLoader(getClass().getResource("/views/score_page.fxml"));
root = loader.load();
ScorePageCtrl scorePageCtrl = loader.getController();
scorePageCtrl.displayDate(strDate);
scorePageCtrl.recievePlayers(playersNum);
stage = (Stage) ((Node) actionEvent4.getSource()).getScene().getWindow();
scene = new Scene(root);
stage.setScene(scene);
stage.show();
} catch (IOException e) {
e.printStackTrace();
}
} else {
System.out.println("missing value(s)");
}
});
I pass that to the next page's controller in this method:
public int recievePlayers(int plrNum){
System.out.println("Players: " + plrNum);
return plrNum;
}
The sout let's me know I'm getting the correct number, but I can't seem to pass the returned value to a for array
AtomicInteger tabs = new AtomicInteger(2);
for (int i = 2; i <= recievePlayers(); i++) {
if (tabs.get() <= 10) {
tabPaneSP.getTabs().add(new Tab("Player" + tabs.getAndIncrement()));
tabPaneSP.getSelectionModel().selectLast();
} else {
System.out.println("No more homies");
}
}
I've tried the method name, the integer name, making int p; and then attaching it to the return, but nothing seems to work.
EDIT:
So I've tried changing things and I can get it to work but for some reason it only fires every other time, which is less than ideal.
I changed:
public static int plrNum;
public int receivePlayers(int players) {
System.out.println("Players: " + players);
//Used to make sure I get the number datesSP.setText(String.valueOf(players));
return this.plrNum = players;
}
And use this to instantiate so I can put it in the for loop:
int n = plrNum;
But there has to be a better way.
EDIT: So I've updated my gist to reflect the current code that is working, but for some reason it only works every other time.
https://gist.github.com/Spider-Ian/3d5c777171d7ad632e9b71943fcf950c
Your method takes a parameter, but you are calling it without. Change it to
public int recievePlayers() {
and it should work.
Bonus tip! Change it to
public int receivePlayers() {
to make it easier to use.
For example, this way can work also.
public class Player {
public int num;
public int recievePlayers(int plrNum){
System.out.println("Players: " + plrNum);
return this.num = plrNum;
}
}
public static void main(String[] args) {
Player player = new Player();
player.recievePlayers(3);
int n = player.num;
AtomicInteger tabs = new AtomicInteger(2);
for (int i = 2; i <= n; i++) {
if (tabs.get() <= 10) {
tabPaneSP.getTabs().add(new Tab("Player" + tabs.getAndIncrement()));
tabPaneSP.getSelectionModel().selectLast();
} else {
System.out.println("No more homies");
}
}
}
Okay apparently there is a very strict course of events that happen in a controller. It loads FXML items, it initializes and then it looks for other methods and fun things to play with. So, the way to make sure that the tabs get the data first, I can call them ahead of time with the previous controller.
threeThirBtn.addEventHandler(MouseEvent.MOUSE_CLICKED, actionEvent1 -> {
try {
FXMLLoader loader = new FXMLLoader(getClass().getResource("/views/score_page.fxml"));
root = loader.load();
ScorePageCtrl scorePageCtrl = loader.getController();
scorePageCtrl.displayDate(strDate);
scorePageCtrl.displayEvent("3 x 30");
scorePageCtrl.receivePlayers(3);
scorePageCtrl.receivePlays(3);
scorePageCtrl.receiveRounds(30);
//**Here is where I told the method to get the returned value before initialization**
scorePageCtrl.addTabs();
scorePageCtrl.addRows();
stage = (Stage) ((Node) actionEvent1.getSource()).getScene().getWindow();
scene = new Scene(root);
stage.setScene(scene);
stage.show();
} catch (IOException e) {
e.printStackTrace();
}
//TODO: Set the row and column numbers to thirty rows and three columns
System.out.println("3 x 30 button clicked");
});
I did have to move the AtomicInteger out of the initialize and into its own method.
public void addTabs() {
int plr = plrNum;
AtomicInteger tabs = new AtomicInteger(2);
for (int i = 2; i <= plr; i++) {
if (tabs.get() <= 10) {
tabPaneSP.getTabs().add(new Tab("Player" + tabs.getAndIncrement()));
tabPaneSP.getSelectionModel().selectLast();
} else {
System.out.println("No more homies");
}
}
addPlayerBtn.setOnAction(event -> {
if (tabs.get() <= 10) {
tabPaneSP.getTabs().add(new Tab("Player" + tabs.getAndIncrement()));
tabPaneSP.getSelectionModel().selectLast();
} else {
System.out.println("No more homies");
}
});
}
The only think I'm still not happy with is the amount of hoops to get a get value to return as an useable integer.
I'm currently setting up a quiz program right now, where the code will loop 20 times. There are 20 question, 80 answers (4 to each question) and the program will set JButtons and action listeners to listen for the user's answer for each question, then call the original quiz loop again from the correct or incorrect answer.
However, the program I'm having is that the program will display question 1, then question 2, but then question 4, 8, 16 and finally 20 since it cannot double anymore.
I've tried:
Breakpointing the value of the currentQuestion variable, as I believe this is the one which is doubling and causing the problem.
Creating a new method named updateQuestionAndAnswer to ensure that it's not a misclick.
Removing the other three action listeners, which helped me to find that it was whatever action listener that I clicked that was repeatedly being called. E.g if it was on Question 8 and I clicked listener 3, it would call listener 3 another 8 times.
I've enclosed the code below I think will be useful. All variables that you cannot see defined within here, are defined to 0 or "" in a static context outside of methods at the top of my program.
* Defines and places all of the content for the Game page.
* #throws IOException
*/
public void setupGamePanel() throws IOException {
// Game page card constructor
card2 = new JPanel() {
// Make the window the specified sizes
public Dimension getPreferredSize() {
Dimension size = super.getPreferredSize();
size.width += extraWindowWidth;
size.height += extraWindowHeight;
return size;
}
};
// JAVA COMPONENT DEFINITIONS
String[] openingDialogue = new String[]{"<html><span style='font-size:20px;'>We need your help. After Junko Enoshima took over Hope’s Peak Academy, she trapped the entire of Class 78 inside a monstrous killing game! My creator, Chihiro Fujisaki, is one of them.", "<html><span style='font-size:20px;'>I managed to patch into the systems that the Ultimate ******** setup when he fell into despair, but we’ve been hit with a security system implemented by Jin Kirigiri before he…", "<html><span style='font-size:20px;'>Anyway, we need to get a good enough score out of twenty quiz questions in order to get inside the network, where my creator should be waiting for me.", "<html><span style='font-size:20px;'>Let’s do this. Answer the questions as best as you can. Good luck.", ""};
// Score counter
scoreCounter.setText("<html><span style='font-size:30px;'>Score: " + String.valueOf(score) + "</html>");
// Alter ego dialogue text
dialogueText = new JLabel("");
dialogueText.setText("<html><span style='font-size:20px;'>You’re...actually here? You survived. You're inside the first versions of the Neo World Program!</html>");
// Buttons
beginButton = new JButton("BEGIN THE GAME!");
continueButton = new JButton("Continue Dialogue");
// Images
alterEgoImage = ImageIO.read(new File("AlterEgo/alterego.png"));
BufferedImage alterEgoNeutral = ImageIO.read(new File("AlterEgo/neutral.jpeg"));
alterEgoImageLabel = new JLabel(new ImageIcon(alterEgoImage));
// X, Y. Width, Height
alterEgoImageLabel.setBounds(510, 150, 550, 300);
scoreCounter.setBounds(15, 15, 250, 40);
beginButton.setBounds(650, 480, 250, 40);
continueButton.setBounds(650, 480, 250, 40);
dialogueText.setBounds(500, 490, 750, 300);
// Allows for a more dynamic and fluid layout of the page where bounds are specified.
card2.setLayout(null);
// Add the components to the page
card2.add(beginButton);
card2.add(continueButton);
card2.add(dialogueText);
card2.add(scoreCounter);
card2.add(alterEgoImageLabel);
continueButton.setVisible(false);
dialogueText.setVisible(false);
// BEGIN THE QUIZ GAME
// Game begins when the button is clicked
beginButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
beginButton.setVisible(false);
continueButton.setVisible(true);
dialogueText.setVisible(true);
}
});
// Continue the opening dialogue with the continue button, and immediately begin the quiz after the dialogue has finished.
continueButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
dialogueText.setText(openingDialogue[openDialoguePos]);
openDialoguePos++;
if(openDialoguePos == openingDialogue.length) {
continueButton.setVisible(false);
dialogueText.setVisible(false);
// SET THE ALTER EGO IMAGE TO THE NEUTRAL ONE TO BEGIN THE GAME
try {
quizProcess();
} catch(IOException excep) {
// Handle the error here
}
//quizProcess();
}
}
});
} // end setupGamePanel()
/**
* Defines and places all of the content for the leaderboard page.
* #throws IOException
*/
public void setupLeaderboardPanel() throws IOException {
// Leaderboard page card constructor
card3 = new JPanel();
card3.add(new JTextField("TextField", 20));
} // end setupLeaderboardPanel()
/**
* The top level method for the quiz game.
* #throws IOException
*/
public void quizProcess() throws IOException {
// TOP LEVEL METHOD BEGINS
setupQuizUI(answerButtons);
readData(questions, answers);
quizLoop(questions, answers, answerButtons);
}
public void quizLoop(String questions[], String[] answers, JButton[] answerButtons) {
System.out.println("A quiz loop is being initiated");
moveOntoNextQuestion(questions, answers, answerButtons);
//assignData();
checkCorrectQuestion(answerButtons);
}
/**
* Initialise and setup the answer buttons and question text.
*/
public void setupQuizUI(JButton[] answerButtons) {
// Alter ego dialogue text
questionText.setText("<html><span style='font-size:20px;'<</html>");
questionText.setBounds(550, 450, 350, 150);
card2.add(questionText);
//System.out.println("Fifth read: " + currentQuestion + 25);
for(int i = 0; i < answerButtons.length; i++) {
answerButtons[i] = new JButton("Test");
}
// Bound setting (X, Y, Width, Height)
answerButtons[0].setBounds(150, 580, 200, 100);
answerButtons[1].setBounds(550, 580, 200, 100);
answerButtons[2].setBounds(950, 580, 200, 100);
answerButtons[3].setBounds(1350, 580, 200, 100);
// Adding to the JFrame
card2.add(answerButtons[0]);
card2.add(answerButtons[1]);
card2.add(answerButtons[2]);
card2.add(answerButtons[3]);
}
/**
* Read in the data from the database to the arrays.
* #param
*/
public void readData(String[] questions, String[] answers) {
//System.out.println("First read: " + currentQuestion + 5);
questions[0] = "Question 1";
questions[1] = "Question 2";
for(int i = 0; i < questions.length; i++) {
questions[i] = "Question " + (i + 1);
}
for(int i = 0; i < answers.length; i++) {
answers[i] = "Answer" + (i + 1);
}
for(int i = 0; i < correctAnswers.length; i+= 4) {
correctAnswers[i] = 0;
correctAnswers[i + 1] = 1;
correctAnswers[i + 2] = 2;
correctAnswers[i + 3] = 3;
}
/*answers[0] = "Answer 1";
answers[1] = "Answer 2";
answers[2] = "Answer 3";
answers[3] = "Answer 4";
answers[4] = "Answer 5";
answers[5] = "Answer 6";
answers[6] = "Answer 7";
answers[7] = "Answer 8";*/
}
/**
*
* Moves onto the next question and prepares the data for read-in
* Assign the next question to the text field
* Assign the next answers to the buttons
*/
public void moveOntoNextQuestion(String questions[], String[] answers, JButton[] answerButtons) {
//System.out.println("-=-=-=-=-=-=-moveOntoNextQuestion-=-=-=-=-=-=-=-");
String nextQuestion = questions[currentQuestion];
questionText.setText(questions[currentQuestion]);
//System.out.println("The current question is " + questions[currentQuestion]);
//System.out.println("The current answer number is " + currentAnswer);
answerButtons[0].setText(answers[currentAnswer]);
answerButtons[1].setText(answers[currentAnswer + 1]);
answerButtons[2].setText(answers[currentAnswer + 2]);
answerButtons[3].setText(answers[currentAnswer + 3]);
//System.out.println("-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-");
}
/**
* #param answer
* Check if the clicked answer was correct.
*/
public void checkCorrectQuestion(JButton[] answerButtons) {
int correctAnswer = correctAnswers[currentQuestion];
//System.out.println("Current correct answer is " + correctAnswer);
answerButtons[0].addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if(correctAnswer == 0) {
System.out.println("Button 1 is correct!");
score += 10;
updateScore(scoreCounter);
try {
correctAnswerAlterEgo(alterEgoImage, alterEgoImageLabel);
} catch(IOException excep) {
// Handle the error here
}
} else {
System.out.println("Button 1 is wrong!");
score -= 5;
updateScore(scoreCounter);
}
updateQuestionAndAnswer();
//currentQuestion += 1;
//System.out.println("currentQuestion value is " + currentQuestion);
//currentAnswer += 4;
//System.out.println("This is the quizLoop for button 1");
quizLoop(questions, answers, answerButtons);
}
});
**WITHIN HERE ARE THE OTHER THREE ACTION LISTENERS FOR THE BUTTONS. THEY ARE THE EXACT SAME EXCEPT [1], [2] and [3].**
}
public void updateQuestionAndAnswer() {
currentQuestion = currentQuestion + 1;
currentAnswer = currentAnswer + 4;
}
public void updateScore(JLabel scoreCounter) {
scoreCounter.setText("<html><span style='font-size:30px;'>Score: " + String.valueOf(score) + "</html>");
}
public void correctAnswerAlterEgo(BufferedImage alterEgoImage, JLabel alterEgoImageLabel) throws IOException {
System.out.println("Correct answer alter ego method called!");
scoreCounter.setText("<html><span style='font-size:30px;'>TEST: </html>");
// Images
BufferedImage[] happyImages = new BufferedImage[]{ ImageIO.read(new File("AlterEgo/excited.jpeg")), ImageIO.read(new File("AlterEgo/happy.jpeg")), ImageIO.read(new File("AlterEgo/shocked.jpeg"))};
alterEgoImage = ImageIO.read(new File("AlterEgo/class78.jpg"));
alterEgoImageLabel = new JLabel(new ImageIcon(alterEgoImage));
card2.add(alterEgoImageLabel);
card2.remove(alterEgoImageLabel);
}
public void wrongAnswerAlterEgo() {
}```
Thank you for your help,
public class Memory extends JFrame {
private static final long serialVersionUID = -2065145900871059367L;
private JPanel contentPane;
public static void main(String[] args) { //auto generated from WindowBuilder
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Memory frame = new Memory();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
JButton[] cards = new JButton[12];
int [] flippedNum = new int[12];
Icon [] catImg = new Icon[12];
{
catImg[0]= new ImageIcon(getClass().getResource("2faceszd.jpg"));
catImg[1] = new ImageIcon(getClass().getResource("blkctszd.jpg"));
catImg[2]= new ImageIcon(getClass().getResource("ct&mszd.png"));
catImg[3]= new ImageIcon(getClass().getResource("floofctszd.jpg"));
catImg[4]= new ImageIcon(getClass().getResource("orngctszd.jpg"));
catImg[5]= new ImageIcon(getClass().getResource("siamctszd.jpg"));
catImg[6]= new ImageIcon(getClass().getResource("2faceszd.jpg"));
catImg[7] = new ImageIcon(getClass().getResource("blkctszd.jpg"));
catImg[8]= new ImageIcon(getClass().getResource("ct&mszd.png"));
catImg[9]= new ImageIcon(getClass().getResource("floofctszd.jpg"));
catImg[10]= new ImageIcon(getClass().getResource("orngctszd.jpg"));
catImg[11]= new ImageIcon(getClass().getResource("siamctszd.jpg"));
} //6 images added twice
Icon photo = new ImageIcon(getClass().getResource("BG.png"));
static List<Integer> cats = new ArrayList<Integer>();{
cats.add(1); cats.add(1);
cats.add(2); cats.add(2);
cats.add(3); cats.add(3);
cats.add(4); cats.add(4);
cats.add(5); cats.add(5);
cats.add(6); cats.add(6);
}
static Random kitty = new Random();
public static int getCardAssignment(){
int cat = kitty.nextInt(cats.size());
int ucat = cats.get(cat);
cats.remove(cat);
return ucat;
} returns a random number to be assigned to an icon
//building the frame
public Memory() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 650, 500);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
contentPane.setLayout(new BorderLayout(0, 0));
setContentPane(contentPane);
JPanel title = new JPanel();
title.setName("");
title.setFont(new Font("Tahoma", Font.PLAIN, 16));
title.setBackground(Color.PINK);
contentPane.add(title, BorderLayout.NORTH);
JLabel gameName = new JLabel("Memory Game");
title.add(gameName);
gameName.setFont(new Font("Arial Black", Font.PLAIN, 16));
gameName.setBackground(Color.PINK);
gameName.setEnabled(false);
JPanel cardDisplay = new JPanel();
cardDisplay.setBackground(Color.PINK);
cardDisplay.setFont(new Font("Arial Black", Font.PLAIN, 16));
cardDisplay.setBorder(new EmptyBorder(10, 10, 10, 10));
contentPane.add(cardDisplay, BorderLayout.CENTER);
cardDisplay.setLayout(new GridLayout(3, 4, 10, 10));
ButtonClickEventHandler clickIt = new ButtonClickEventHandler();
for(int i = 0; i < cards.length; i ++){
cards[i] = new JButton(); // new button
flippedNum[i] = getCardAssignment(); //card# assigned to cat icon
cards[i].setIcon(photo); //set background image
cards[i].addActionListener(clickIt); //when you click it
cardDisplay.add(cards[i]); //show them all
System.out.println("background displayed");
//sysprint statements are for testing the output stream only
}
}
private class ButtonClickEventHandler implements ActionListener{
private int q = 0; //# of clickes, like switch statement w/o userinput
private int l; // = 0; records number location when clicked
#Override
public void actionPerformed(ActionEvent e) {
for(int i = 0; i < 12; i ++){
if (q == 0){ //at zero all enabled cards/buttons are face up
if(cards[i] == e.getSource()){//first card clicked //start state
System.out.println("q is 0");
System.out.println("Selection was number " + i);
l = i; // record the click for the next state.
//sets the icon to a cat image w/num [flipped num]
cards[i].setEnabled(false);
// prevents user from clicking the same card twice for a match
cards[i].setIcon(catImg[flippedNum[i]])
cards[i].setDisabledIcon(catImg[flippedNum[i]]);
//prevents the icon from being grayed out when clicked
//setting the icon and THEN the disabled icon shows
//non gray'd out image when clicked that cannot be clicked again
q = 1;
System.out.println("q is now 1");
}
}
else if(q == 1) { //if one card is already clicked, second click
System.out.println("q was not 0, now is 1");
if(cards[i] == e.getSource()){
cards[i].setIcon(catImg[flippedNum[i]]);
System.out.println("first was " + flippedNum[l] + " Second was " + flippedNum[i]);
cards[i].setIcon(catImg[flippedNum[i]]);
q = 2;
}
if(q == 2){
System.out.println("Timer started");
cards[l].doClick(1500);
//i tried moving this up to before q=2, no luck
if(flippedNum[l] == flippedNum[i]){
System.out.println("They Match!!");
cards[i].setEnabled(false);
// permanenty sets the button as disabled
cards[l].setEnabled(false);
q=0;
System.out.println("end of turn q is zero, find another match");
}else {
System.out.println("Dont Match");
cards[i].setEnabled(true);
cards[l].setEnabled(true);
cards[i].setIcon(photo);
cards[l].setIcon(photo);
q = 0;
System.out.println("end of turn, back to start, q = 0");
}
}
}
}
}
}
}
The code SHOULD let the user click on one image where it is displayed and disabled so you can't click it a second time and match it to itself. the second click SHOULD reveal the second card (it doesn't) and start the timer (it does)
with in the q=2 section, the match check is still preformed on the image the user can't see and the timer still flips the first card back over after 1500mills. and if there is a match both cards should stay image side up (it does) and grayed out (it doesn't unless i remove the cards[i].setEnabled, even the previously unseen card turns gray when the .setEnabled is off in the q=0 statement)
I've had teachers, tutors, and friends look over this without any progress, PLEASE help. ty.
SAMPLE OUTPUT:
background displayed
// this is printed 12 times
//once for each card
Selection was number 1 // selected the 4th card in the first row
q is now 1
q was not 0, now is 1
q was not 0, now is 1
q was not 0, now is 1
q was not 0, now is 1
q was not 0, now is 1
q was not 0, now is 1
q was not 0, now is 1
q was not 0, now is 1
q was not 0, now is 1
q was not 0, now is 1
q was not 0, now is 1
q was not 0, now is 1
//selected the second card in the first row which did not "Show"
q was not 0, now is 1
q was not 0, now is 1
first was 6 Second was 1
Timer started
Don't Match// first card flipped back to background after 1.5 seconds
end of turn, back to start, q = 0
q is 0
Selection was number 2 // selected 3rd card in first row
q is now 1
q was not 0, now is 1
q was not 0, now is 1
q was not 0, now is 1
q was not 0, now is 1
q was not 0, now is 1
q was not 0, now is 1
q was not 0, now is 1
q was not 0, now is 1
q was not 0, now is 1
q was not 0, now is 1
q was not 0, now is 1
first was 6 Second was 6 // second image selected, didn't show
Timer started
They Match!! // both images are revealed! neither is gray'd out
end of turn q is zero, find another match
Basically, based on your code doClick(long) will make the button appear pressed, it will not delay the code and will cause actionPerformed to be called again ... when you really don't want it to be.
The solution you seem to be looking for is a Swing Timer, see How to use Swing Timers for more details
I butchered your code a little to get "something" working, it will at least display the second card 1.5 seconds.
private class ButtonClickEventHandler implements ActionListener {
private int q = 0; //# of clickes, like switch statement w/o userinput
private int l; // = 0; records number location when clicked
#Override
public void actionPerformed(ActionEvent e) {
for (int i = 0; i < 12; i++) {
if (q == 0) { //at zero all enabled cards/buttons are face up
if (cards[i] == e.getSource()) {//first card clicked //start state
System.out.println("q is 0");
System.out.println("Selection was number " + i);
l = i; // record the click for the next state.
//sets the icon to a cat image w/num [flipped num]
cards[i].setEnabled(false);
// prevents user from clicking the same card twice for a match
cards[i].setIcon(catImg[flippedNum[i]]);
cards[i].setDisabledIcon(catImg[flippedNum[i]]);
//prevents the icon from being grayed out when clicked
//setting the icon and THEN the disabled icon shows
//non gray'd out image when clicked that cannot be clicked again
q = 1;
System.out.println("q is now 1");
break;
}
} else if (q == 1) { //if one card is already clicked, second click
System.out.println("q was not 0, now is 1");
if (cards[i] == e.getSource()) {
cards[i].setIcon(catImg[flippedNum[i]]);
System.out.println("first was " + flippedNum[l] + " Second was " + flippedNum[i]);
flipFlop(l, i);
q = 0;
break;
}
}
}
}
protected void flipFlop(int l, int i) {
Timer timer = new Timer(1500, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("Timer started");
//cards[l].doClick(1500);
//i tried moving this up to before q=2, no luck
if (flippedNum[l] == flippedNum[i]) {
System.out.println("They Match!!");
cards[i].setEnabled(false);
// permanenty sets the button as disabled
cards[l].setEnabled(false);
System.out.println("end of turn q is zero, find another match");
} else {
System.out.println("Dont Match");
cards[i].setEnabled(true);
cards[l].setEnabled(true);
cards[i].setIcon(photo);
cards[l].setIcon(photo);
System.out.println("end of turn, back to start, q = 0");
}
}
});
timer.setRepeats(false);
timer.start();
}
}
You actionPerformed method could use a little more optimising, once you have established some action, you should break out of the loop, as no further processing should be done, let's face it, once you know which button was clicked and if it was the first or second button, why should you keep iterating?
I ran out of ideas on how to perform search in table layout using textfield. I just want to match the text of textfield with 1st column text, if it exist, show the entire row containing that text.I have done it in list and table component but in table layout everything i do is just not working. Any help is appreciated.
TableLayout tl1 = new TableLayout(1, 2);
Container containerTableData = new Container(tl1);
for (int i = 1; i < 3; i++) {
Container tableNameDataContainer = new Container(new FlowLayout(Component.CENTER, Component.CENTER));
tableNameData = new TextArea("Table Name " + i);
tableNameDataContainer.add(tableNameData);
Container inaugurationDateDataContainer = new Container(new FlowLayout(Component.CENTER, Component.CENTER));
inaugurationDateData = new TextArea("Inauguration Date 1");
inaugurationDateDataContainer.add(inaugurationDateData);
containerTableData.add(tl1.createConstraint().widthPercentage(50), tableNameDataContainer);
containerTableData.add(tl1.createConstraint().widthPercentage(50), inaugurationDateDataContainer);
containerTableData.revalidate();
}
TextField searchTextField = new TextField();
searchTextField.addDataChangeListener(new DataChangedListener() {
#Override
public void dataChanged(int type, int index) {
String getTextAreaData = tableNameData.getText();
String getTextField = searchTextField.getText();
if (getTextAreaData.startsWith(getTextField)) {
}
}
}
Update 1:
To add black and white strips design to the table as in fig below:
Mycode so far:
for (int i = 1; i < 3; i++) {
Container tableNameDataContainer = new Container(new FlowLayout(Component.CENTER, Component.CENTER));
tableNameData = new TextArea("Table Name " + i);
tableData(tableNameData, i, tableNameDataContainer);
tableNameDataContainer.add(tableNameData);
Container inaugurationDateDataContainer = new Container(new FlowLayout(Component.CENTER, Component.CENTER));
inaugurationDateData = new TextArea("Inauguration Date 1");
tableData(inaugurationDateData, i, inaugurationDateDataContainer);
inaugurationDateDataContainer.add(inaugurationDateData);
containerTableData.add(tl1.createConstraint().widthPercentage(50), tableNameDataContainer);
containerTableData.add(tl1.createConstraint().widthPercentage(50), inaugurationDateDataContainer);
}
method to add desired style
public void tableData(TextArea textAreaName, int i, Container c) {
textAreaName.setName(textAreaName.getText());
c.setName("c" + i);
zeroPaddingMargin(textAreaName);
zeroPaddingMargin(c);
textAreaName.setUIID(textAreaName.getText());
textAreaName.getAllStyles().setFont(Font.createSystemFont(Font.FACE_SYSTEM, Font.STYLE_PLAIN, Font.SIZE_SMALL));
textAreaName.setEditable(false);
textAreaName.setGrowByContent(true);
textAreaName.setGrowLimit(2);
textAreaName.getAllStyles().setBgTransparency(0);
c.getAllStyles().setBgTransparency(255);
textAreaName.getAllStyles().setFgColor(0x000000);
if (i % 2 == 0) {
c.getAllStyles().setBgColor(0xcccccc);
} else {
c.getAllStyles().setBgColor(0xffffff);
}
textAreaName.getAllStyles().setPadding(0, 0, 0, 0);
textAreaName.getAllStyles().setMargin(0, 0, 0, 0);
textAreaName.getAllStyles().setAlignment(Component.CENTER);
}
public void zeroPaddingMargin(Component a) {
a.setUIID("Uiid" + a.getName());
a.getAllStyles().setPadding(0, 0, 0, 0);
a.getAllStyles().setMargin(0, 0, 0, 0);
}
The black and white strip style in table rows appears as abov img at first but all the styles disappears as soon as i search in the textfield. I managed to achieve those styles somehow though i think it is not the standard way to do that. Is there any standard way to achieve that?
Didn't try it but I'm guessing this should work. It will require making containerTableData final:
searchTextField.addDataChangeListener(new DataChangedListener() {
#Override
public void dataChanged(int type, int index) {
String getTextField = searchTextField.getText().toLowerCase();
int counter = 0;
boolean show = false;
for(Component c : containerTableData) {
if(counter % 2 == 0) {
Container cnt = (Container)c;
TextArea ta = (TextArea)cnt.getComponentAt(0);
show = ta.getText().toLowerCase().indexOf(getTextField) > -1);
}
counter++;
c.setHidden(!show);
c.setVisible(show);
}
containerTableData.animateLayout(200);
}
}
Edited the answer to hide/show the entire row. It relies on searching only in the first column and on there being two columns but that should be easily adaptable.
I have a swing application that involves a Container, a JButton, a JPanel, a JTextArea and an array. The array of String objects and contains 5 elements.
I want to return all elements in the array by a method and compare each of them with the element entered by end user in the text area, after pressing a JButton.
If they are same a JOptionPane message displaying the matched element should appear. If they are different a JoptionPane should show a message saying Number Entered is not found in myArray else, a message saying please Enter something" should appear
The problem I face is that when the end user enters a valid number a JOptionPane message saying: Number Entered is not found in myArray appear many times, e.g. when entering 4, a JoptionPane message saying
Number Entered is not found in myArray appear 3 times.
How do I prevent this message if the entered element is correct?
import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
public class Array_Search extends JFrame {
String myString[] = { "1", "2", "3", "4", "5" };
public String[] get_Element() {
String str[] = new String[myString.length];
str = myString;
return str;
}
public Array_Search() {
Container pane = getContentPane();
JPanel panel = new JPanel();
final JTextField txt = new JTextField(
" ");
JButton b = new JButton("Click Me ");
panel.add(b);
panel.add(txt);
pane.add(panel);
b.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
String[] str = get_Element();
String s2 = txt.getText().trim();
if (s2 != null && s2.length() > 0)
for (int i = 0; i < str.length; i++) {
if (s2.equals(str[i].trim())) {
JOptionPane option = new JOptionPane();
option.showInputDialog("" + str[i]);
} else {
JOptionPane option = new JOptionPane();
option.showInputDialog("Number Entered is not found in myArray");
}
}
else {
JOptionPane o = new JOptionPane();
o.showInputDialog("please Enter something");
}
}
});
}
public static void main(String[] args) {
Array_Search myArray = new Array_Search();
myArray.setSize(500, 500);
myArray.setVisible(true);
}
}
Your code shows message every time when non-matching element is found.
Instead, you need to look through all of the elements and display Not found message after that.
Something like this should work:
...
if (s2 != null && s2.length() > 0) {
boolean isFound = false;
for (int i = 0; i < str.length; i++) {
if (s2.equals(str[i].trim())) {
JOptionPane option = new JOptionPane();
option.showInputDialog("" + str[i]);
isFound = true;
break;
}
}
if(!isFound) {
JOptionPane option = new JOptionPane();
option.showInputDialog("Number Entered is not found in myArray");
}
} else
...
You return an empty Array in your get_Element method.
Can be fixed like that:
public void actionPerformed(ActionEvent ae) {
String [] str = get_Element(); // replace this
String [] str = myString; // with this
or change get_Element to:
public String[] get_Element() {
return myString;
}
Note: by Java code conventions use camel case for method names. getElement instead of get_Element.