Can't Run Method and Its GUI From Inside a Try Catch - java

I am trying to execute the lines:
Balldemo bd = new BallDemo();
bd.bounce(myInt);
In the below code:
public void actionPerformed(ActionEvent evt) {
String text = textField.getText();
try {
myInt=Integer.parseInt(textField.getText());
BallDemo bd = new BallDemo();
bd.bounce(myInt);
int newInt = myInt + 5;
System.out.println("Integer is: "+newInt);
}
catch (NumberFormatException ex) {
System.out.println("Not a number");
}
//Make sure the new text is visible, even if there
//was a selection in the text area.
textArea.setCaretPosition(textArea.getDocument().getLength());
}
But is does not boot the program correctly as follows:
program is a canvas with two balls that move, bounce(int numberOfBalls) will draw the balls on the canvas and start them moving.
In the above code, the canvas is created but the balls do not appear.
However, in a different class under the main method it works fine.
Basically don't understand why it won't successfully execute in a try-catch loop.

I suspect your BallDemo object (bd) is going out of scope as soon as the try block ends. Try declaring it outside the try block.

Related

Wait for button to be pressed JAVA GUI

At the moment I'm currently re-writing a text-based program to have a GUI. One of the problems I am experiencing is that I want the program to wait until a certain condition is met. This condition can be met through the user clicking the "Walk" button until the player.walked attribute = 5. When using a text-based interface this is quite simple, use a while loop and inside have an input function.
while (player.getWalked() < 5) {
//wait for user input via terminal through the scanner.
}
However when using a GUI and wanting to follow the approach of the Model-View Controller (i.e. keeping game mechanics and user interface stuff separate) it becomes rather difficult. After attempting to implement a GUI My program keeps freezing as the while loop is now empty. I will attempt to evidence this below but it is rather confusing. I apologise if this is unprofessional.
World Class:
public static void play(Player player) throws FileNotFoundException, IOException, ClassNotFoundException{ // play method is the centralised place for all in-game simulation and user interaction.
welcome(player);
while (player.getWalked() <5) {
}
GUI Class:
Button walk_button = new Button("Walk");
walk_button.setBounds(195, 395, 100,100);
add(walk_button);
walk_button.addActionListener((new ActionListener(){
public void actionPerformed(ActionEvent evt) {
try{
label1.setVisible(false);
label.setText(player.interaction("W"));
label.setBounds(200,50,400,100);
}
catch (FileNotFoundException e) {System.out.println(e.getMessage());} catch (IOException e) {System.out.println(e.getMessage());} catch (ClassNotFoundException e) {System.out.println(e.getMessage());}
}
}));
Player class consisting of the interaction method:
public String interaction(String input) throws FileNotFoundException, IOException, ClassNotFoundException{
//String input = World.input("You have walked "+getWalked()+" miles so far.\nOnly "+(END_POINT - walked)+" miles until you reach the end of the town.\nPress 'w' to walk.\nPress 'c' to change weapon equipped.\nPress 's' to save and exit.");
if (input.equals("W")) {
return walk(World.dice(4,1));
}
If anyone can find a solution to this I would be much appreciated. The end goal is for the program to keep running (allow the player to keep pressing the "Walk" button) until the while loop is broken.
Thank you very much and apologies if this is rather long, confusing and unprofessional.
It's not a great idea to have empty while loops, so I would suggest checking the player's position with an if-statement in the same method where it is set (right after the button trigger actionPerformed), and then continuing from there. I can't give you a specific implementation though because I don't know what you want to do.
EDIT:To clarify, I meant something like this:
public void actionPerformed(ActionEvent evt) {
//set player's walked distance ...
//...
if (player.getWalked() > 5) {
//put all your logic here, or extract to a method
}
}
Side note: Instead of having multiple catch blocks where you do the same thing, just use FileNotFoundException | ClassNotFoundException | etc.

How to fix bug with endless writing of numbers using FileWriter with append argument

I faced one problem which I’m struggling to solve.
Imagine simple game, where some object , lets call it car, remains motionless on X-axis ( x = 50 ) and is able to move only on Y-axis (up and down). At the same time, another objects are created beyond the screen at random point ( and move toward my first object ) , so their coordinates decrementing on X-axis. As soon as every object reaches my first object coordinates, some variable int scores; increments.
int scores;
if(cars.getX() == getCarPos_X() && cars.getY() != getCarPos_Y() )
scores++;
Basically this game looks like car which goes between other cars and avoid hitting, and counter scores increments every time my car pass next moving car.
So what is the problem?
I use timer which count time between repainting. All objects pass to the paintComponent where actually all graphic draw. In actionPerformed I call methods for all moves, and one method which checks if collision with another car occurred. In case of collision, game stops, and scores should be written in some txt file.
The problem is that while two objects have same coordinates, JVM write endless number of figures (scores) into the file ( I think it’s because coordinates stop decrementing and every timer interval it checks for collision and it’s == true , as game is stoped , and object remains where they are.)
So my scores in txt file looks like :
0
0
0
0
In one column.
Or it displays any score which I’ve got.
And so on...
Here is the crucial code snippet which I used
public void actionPerformed(ActionEvent e)
{
animate();
checkTouch();
}
private void animate()
{
//here code that creates obstacles and moves them
}
checkTouch()
{
//objects creating in some inner class Cars and add to ArrayList ( I don’t mention about it as it is beside the point )
for(Cars car : cars)
{
if((cars.getX() == getCarPos_X && cars. getY() == getCarPos_Y())
{
//boolean var which stops game
inGame = false;
writeScore();
}
}
}
public void writeScore()
{
File scoresTxt = new File("scores.txt");
FileWriter fw = null;
BufferedWriter bw = null;
try
{
fw = new FileWriter(scoresTxt, true);
bw = new BufferedWriter(fw);
bw.write(scores + "\n");
}catch (IOException e)
{
e.printStackTrace();
}finally
{
try
{
bw.flush();
bw.close();
fw.close();
}catch(IOException e)
{
e.printStackTrace();
}
}
}
public void paintComponent (Graphics g)
{
if(inGame)
{
g.drawImage(myCar, 50, 100, this);
for(Cars car : cars)
{
g.drawImage(obstacleCar, car.getX(), car.getY(), this);
}
}
}
Should you need some extra code I used, write comment and I’ll add it.
And again I need to fix bug which write endless column of numbers instead of one final score from the moment of collision.
What’s wrong with my code , and how to solve this problem?
Give me advice for simplest decision, as I’m beginner.
Thanks in advance!
If your timer is started like this, or something similar, the you could cancel it when the inGame variable becomes false. Nice article on timers.
TimerTask task = new TimerTask() {
public void run() {
if (!inGame)
cancel();
else
// whatever it is that you are doing now
}
};
You might also want to stop processing events in the actionPerformed(e) method in a similar way.
if (!inGame)
return;

Disable the mouse cursor within a program

I'm creating a text adventure and I need to completely disable the mouse cursor. Not just hide it, although I already know how to do that, but disable it completely so that you must use Alt-Tab or a built-in quit button to stop. The main reason for this is because people can scroll with the mouse cursor and I need to disable that, I thought about canceling MouseEvents when they're fired but I couldn't get it to work (the listener that is.)
If someone knows how then please speak up and tell me! :)
EDIT: Whoops, I forgot my code. Here is my Console class.
This is started by another class with new Console();
EDIT 2: Here are some snippets of me trying to create an invisible cursor and a mouse listener. The first one works, but the latter does not.
// Invisible cursor
Toolkit toolkit = Toolkit.getDefaultToolkit();
Point hotSpot = new Point(0,0);
BufferedImage cursorImage = new BufferedImage(1, 1, BufferedImage.TRANSLUCENT);
Cursor invisibleCursor = toolkit.createCustomCursor(cursorImage, hotSpot, "InvisibleCursor");
frame.setCursor(invisibleCursor);
// Adding mouse listener
frame.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent me) {
System.out.println(me);
}
});
EDIT 3: To elaborate on the mouse listener it simply does not work. It doesn't print anything.
If you just want to prevent users from seeing old text, remove the old text from the JTextArea.
The easiest way to do it is to leave the JTextArea in a JScrollPane, and keep track of the lines yourself:
private static final int MAX_VISIBLE_LINES = 12;
private final Deque<String> lines = new LinkedList<>();
void appendLine(String line,
JTextArea textArea) {
lines.addLast(line);
if (lines.size() > MAX_VISIBLE_LINES) {
lines.removeFirst();
}
String text = String.join("\n", lines);
textArea.setText(text);
textArea.setCaretPosition(text.length());
try {
textArea.scrollRectToVisible(
textArea.modelToView(text.length()));
} catch (BadLocationException e) {
throw new RuntimeException(e);
}
}
Trying to commandeer the mouse on a multitasking desktop is just going to make users angry. Would you want an application preventing you from reading your e-mail?
Update:
If you want to base the number of lines of text on the JTextArea’s current height, use the JTextArea’s font metrics. I assume you don’t need to get it exactly right and it’s okay if the number is off by one or two lines. (To account for things like line wrapping would be considerably more difficult.)
private final Deque<String> lines = new LinkedList<>();
void appendLine(String line,
JTextArea textArea) {
FontMetrics metrics = textArea.getFontMetrics(textArea.getFont());
JViewport viewport = (JViewport) textArea.getParent();
int visibleLineCount = viewport.getExtentSize().height / metrics.getHeight();
lines.addLast(line);
while (lines.size() > visibleLineCount) {
lines.removeFirst();
}
String text = String.join("\n", lines);
textArea.setText(text);
textArea.setCaretPosition(text.length());
try {
textArea.scrollRectToVisible(
textArea.modelToView(text.length()));
} catch (BadLocationException e) {
throw new RuntimeException(e);
}
}

Adding a timer to a for loop

I'm writing code that moves a token piece around a monopoly board based on certain coordinates. Currently, it prints it in each square but I'm trying to get it to print in each square, with a timer so you can see each square printing and when it prints in one square, it removes the print in the previous square so the token can only be in one square at a time. This is the code I have so far:
for(int g=0;g<10;g++)
{
JLabel redtoken = new JLabel(new ImageIcon ("src/TokenRed.png"));
redtoken.setBounds(x[g],y[g], 10, 10); // Size and position set
LPane.add(redtoken, new Integer(3)); // Red token set as layer 3
}
Test using a selection of coordinates: (Token is Red Square)
If I understand correctly, you want to see a red token hopping from square to square.
I suggest something like that :
Object lastPrinted = null;
for(int g=0;g<10;g++)
{
if(alreadyPrinted != null){
deleteToken(alreadyPrinted);
}
printNewToken(g)
try {
Thread.sleep(300);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
System.err.println(e);
}
}

Continuously read from file and do an action

I want to continuously read from a text file, and change the color of a box I have shown on the canvas when a certain line is read (the text file is going to be constantly updating). Right now, I have a green square drawn on the canvas and three "test" lines in the text file, and when it reaches the third line of the text file I would like to change the the square to Red.
Here is my code, from two files (myCanvas.java and myFileReader.java). Any point in the right direction is greatly appreciated.
public class myCanvas extends Canvas{
public myCanvas(){
}
public void paint(Graphics graphics){
graphics.setColor(Color.green);
graphics.fillRect(10, 10, 100, 100);
graphics.drawRect(10,10,100,100);
}
public static void main(String[] args){
myCanvas canvas = new myCanvas();
JFrame frame = new JFrame("Live GUI");
frame.setSize(400, 400);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(canvas);
frame.setVisible(true);
myFileReader read = new myFileReader();
read.readFromFile();
if(myFileReader.strLine == "This is the third line."){
//change color
}
}
public class myFileReader{
public static String strLine;
public void readFromFile()
{
try{
FileInputStream fstream = new FileInputStream(System.getProperty("user.dir")+"\\sample.txt");
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
while (true){
strLine = br.readLine();
if(strLine == null) {
Thread.sleep(1000);
}
}
}
catch (Exception ex){
System.err.println("Error: " + ex.getMessage());
}
}
}
Here is a way you can do it without much changes to your code.
Create a local variable in your MyCanvas class called currentColor of type Color. FYI, the convention in Java is to have class names start with a capital letter.
Update your paint() method to set the color of the rectangle to the new variable currentColor, instead of the static green value.
In your main method, you can do canvas.currentColor = <new color here>; and then canvas.repaint(). The repaint() function call will erase the canvas and redraw it using your paint() function.
I don't think your FileReader will work well with a file that's constantly being modified though.
Simply add a counter and increment it each time you read a line. When the counter reaches the third line use an if statement to do your task
Try this
1.Use BreakIterator class, with its static method getLineInstance(),
this will help you identify every line in the file.
2. Create an HashMap with the colour as Key, and its RGB as Value.
3. Parse every word in the line, which is obtained from
BreakIterator.getLineInstance().
4. Compare it with the Key in the HashMap,
if the word in the line happens to match the Key in
the HashMap, then colour the box with the Value of the Key.

Categories