First of all, it's not really a virus that is used to spy, or steal bank accounts. I don't even know if it's a virus at all. I only made it to troll friends/people I know, and practice my programming skills. I will show you the code, then I will try to explain it a bit;
package pracatice;
import java.awt.event.*;
import javax.swing.*;
public class practice extends JFrame
{
public static boolean bool = true;
public static int x = 0;
public static int y = 0;
public static int num = 0;
public static TimerClass tc = new TimerClass();
public static Timer timer = new Timer(30, tc);
public JPanel panel = new JPanel();
public JButton btn = new JButton("press");
public practice()
{
setSize(100,100);
setTitle("Test");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setPanel();
setVisible(true);
}
public void setPanel()
{
btn.addActionListener(new listener());
panel.add(btn);
add(panel);
}
public class listener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
num = 0;
timer.start();
}
}
public static class TimerClass implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
do
{
num++;
JOptionPane optionPane = new JOptionPane("PC afected by virus");
JDialog dialog = optionPane.createDialog(null, "Virus");
dialog.setModal(false);
dialog.setLocation(x, y);
dialog.show();
updateCordinates();
}while(bool == true);
}
}
public static void updateCordinates()
{
if(x != 1100)
x += 100;
else if(x == 1100)
{
x = 0;
y += 50;
}
if(y == 650)
y =0;
}
public static void main(String[] args)
{
new practice();
}
}
So, at first it obviously builds a window, 100 X 100 px big. It adds a button that says "press". When you press, it starts a new loop, every 30 milliseconds.
every iteration of the loop, it puts in a new JOPtionPane.showMessageBox(null,...) in a slightly different location.
At first, when I just made it, I didn't know it would be unstoppable. I ran it, and had to restart my laptop. When I pressed ok, it would put in another box, in the exact same spot. When I tried to open task manager, it would automatically minimize it, and go back into the "virus" window. So, the laptop was unusable. I had to restart it, closing some of my dads tabs...
Here are a few things I would like to find out;
1) If I left this run over night, is it possible, that the laptop ran out or RAM, and if it did, what would happen?
2) Can I make it that, when I press a button on the keyboard, the whole thing just closes?
Like I said before, I was only trying to prank my friends, and the program happened to not be closable... any advice?
Yes, the computer will eventually run out of RAM. When that happens, nothing disastrous should happen other than your program crashing.
Not very easily, because JOptionPane windows don't let keyboard events get to the rest of the program. You'd need to use your own type of window instead of JOptionPane. You could then use a KeyListener that does System.exit(0).
Related
This goes along with my last question - I got the rooster sound to repeat every five seconds, but now I had to add a cow sound and a black background. Every five seconds, the rooster sound and the white background should alternate with the cow sound and black background. However, while my program is compiling, it just plays the rooster sound, then the cow sound, and doesn't change the background color. Help!
Here is my code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Morning extends JFrame
implements ActionListener
{
private EasySound rooster;
private EasySound cow;
private int time;
public Morning()
{
super("Morning");
rooster = new EasySound("roost.wav");
rooster.play();
cow = new EasySound("cow2.wav");
cow.play();
time = 0;
Timer clock = new Timer(5000, this);
clock.start();
Container c = getContentPane();
c.setBackground(Color.WHITE);
}
public static void main(String[] args)
{
Morning morning = new Morning();
morning.setSize(300, 150);
morning.setDefaultCloseOperation(EXIT_ON_CLOSE);
morning.setVisible(true);
}
public void actionPerformed(ActionEvent e)
{
Container c = getContentPane();
if (time == 5000)
{
rooster.play();
c.setBackground(Color.BLACK);
time = 0;
}
if (time == 0)
{
cow.play();
c.setBackground(Color.WHITE);
time++;
}
}
}
Where is my mistake?
Thank you to whoever helps!
Simone
You need to change the second if with an else.
Since you also used if for the second condition, as soon as you reset the time to 0, then the background is set to white again; giving the impression that it's not changed.
UPDATED:
I think you would want to change it to black first, since initially the background is already white.
#Override
public void actionPerformed(ActionEvent e) {
if (time == 0) {
rooster.play();
c.setBackground(Color.BLACK);
time += 5000;
}
else /*if (time == 5000)*/ {
cow.play();
c.setBackground(Color.WHITE);
time = 0;
}
}
First of all, apologies for how long winded this is.
I'm trying to make a simple roulette game that allows a user to add players, place bets for these players, and spin the roulette wheel, which is represented as a simple JLabel that updates it's text with each number it passes.
However, I've run into a bug that I'm having a lot of trouble with: the JLabel only updates the text for the last element in my loop.
Basically, my solution works like this:
When a user presses a button labelled "Spin" (given that users have been added to the game), I call a method from a class called SpinWheelService, which is an Observable singleton which in turn calls the notifyObservers() method:
public void actionPerformed(ActionEvent e) {
String cmd = e.getActionCommand();
String description = null;
if (ADD_PLAYER.equals(cmd)) {
addDialog();
} else if (PLACE_BET.equals(cmd)) {
betDialog();
} else if (SPIN.equals(cmd)) {
SpinWheelService.sws.setSpinWheelService();
} else if (DISPLAY.equals(cmd)) {
System.out.println("Display selected!");
}
}
Here is my SpinWheelService class:
package model;
import java.util.*;
public class SpinWheelService extends Observable {
public static SpinWheelService sws = new SpinWheelService();
public void setSpinWheelService() {
setChanged();
notifyObservers();
}
}
The only listener registered for SpinWheelService is this class, where GameEngine is my game engine that handles internal game logic, WheelCallbackImpl is a class that updates the View:
class SpinWheelObserver implements Observer {
GameEngine gameEngine;
ArrayList<SimplePlayer> players;
WheelCallbackImpl wheelCall;
int n;
public SpinWheelObserver(GameEngine engine, WheelCallbackImpl wheel, ArrayList<SimplePlayer> playerList) {
players = playerList;
gameEngine = engine;
wheelCall = wheel;
}
public void update(Observable sender, Object arg) {
// check if any players are present
if (players.size() == 0) {
System.out.println("Empty player array!");
return;
}
do {
gameEngine.spin(40, 1, 300, 30, wheelCall);
n = wheelCall.playback();
} while (n== 0);
}
}
The main point of note here is my gameEngine.spin() method, which is this:
public class GameEngineImpl implements GameEngine {
private List<Player> playerList = new ArrayList<Player>();
// method handles the slowing down of the roulette wheel, printing numbers at an incremental delay
public void delay(int millis) {
try {
Thread.sleep(millis);
} catch (InterruptedException e) {
System.out.println("Sleep method failed.");
}
}
public void spin(int wheelSize, int initialDelay, int finalDelay,
int delayIncrement, WheelCallback callback) {
Random rand = new Random();
int curNo = rand.nextInt(wheelSize) + 1;
int finalNo = 0;
assert (curNo >= 1);
// while loop handles how long the wheel will spin for
while (initialDelay <= finalDelay) {
delay(initialDelay);
initialDelay += delayIncrement;
// handles rotating nature of the wheel, ensures that if it reaches wheel size, reverts to 1
if (curNo > wheelSize) {
curNo = 1;
callback.nextNumber(curNo, this);
curNo++;
}
assert (curNo <= wheelSize);
callback.nextNumber(curNo, this);
curNo++;
finalNo = curNo - 1;
}
calculateResult(finalNo);
callback.result(finalNo, this);
}
The method callback.nextNumber(curNo, this):
public void nextNumber(int nextNumber, GameEngine engine) {
String strNo = Integer.toString(nextNumber);
assert (nextNumber >= 1);
System.out.println(nextNumber);
wcWheel.setCounter(strNo);
}
Where in, wcWheel is my singleton instance of my View, which contains the method setCounter():
public void setCounter(String value) {
label.setText(value);
}
Sorry for how convoluted my explanation is, but basically what it boils down to is that setCounter() is definitely being called, but seems to only call the setText() method on the final number. So what I'm left with is an empty label that doesn't present the number until the entire roulette has finished spinning.
I've determined that setCounter() runs on the event dispatch thread, and I suspect this is a concurrency issue but I have no idea how to correct it.
I've tried to include all relevant code, but if I'm missing anything, please mention it and I'll post it up as well.
I'm at my wits end here, so if anyone would be kind of enough to help, that would be so great.
Thank you!
Your while loop along Thread.sleep() will block and repainting or changing of the UI until the loop is finished.
Instead you'll want to implement a javax.swing.Timer for the delay, and keep a counter for the number of ticks, to stop it. You can see more at How to Use Swing Timers
The basic construct is
Timer ( int delayInMillis, ActionListener listener )
where delayInMillis is the millisecond delay between firing of an ActionEvent. This event is listened for by the listener. So every time the event is fired, the actionPerfomed of the listener is called. So you might do something like this:
Timer timer = new Timer(delay, new ActionListener()(
#Override
public void actionPerformed(ActionEvent e) {
if (count == 0) {
((Timer)e.getSource()).stop();
} else {
//make a change to your label
count--;
}
}
));
You can call timer.start() to start the timer. Every delay milliseconds, the label will change to what you need it to, until some arbitrary count reaches 0, then timer stops. You can then set the count variable to whatever you need to, if you want to to be random, say depending on how hard the wheel is spun :D
I think you didn't post all the relevant code that is required to know exactly the problem.
But most likely the problem is due to you run your loop and JLabel.setText() in the EDT (Event Dispatching Thread).
Note that updating the UI components (e.g. the text of a JLabel) also happens in the EDT, so while your loop runs in the EDT, the text will not be updated, only after your loop ended and you return from your event listener. Then since you modified the text of the JLabel it will be refreshed / repainted and you will see the last value you set to it.
Example to demonstrate this. In the following example a loop in the event listener loops from 0 to 9 and sets the text of the label, but you will only see the final 9 be set:
JPanel p = new JPanel();
final JLabel l = new JLabel("-1");
p.add(l);
JButton b = new JButton("Loop");
p.add(b);
b.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
for ( int i = 0; i < 10; i++ ) {
l.setText( "" + i );
try { Thread.sleep( 200 ); } catch ( InterruptedException e1 ) {}
}
}
} );
A proposed solution: Use javax.swing.Timer to do the loop's work. Swing's timer calls its listeners in the EDT so it's safe to update swing components in it, and once the listener returns, a component UI update can happen immediately:
JPanel p = new JPanel();
final JLabel l = new JLabel("-1");
p.add(l);
JButton b = new JButton("Loop");
p.add(b);
b.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
new Timer(200, new ActionListener() {
int i = 0;
#Override
public void actionPerformed(ActionEvent e2) {
l.setText("" + i);
if ( ++i == 10 )
((Timer)e2.getSource()).stop();
}
}).start();
}
} );
In this solution you will see the label's text counting from 0 up to 9 nicely.
It's appears to me that your entire game must block in the action handler until the while loop has finished? So the text of the label will be getting updated but only the last update will be visible once the AWT thread is running again.
Im writing a program that deals with creating a house and rearranging the neighbors (similar to game of life)
It is written in Java and it as a Reset button to restart with the current parameters.
The problem is that when i click the resetButton the whole window closes.
You can find the code at the and of the question.
These are other involved fields, so you might be able to understand the code better:
TextField to set the size of the city (number of squares on an edge).
TextFild to set the maximum percentage of neighbors not-like-you that a household will tolerate before they move. I.e., if the number is set to 70, a red house hold with 6 blue neighbors will move; a red household with 5 blue neighbors is ok according to this.
TextField to set a minimum percentage of neighbors not-like-you that a household will tolerate before they move. Make this greater than 0 for a person who LIKES diversity TextField to set the percentage of red households. Note: you can do this with probability. You do not need to have this exact percentage of red households.
TextField to set the percentage of blue households. White will be what is left over. Single step button gives every household one chance to move. You do not need to be careful about that fact that, as you progress through the city, a person early in the move chances may move to a place that later gets a chance (i.e., some households really get two or more turns).
Go button, to start and stop the program from doing steps on its own.
So my questions is how do i let those field and buttons restart with the current parameters ( restart it with what i have originally after playing a few times)
As you can see I added the resetButton to do its job but somehow it is not.
Ok it is like I run the program I have a set of numbers for red and blue as you can see in my, then when I run it it starts with those numbers. And so I keep on changing as i play, and then there is a reset button that lets me reset what I did and should bring back what it originally started with:
public final static int size = 5 and so on
This is my main program
public class Ghetto extends JFrame implements ActionListener, MouseListener,MouseMotionListener
{
protected Grids theGrid;
JButton resetButton;
javax.swing.Timer timer; // generates ticks that drive the animation
public final static int SIZE = 5;
public final static int BLUE = 10;
public final static int RED = 8;
public final static int DIVERSITY_PERCENTAGE = 70;
public static void main(String[] args)
{
new Ghetto();
}
public Ghetto() {
setDefaultCloseOperation(EXIT_ON_CLOSE);
addMouseListener(this);
addMouseMotionListener(this);
setLayout(new FlowLayout());
theGrid = new Grids(SIZE, BLUE, RED, DIVERSITY_PERCENTAGE);
add(theGrid);
resetButton = new JButton("Reset");
add(resetButton);
resetButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
resetWithCurrent();
}
});
setSize(new Dimension(550, 600));
setVisible(true);
}
public void resetWithCurrent()
{
//this.dispose();
}
#Override
public void actionPerformed(ActionEvent e)
{
timer.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
performStep();
//if (e.getSource() == resetButton )
//{
//resetWithCurrent();
//}
}
});
}
}
Also I added this part
public class Observable{
int state = 0;
int additionalState = 0;
public final void updateState(int increment)
{
doUpdateState(increment);
notifyObservers();
}
private void notifyObservers() {
// TODO Auto-generated method stub
}
public void doUpdateState(int increment)
{
state = state + increment;
}
}
public class ConcreteObservable extends Observable{
public void doUpdateState(int increment){
super.doUpdateState(increment); // the observers are notified
additionalState = additionalState + increment; // the state is changed after the notifiers are updated
}
}
But it didnt make any difference.
I just need to get it to alternate between "X" and "O" for the turns but it's only giving me X's.
import java.awt.GridLayout;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.*;
public class tictactoe {
public static final int FRAME_WIDTH = 700;
public static final int FRAME_HEIGHT = 200;
public static void main(String[] args)
{
int slots = 9;
final JButton[] gameButton = new JButton[9];
JPanel ticTacToeBoard = new JPanel();
ticTacToeBoard.setLayout(new GridLayout(3, 3));
JButton clearButtons = new JButton("New Game");
for (int i = 0; i < slots; i++)
{
gameButton[i] = new JButton();
ticTacToeBoard.add(gameButton[i]);
final int countTurns = i;
gameButton[i].addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
Object clicked = e.getSource();
int turns = 1;
for (int p = 0; p < 9; p++)
{
if(clicked == gameButton[countTurns] && turns < 10)
{
if (!(turns % 2 == 0))
{
((JButton)e.getSource()).setText("X");
turns++;
}
else
{
((JButton)e.getSource()).setText("O");
turns++;
}
}
}
}
});
final int integerHack = i;
clearButtons.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
gameButton[integerHack].setText("");
}
});
}
JButton exit = new JButton("Exit");
exit.setActionCommand("EXIT");
exit.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
String cmd = e.getActionCommand();
if (cmd == "EXIT")
{
System.exit(FRAME_WIDTH);
}
}
});
JPanel rightPanel = new JPanel();
JLabel wonLabel = new JLabel();
rightPanel.setLayout(new GridLayout(1, 3));
rightPanel.add(wonLabel);
rightPanel.add(clearButtons);
rightPanel.add(exit);
JFrame mainFrame = new JFrame();
mainFrame.setSize(FRAME_WIDTH, FRAME_HEIGHT);
mainFrame.setVisible(true);
mainFrame.setLayout(new GridLayout(1,2));
mainFrame.add(ticTacToeBoard);
mainFrame.add(rightPanel);
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
Look at your actionPerformed method. Every time a click happens, you set turns to 1. As a result, !(turns % 2 == 0) will always evaluate true, and you'll always draw an X.
Just by quickly looking at your code, I would guess it is because your turn variable is local in all the ActionListener objects. Therefore, the turn variable is always 1 and you always run into the first if case. So the turn variable is always recreated on the stack as soon as you get a callback in the actionPerformed method. For a quick fix and test, try to put the turn variable in the tictactoe class and see if that helps.
The trouble is with the turns variable in your actionPerformed. If you want to keep a track of it you should move that out from your method.
Firstly, as the other people have also said, you want "turns" to be initialized outside all your loops.
Secondly, I would like to point out a typo:
if(clicked == gameButton[countTurns] && turns < 10)
should be
if(clicked == gameButton[p] && turns < 10)
...unless you really want to change each button's text from X to O nine times each time a button is clicked.
But even fixing that typo is pointless. Why loop through to find a specific button when it doesn't matter which specific button it is? All the buttons have the same action handler, anyway, just nine separate copies of it, because you are creating nine identical copies each time around.
Instead, because all the buttons do the same thing, you should have one action handler for all the buttons. If you're not sure how that's done, you create it outside your button making loop and assign it to a variable, and then you put in that variable when you assign each button's action handler, e.g.
gameButton[i].addActionListener(myActionListener);
I want to build a simple memory game. I want to put a replay button, which is play again the memory game.
I have built a class named MemoryGame and a main class.
Here is the part of the ButtonListener code.
public void actionPerformed(ActionEvent e) {
if (exitButton == e.getSource()) {
System.exit(0);
}
else if (replayButton == e.getSource()) {
//How can I declare it?
}
}
If I declare the replay button as :
new MemoryGame();
It's work fine, but it pops up another windows.
I want to clear the current display and return to the beginning, without a new windows. How can I do that?
EDIT :
I think I need to rewrite the code of my program, because my program does not have the init() method as suggested which is the initial state of the program.
My Java knowledge is very limited and usually I create less method and dump most into a method.
I will try to redo my program.
Thanks for the suggestions.
Show us what is inside the MemoryGame how you create its initial state. Effectively what folks are suggesting here is for you is to have an initial method which will set-up the game state which the MemeoryGame constructor will call. Then on replay-button of the game you call this method.
Something along these lines:
void init(){
this.x = 10;
this.y = 10;
}
public MemoryGame(){
init();
}
public void actionPerformed(ActionEvent e) {
if (exitButton == e.getSource()) {
System.exit(0);
}
else if (replayButton == e.getSource()) {
init();
}
}
one way you can do it although it might be dirty, is to grab your MemoryGame constructor, and put the stuff inside it inside another method, and call that method in your constructor and inside the button event.
as an example i have made the following class and it resets itself with the use of the previous technique:
public class App extends JFrame{
public static void main(String[] args){
new App();
}
public App(){
init();
}
private JButton changeColorButton;
private JButton resetAppButton;
private JPanel panel;
private void init() {
changeColorButton=null;
resetAppButton=null;
panel=null;
this.setSize(200,400);
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
panel = new JPanel();
panel.setBackground(Color.white);
panel.setPreferredSize(new Dimension(200,400));
changeColorButton = new JButton("Change");
changeColorButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
panel.setBackground(Color.black);
panel.repaint();
}
});
changeColorButton.setPreferredSize(new Dimension(100,100));
resetAppButton = new JButton("Reset");
resetAppButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
init();
}
});
resetAppButton.setPreferredSize(new Dimension(100,100));
panel.add(changeColorButton);
panel.add(resetAppButton);
this.add(panel);
this.validate();
}
}
what this app does is it has two buttons. one changes the color and the other resets the app itself.
You should think about re-factoring your code so that the MemoryGame class does not create the GUI, then you wont be recreating it whenever you initialise a new Game.
It's a good idea to keep program logic separate to UI code.
What you could do is you could call dispose() on your JFrame. This will get rid of it and go to your title screen like this:
Here's the button code
public void actionPerformed(ActionEvent event)
{
if (closeButton = event.getSource())
{
System.exit(0);
}
if (playAgainButton = event.getSource())
{
Game.frame.dispose(); // Your class name, then the JFrame variable and call dispose
}
}
This will work but you may have a few problems reseting your program. If so then create a reset method where you can reset all your variables and call when playAgainButton is clicked. For example:
public void reset()
{
// Right here you'd reset all your variables
// Perhaps you have a gameOver variable to see if it's game over or not reset it
gameOver = false;
}