Given my code below how can I make the paint applet open up when I run the main code? I thought extends would do the trick but nothing has come up. I can't get the program to execute one body part at a time. I don't have enough time, but at the very least I would like it to show the hangman drawing as soon as the main is executed.
import java.awt.Graphics;
import java.util.Scanner;
import javax.swing.JApplet;
public class HangmanLogic extends HangmanGuy {
public static void main(String[] args) {
int count = 0;
Scanner in = new Scanner(System.in);
System.out.println("Enter a 4 or 5 letter word and the computer will play hangman against you!");
String word = in.nextLine();
char[] letter = word.toCharArray();
for (int i = 0; i < letter.length; i++) {
letter[i] = 'a';
}
for (int i = 0; i < word.length(); i++){
for (int j = 48; j < 122; j++) {
count++;
if (letter[i] == word.charAt(i)) {
break;
} else {
letter[i] = (char)((int) j + 1);
}
}
}
System.out.println("Attempt to solve: " + count);
System.out.println("Your word is: ");
for (char letters : letter) {
System.out.print(letters);
}
}
}
import java.awt.Graphics;
import javax.swing.JApplet;
import java.awt.*;
public class HangmanGuy extends JApplet
{
public void paint (Graphics Page)
{
//gallows
Page.drawLine(0,300,20,300);
Page.drawLine(10,40,10,300);
Page.drawLine(10,40,80,40);
Page.drawLine(80,40,80,55);
//torso
Page.drawOval(50,55,50,55);
Page.drawOval(50,100,50,100);
//left arm and hand
Page.drawLine(50,150,40,110);
Page.drawLine(40,110, 45,100);
Page.drawLine(40,110, 25,100);
Page.drawLine(40,110, 25,115);
//right arm and hand
Page.drawLine(100,150,120,110);
Page.drawLine(120,110, 115,95);
Page.drawLine(120,110, 125,95);
Page.drawLine(120,110, 135,115);
//left leg and foot
Page.drawLine(80,200,100,250);
Page.drawLine(100,250, 115,260);
//right leg and foot
Page.drawLine(75,200,60,250);
Page.drawLine(60,250,45,260);
}
}
Two things.
Why should it. Nothing is controlling it. Applets are suppose to be loaded and controlled by browsers;
Why are you mixing GUI and console paradigms? User input from GUI's is suppose to come from UI components and controls, not the command line.
Start by taking a look at Creating a GUI With JFC/Swing.
I'd recommend moving your UI to a JFrame instead, until you understand the basics of how to build a UI as applets bring there own issues which can stump you if you don't already have some background in how the UI works.
In fact. Start with a JPanel and when you're ready, add it to an instance of JFrame. When that works, you can try adding the panel to a JApplet
Related
I made tic-tac-toe game using javafx. I'm new in java and I tried to make way to end game after winning or draw. There is no need to check if winning or losing or anything. I want put that text to end when you can't continue playing. I tried use array but I have no idea what to do.
Here is my code:
import java.util.ArrayList;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.scene.text.Font;
import javafx.stage.Stage;
public class ticTacToe extends Application {
private boolean turn;
private int[][] locations;
public RistinollaSovellus() {
turn = true;
locations = new int[3][3];
}
public static void main(String[] args) {
launch(ticTacToe.class);
}
#Override
public void start(Stage window) throws Exception {
boolean endGame = false;
BorderPane layout = new BorderPane();
Label text = new Label("Turn: X");
text.setFont(Font.font("Monospaced", 40));
layout.setTop(text);
GridPane array = new GridPane();
if (!endGame) {
for (int x = 1; x <= 3; x++) {
for (int y = 1; y <= 3; y++) {
Button btn = new Button(" ");
btn.setFont(Font.font("Monospaced", 40));
array.add(nappi, x, y);
locations[x][y] = 0;
btn.setOnAction((event) -> {
if (btn.getText().equals(" ")) {
if (turn) {
btn.setText("X");
text.setText("Turn: O");
turn = false;
} else if (!turn) {
btn.setText("O");
text.setText("Turn: X");
turn = true;
}
}
});
}
}
}
layout.setCenter(array);
Scene showing = new Scene(layout);
window.setScene(showing);
window.show();
}
}
The argument passed to btn.setOnAction() is an event listener and its logic is executed each time a user clicks the button.
https://docs.oracle.com/javase/8/javafx/api/javafx/scene/control/ButtonBase.html#setOnAction-javafx.event.EventHandler-
On a button click you want to check if the grid contains a valid tic-tac-toe configuration. To do this, you need to expand the listener and use the location array to check the current state of all buttons on the grid.
Once a valid combination of cells is found, you call Platform.exit() to stop the application.
EDIT: The x and y loop variables should start at 0 and go up to 2, otherwise an ArrayIndexOutOfBoundsException is thrown. The first index of an array is 0, not 1.
I'm not sure what you mean but I think if you implemented the game this far like if its working as it should then it'll be really easy for you to figure out how to end it.
See you can do many things here if any player wins you can just show an alert that player x won and give an option to either quit or restart the application all over, in case of a tie you can do the same.
Technically call the stop() method to stop all the processes and to end the game
Ok, I am sorry I am repeating questions that have already been asked but I have searched and searched and searched and nobody's answers seemed to have helped me... I tried the following questions:
JButton "stay pressed" after click in Java Applet
JButton stays pressed when focus stolen by JOptionPane
(I apologize if I'm just being dumb.. it is hard to relate to my code)
I have tried everything: using another thread to handle all the stuff, changing the JFrame to a JDialog as apparently they are "modal" so it would work independently. But that didn't seem to work either. I am stuck now so I am using my last resource (asking Stack Overflow).
What I am trying to do is get the user to enter some numbers in a textfield (4,2,7) then they press a JButton "Calculate Mean" and it finds the mean of the numbers and displays it in a JOptionPane message. When the user closes the JOptionPane dialog box they should be able to edit the numbers and do it again but the "Calculate Mean" button stays pressed and the user can't do anything but close the window. Even pressing the Tab key doesn't change anything. Does anyone know why this is? My code is down below:
PLEASE FORGIVE ME IF MY CODE IS HARD TO READ! I spent a very long time trying to indent it all correctly and I also tried to make it as short as possible by taking out any bits unrelated to the question. I was unsure which bits to take out so there still might be some unnecessary bits...
I am sorry for my messy code but this is the code:
package MathsProgram_II;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Arrays;
public class Mean implements Runnable {
JFrame meanFrame = new JFrame(); //I tried changing this to dialog
JPanel meanPanel = new JPanel(new GridBagLayout());
JLabel enterNums = new JLabel("Enter Numbers: ");
JTextField txtNums = new JTextField(20);
JButton calculate = new JButton("Calculate Mean");
boolean valid = true;
double answer = 0;
ButtonListener bl = new ButtonListener();
public synchronized double[] getArray() {
String nums = txtNums.getText();
String[] numsArray = nums.split(",");
double[] doubleArray = new double[numsArray.length];
if (nums.isEmpty() == true) {
JOptionPane.showMessageDialog(meanFrame, "You did not enter anything!",
"Fail", JOptionPane.ERROR_MESSAGE);
valid = false;
calculate.setEnabled(false);
} else {
for (int i = 0; i < numsArray.length; i++) {
try {
doubleArray[i] = Double.parseDouble(numsArray[i]);
} catch (NumberFormatException nfe) {
JOptionPane.showMessageDialog(meanFrame, "Error getting numbers!",
"Error", JOptionPane.ERROR_MESSAGE);
valid = false;
}
}
}
return doubleArray;
}
public synchronized void calculateMean() {
ArrayList<Double> numbersList = new ArrayList<Double>(20);
double[] theNumbers = getArray();
double tempAnswer = 0;
if (valid == true) {
int length = theNumbers.length;
for (int i = 0; i < theNumbers.length; i++) {
numbersList.add(theNumbers[i]);
}
for (int i = 0; i < length; i++) {
double y = numbersList.get(i);
tempAnswer = tempAnswer + y;
}
this.answer = tempAnswer / length;
//I ALSO TRIED DOING THIS:
txtNums.requestFocus();
calculate.setEnabled(false);
showMean();
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
}
}
}
public void showMean() {
JOptionPane.showMessageDialog(meanFrame, "The Mean: " + answer, "The Mean of Your Numbers", JOptionPane.INFORMATION_MESSAGE);
}
private class ButtonListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == calculate) {
meanFrame.remove(meanPanel);
meanFrame.setVisible(true);
calculateMean();
}
}
}
}
Don't remove the panel from your mainframe.
Don't use "synchronized" on your "calculateMean()" method. The code is executed on the Event Dispatch Thread (EDT) so it will be single threaded.
Don't use a Thread.sleep() on the EDT. This will prevent the GUI from repainting itself.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 9 years ago.
Improve this question
First, I figured I would try to write a standard hangman program without the GUI. I was able to succeed doing that. But I'm having trouble getting it into the GUI. I seem to struggle with GUIs the most.
I'll show my code so far. Maybe you guys could point me in the right direction? Or tell me if I'm on the right track?
Driver:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Hangman {
public static void main (String[] args){
JFrame frame = new JFrame ("Hangman");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
HangmanPanel hmp = new HangmanPanel();
frame.getContentPane().add(hmp);
frame.pack();
frame.setVisible(true);
}
}
Panel Class (this one is a bit messy, because I'm trying to experiment, and I'm going through a trial and error process I guess) My apologies if its logically off.
import java.awt.Panel;
import java.util.Scanner;
import java.util.Random;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class HangmanPanel extends JPanel {
private Hangman hm;
Scanner input = new Scanner(System.in);
final String[] WordList = { "ADA", "COBOL", "LOGO", "BASIC", "PROLOG",
"UBUNTU", "UHURU" };
String ChosenWord = WordList[(int) Math.random() * WordList.length];
StringBuilder display = new StringBuilder(ChosenWord.length());{
for (int i = 0; i < ChosenWord.length(); i++)
display.append("*");
int NumberOfTries = 0;
System.out.print("Let's Begin \n\n");
System.out.println("Try to guess the word in 6 tries, or you're a dead man!\n\n");
boolean correct = false;
while (NumberOfTries < 6 && !correct) {
String UserGuess = input.next();
String Letter = UserGuess.substring(0, 1);
if (ChosenWord.indexOf(Letter) < 0) {
System.out
.printf("The letter %s does not appear anywhere in the word.\n",
Letter);
NumberOfTries++;
}
else {
if (display.indexOf(Letter) >= 0)
System.out
.printf("The letter %s has already been entered as a guess.\n",
Letter);
else {
for (int p = 0; p < ChosenWord.length(); p++)
if (ChosenWord.charAt(p) == Letter.charAt(0))
display.setCharAt(p, Letter.charAt(0));
}
}
correct = display.indexOf("*") < 0;
draw(NumberOfTries);
}
if (correct)
System.out
.println("You have guessed "
+ ChosenWord
+ " correct and saved yourself from the gallos. Till next time that is.\n");
else {
System.out
.printf("You've had %d strikes against you. Thus you've been hung. Better luck next time.\n",
NumberOfTries);
}
}
public static void draw(int num) {
JPanel p1 = new JPanel();
p1.setBorder(BorderFactory.createEtchedBorder());
final String[] status = { "____\n| |\n | \n|\n|",
"____\n| |\n| O\n|\n|\n|", "____\n| |\n| O\n|/|\n|\n|",
"____\n| |\n| O\n|/|\\\n|\n|", "____\n| |\n| O\n|/|\\\n|/\n|",
"____\n| |\n| O\n|/|\\\n|/\\\n|" };
p1.add(new JLabel("Etched Border"));
if (num >= 0 && num < status.length) {
System.out.println(status[num]);
}
else {
System.out.println("Must be a Mistake. Out of Range.");
}
}
}
Swing (and most GUI's) are event driven environments. This basically means execution of logic is normally handled by event listeners/handlers
Start by becoming familiar with how to write general user interfaces, take a look at Creating a GUI with Swing
Using things like while-loops to get user input won't work within a GUI environment, you need to build the concept of what you want to do using the available controls
I have a JAVA card game, which show four cards at each round.
Currently, the stop between each round is waiting for a \n input in console. But I'd like to change it to waiting for a keyboard "enter" on the GUI.
Following is my current code. Please let me know how should I change it?
Millions of thanks!!!
import java.awt.GridLayout;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
public class Game {
public static void main(String args[]) throws IOException {
Deck deck = new Deck();
deck.shuffle();
int aGame = 4;
List<Card> cards = new ArrayList<Card> ();
for(int i = 0; i < 52; i++) {
cards.add(deck.deck.get(i));
if(aGame == 1) {
System.out.println(deck.deck.get(i).toString());
System.out.println("Start!!!");
JFrame f = new JFrame("Calculating 24!");
GridLayout grid = new GridLayout(2, 2);
f.setLayout(grid);
f.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
for(Card c: cards){
f.add(new LoadImageApp(c));
}
f.pack();
f.setVisible(true);
cards.clear();
while (true) {
char c = (char) System.in.read();
if (c == '\n') {
f.setVisible(false);
break;
}
}
aGame = 4;
if(i == 51) {
deck.shuffle();
i = -1;
}
}
else if(aGame == 4) {
System.out.println("Calculate based on the following four cards!");
System.out.println(deck.deck.get(i).toString());
aGame --;
}
else {
System.out.println(deck.deck.get(i).toString());
aGame --;
}
}
}
}
If the GUI element accepting the values is a JTextField, it is possible to add an ActionListener that will typically respond when the user hits Enter
Other tips
1)
f.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
Change that to:
f.setDefaultCloseOperaiton(JFrame.EXIT_ON_CLOSE);
Or better..
f.setDefaultCloseOperaiton(JFrame.DISPOSE_ON_CLOSE);
The first will have the same effect as what was, but the second will also check there are no non-daemon threads running prior to exit.
2)
Do not try to mix GUIs and the command line together. The way you go about writing an application for either is significantly different.
For Swing based applications key events should be handled using Key Bindings. However it may not be apparent to the end user that ENTER is required. A more UI centric approach is to use a dialog for this purpose
JOptionPane.showMessageDialog(frame, "Press ENTER to continue");
Using console based read methods such as InputStream#read is another source of confusion for users. Use a JTextComponent such as a JTextField to read user input in Swing applications.
I'm building a board game for a cs course, I've started with the engine - its backbone - and I've perfected it, I'm still stuck on the GUI part though. In the engine, I have a double array that initialises the board with the pieces, and it has a getWinner and move methods. In the GUI part, I created my JFrame and set its layout to gridlayout, and I've another double array there that checks the engine's array and prints the board with the board pieces accordingly.. however, whenever I move, the engine's array registers the move but it doesn't get displayed on my JFrame.. I've no idea on how to do it..
Here's my Main class in the GUI package:
package eg.edu.guc.loa.gui;
import java.awt.*;
import java.util.ArrayList;
import javax.swing.*;
import eg.edu.guc.loa.engine.*;
import eg.edu.guc.loa.engine.Point;
#SuppressWarnings("serial")
public class LOA extends JFrame{
static Tiles[][] Jboard;
static Board b = new Board();
static Color temp;
static Color col1 = Color.DARK_GRAY;
static Color col2 = Color.LIGHT_GRAY;
static JFrame LOA = new JFrame();
JButton b1, b2;
public LOA(){
Jboard = new Tiles[8][8];
LOA.setLayout(new GridLayout(8, 8));
initBoard();
LOA.setSize(600, 600);
LOA.setVisible(true);
LOA.setLocationRelativeTo(null);
LOA.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
b.printBoard();
}
public static void initBoard(){
remove();
b.printBoard();
for(int i = 0; i<8; i++){
if (i%2 == 0){
temp = col1;
}
else{
temp = col2;
}
for(int j = 0; j<8; j++){
Jboard[i][j] = new Tiles(temp, i, j);
LOA.getContentPane().add(Jboard[i][j]);
if (temp.equals(col1)){
temp = col2;
}
else{
temp = col1;
}
if(b.getPiece(new Point(j, i)).getPlayer() == BoardCell.PLAYER_1_PIECE){
Jboard[i][j].hasChecker(true);
Jboard[i][j].setWhite(true);
Jboard[i][j] = new Tiles(temp, i, j);
}
if(b.getPiece(new Point(j, i)).getPlayer() == BoardCell.PLAYER_2_PIECE){
Jboard[i][j].hasChecker(true);
Jboard[i][j].setWhite(false);
Jboard[i][j] = new Tiles(temp, i, j);
}
}
}
}
public static void remove(){
for(int i = 0; i<8;i++){
for(int j = 0; j<8; j++){
if(Jboard[i][j] != null)
LOA.remove(Jboard[i][j]);
}
}
}
public static void main (String [] args){
new LOA();
}
}
Any help will be much appreciated.. Thanks in advance.
EDIT:
b.print() prints the Engine's array on the console, and remove() is just my attempt on removing the old frame and building a new one based on the new updated array (with moved piece), which obviously failed.
As shown in this much simpler MVCGame, you can arrange for your view to register as a listener to your model using the observer pattern. User gestures should update the model; when notified by the model, the view should simply render the current state of the model. There should be no drawing in the model and no game logic in the view.