main method terminates when I instantiate a new thread - java

I am programming a top-down shooter game, and I want to open a new window between each level of the game. After each level, if a certain criteria is met then the following class is implemented:
import java.util.*;
import javax.swing.*;
import java.awt.*;
import java.awt.Image.*;
import java.awt.image.BufferedImage.*;
import java.text.*;
import java.awt.event.*;
import javax.swing.event.*;
import javax.swing.border.*;
import javax.swing.text.*;
import javax.imageio.ImageIO;
import java.io.InputStream.*;
import java.io.*;
public class Shop extends JFrame implements Runnable
{
private static java.awt.image.BufferedImage shotgun, zombie, armor, aRifle;
static ArrayList<Image> stock = new ArrayList<Image>();
private ColorPanel contentPane3;
private JPanel container = new JPanel();
private JPanel contentPane4;
private int item=0;
private boolean broke = false;
private boolean newb = true;
private boolean reg = false;
private boolean stay = true;
public static void main(String [] args)
{
System.out.println("started");
Thread s = new Thread( new Shop () );
System.out.println("running");
s.start();
System.out.println("ended");
}
public Shop()
{
super("Monster Escape v4");
try
{
shotgun = ImageIO.read(getResource("shotgun.png"));
zombie = ImageIO.read(getResource("zombie.png"));
armor = ImageIO.read(getResource("armor.png"));
aRifle = ImageIO.read(getResource("assaultRifle.png"));
}catch (IOException e){System.exit(0);}
stock.clear();
stock.add(armor);
if(!(Client.inventory.contains("shotgun")))
stock.add(shotgun);
if(!(Client.inventory.contains("assaultRifle")))
stock.add(aRifle);
container.removeAll();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
contentPane4 = new JPanel();
contentPane4.setPreferredSize(new Dimension( 700,100 ));
contentPane3 = new ColorPanel(Color.WHITE);
contentPane3.setPreferredSize(new Dimension( 700,700 ));
setBounds( 100,100,606,719 );
setResizable(false);
GridLayout g1 = new GridLayout(1, 3);
contentPane4.setLayout(g1);
container.setLayout(new BoxLayout(container, BoxLayout.Y_AXIS));
JButton sleft = new JButton("←");
JButton sright = new JButton("→");
JButton buy = new JButton("buy");
JButton leave = new JButton("leave");
contentPane4.add(sleft);
contentPane4.add(buy);
contentPane4.add(sright);
contentPane4.add(leave);
sleft.addActionListener((e) -> {
broke = false;
newb = false;
if(item==0)
item = stock.size()-1;
else
item--;
});
sright.addActionListener((e) -> {
broke = false;
newb = false;
if(item==stock.size()-1)
item=0;
else
item++;
});
buy.addActionListener((e) -> {
broke = false;
newb = false;
if(stock.get(item) == armor)
{
if(Client.cash >= 100)
{
Client.maxHealth += 4;
Client.cash -= 100;
reg = true;
}
else
broke = true;
}
else
{
if(Client.cash >= 250)
{
Client.inventory.add(getName(item));
stock.remove(item);
Client.cash -= 250;
item--;
reg = true;
}
else
broke = true;
}
});
leave.addActionListener((e) -> {
stay = false;
});
container.add(contentPane3, BorderLayout.EAST);
container.add(contentPane4, BorderLayout.WEST);
setContentPane(container);
setVisible(true);
}
public static String getName(int i)
{
String temp = null;
if(stock.get(i) == armor)
temp = "armor";
else if(stock.get(i) == shotgun)
temp = "shotgun";
else if(stock.get(i) == aRifle)
temp = "assaultRifle";
return temp;
}
private InputStream getResource(String ref) throws IOException
{
InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream(ref);
if( in != null )
return in;
return new FileInputStream(ref);
}
public void run()
{
while(stay)
{
repaint();
try
{
Thread.sleep(10);
}catch( InterruptedException e ) { }
}
dispose();
}
}
This includes a ColorPanel subclass that isn't shown. In previous versions of my game, this has worked fine. However, I recently added a KeyListener subclass to my Client, and now nothing happens when I try to instantiate the thread. I created a main method in the Shop class itself to see where the issue is, and it seems that when the code reaches
Thread s = new Thread( new Shop () );
the system terminates entirely, since when I run main it only prints "started." What is causing this?

add
s.join();
after start. In this case main thread will wait until s thread will be finished.

Related

Running a GUI client multiple times without having to close it

I'm in the process of making a GUI where I input a string into a text box and, once I click a Jbutton, a second text box will produce the string I inputted into the first or produce a random string from a method I created (public void associate()). When I run the GUI and click the button to produce the text in the second text box, everything works fine. However, when I click the button a second time so the GUI performs the same action, nothing happens. Is there anything I can do so that I don't have to close the GUI every time I wish to run it multiple times?
public class GUIWindow extends JFrame {
private Joketeller robot= new Joketeller();
private JLabel speakerlabel = new JLabel("Joke");
private JLabel MarcoLabel= new JLabel ("Marco");
private JTextField speakerfield= new JTextField ("Enter Joke Here");
private JTextField Marcofield= new JTextField ("",20);
private JButton Jokebutton=new JButton("Recite Joke >>>");
public GUIWindow() {
JPanel dataPanel= new JPanel(new GridLayout(2,2,12,16));
dataPanel.add(speakerlabel);
dataPanel.add(MarcoLabel);
dataPanel.add(speakerfield);
dataPanel.add(Marcofield);
JPanel buttonPanel= new JPanel();
buttonPanel.add(Jokebutton);
Container container = getContentPane();
container.add(dataPanel,BorderLayout.CENTER);
container.add(buttonPanel,BorderLayout.SOUTH);
Jokebutton.addActionListener(new JokeListener());
}
private class JokeListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
String input=speakerfield.getText();
if (Jokebutton.isEnabled()) {
robot.setJoke(input);
String Response= robot.getResponse();
Marcofield.setText(Response);}
Joketeller class:
public class Joketeller {
private static String Marco;
private static String Response;
static int i= (int)(Math.random()*((5-1)+1)+1);
static String r;
public void setMarco(String Joke ) {
Marco=Joke;
}
public void setJoke(String Joke) {
Marco=Joke;
associate();
}
public String getJoke() {
return Marco;
}
public static String getMarco() {
return Marco;
}
public static void associate(){
if(i==1)
r= "Connect Angie";
else if(i==2)
r= "*Cloud Laugh*";
else if(i==3)
r= "Community";
else if(i==4)
r=getMarco();
else if(i==5)
r= "Indeed!";
Response=r;
}
public String getResponse() {
return Response;
}
}
Any help is appreciated. Thank you.
The first thing that jumps out at me, is the overuse of static...
public class Joketeller {
private static String Marco;
private static String Response;
static int i= (int)(Math.random()*((5-1)+1)+1);
static String r;
This is not helping your here, and if done right, shouldn't be needed.
The next issue is with i...
static int i = (int) (Math.random() * ((5 - 1) + 1) + 1);
public static void associate() {
if (i == 1) {
r = "Connect Angie";
} else if (i == 2) {
r = "*Cloud Laugh*";
} else if (i == 3) {
r = "Community";
} else if (i == 4) {
r = getMarco();
} else if (i == 5) {
r = "Indeed!";
}
Response = r;
}
i is never changed. Because it's static, you can create as many instance of Joketeller as you like and it will need change, so the response will always be the same.
While there are a number of possible ways to fix it, the simplest would be to remove all the static and make i a local variable within associate, as it's really not used anywhere else..
public void associate() {
int rnd = (int) (Math.random() * ((5 - 1) + 1) + 1);
if (rnd == 1) {
r = "Connect Angie";
} else if (rnd == 2) {
r = "*Cloud Laugh*";
} else if (rnd == 3) {
r = "Community";
} else if (rnd == 4) {
r = getMarco();
} else if (rnd == 5) {
r = "Indeed!";
}
response = r;
}
This means you don't need to create a new instance of Joketeller in order to get a different response.
For example....
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class GUIWindow extends JFrame {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
GUIWindow wnd = new GUIWindow();
wnd.pack();
wnd.setLocationRelativeTo(null);
wnd.setVisible(true);
}
});
}
private Joketeller robot = new Joketeller();
private JLabel speakerlabel = new JLabel("Joke");
private JLabel marcoLabel = new JLabel("Marco");
private JTextField speakerfield = new JTextField("Enter Joke Here");
private JTextField marcofield = new JTextField("", 20);
private JButton jokebutton = new JButton("Recite Joke >>>");
public GUIWindow() {
JPanel dataPanel = new JPanel(new GridLayout(2, 2, 12, 16));
dataPanel.add(speakerlabel);
dataPanel.add(marcoLabel);
dataPanel.add(speakerfield);
dataPanel.add(marcofield);
JPanel buttonPanel = new JPanel();
buttonPanel.add(jokebutton);
Container container = getContentPane();
container.add(dataPanel, BorderLayout.CENTER);
container.add(buttonPanel, BorderLayout.SOUTH);
jokebutton.addActionListener(new JokeListener());
}
private class JokeListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
String input = speakerfield.getText();
if (jokebutton.isEnabled()) {
robot.setJoke(input);
String Response = robot.getResponse();
marcofield.setText(Response);
}
}
}
public class Joketeller {
private String marco;
private String response;
private String r;
public void setMarco(String Joke) {
marco = Joke;
}
public void setJoke(String Joke) {
marco = Joke;
associate();
}
public String getJoke() {
return marco;
}
public String getMarco() {
return marco;
}
public void associate() {
int rnd = (int) (Math.random() * ((5 - 1) + 1) + 1);
if (rnd == 1) {
r = "Connect Angie";
} else if (rnd == 2) {
r = "*Cloud Laugh*";
} else if (rnd == 3) {
r = "Community";
} else if (rnd == 4) {
r = getMarco();
} else if (rnd == 5) {
r = "Indeed!";
}
response = r;
}
public String getResponse() {
return response;
}
}
}

java enumeration loop doubles up on repeat of cycle

I'm trying to make a trivia game in swing with CardLayout to change between screens in a single JFrame. I have a loop set to move through the states in my enumeration. Everything works quite well except for when, at the end of a game, if I choose to start a new game, it somehow goes to both the first and second states simultaneously. I'm not sure how this happens as this is the only state this happens in.
Code for main:
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
import java.awt.CardLayout;
import java.awt.Color;
import java.io.IOException;
import java.util.Random;
import javax.swing.*;
public class Main
{
public enum State {SPLASH, PREQUESTION, QUESTION, WIN, LOSS};
public static JFrame frame;
public static JPanel content;
public static JPanel neutral;
public static int event;
public static Random rn = new Random();
public static Splash splash;
public static Prequestion eventStart;
public static Question question;
public static Win win;
public static Loss loss;
public static void main(String[] args) throws LineUnavailableException, UnsupportedAudioFileException, IOException
{
frame = new JFrame("DREWcathalon");
content = new JPanel();
neutral = new JPanel();
CardLayout cards = new CardLayout();
content.setLayout(cards);
neutral.setBackground(Color.WHITE);
content.add(neutral, "neutral");
frame.add(content);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(1000, 750);
frame.setVisible(true);
cards.show(content, "neutral");
State gameState = State.SPLASH;
while (true)
{
switch(gameState)
{
case SPLASH:
event = 0;
splash = new Splash(content, cards);
splash.splashSound();
while (splash.holdState()){};
cards.show(content, "neutral");
gameState = State.PREQUESTION;
splash = null;
break;
case PREQUESTION:
event++;
eventStart = new Prequestion(event, content, cards);
while (eventStart.holdState()){};
cards.show(content, "neutral");
gameState = State.QUESTION;
eventStart = null;
break;
case QUESTION:
question = new Question(event, rn.nextInt(5)+1, content, cards);
while (question.holdState()){};
cards.show(content, "neutral");
if (question.rightState() && event > 9)
{
gameState = State.WIN;
}
else if (question.rightState())
{
gameState = State.PREQUESTION;
}
else
{
gameState = State.LOSS;
}
question = null;
break;
case WIN:
win = new Win(content, cards);
while(win.holdState()){};
cards.show(content, "neutral");
gameState = State.SPLASH;
win = null;
break;
case LOSS:
loss = new Loss(content, cards);
while(loss.holdState()){};
cards.show(content, "neutral");
gameState = State.SPLASH;
loss = null;
break;
}
}
}
}
Code for Win:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.sound.sampled.*;
import java.io.*;
public class Win
{
static private Clip clip;
static private boolean hold = true;
public Win(JPanel content, CardLayout cards) throws UnsupportedAudioFileException, IOException, LineUnavailableException
{
JButton restart = new JButton("New Game+");
JButton quit = new JButton("Flee");
JLabel title = new JLabel("A Winnar is You!");
JPanel wContent = new JPanel();
wContent.add(title);
wContent.add(restart);
wContent.add(quit);
wContent.setBackground(Color.WHITE);
content.add(wContent, "win");
cards.show(content, "win");
File soundFile = new File("TEST.wav");
AudioInputStream audioIn = AudioSystem.getAudioInputStream(soundFile);
clip = AudioSystem.getClip();
clip.open(audioIn);
clip.start();
restart.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
if (clip.getMicrosecondPosition() < clip.getMicrosecondLength())
{
clip.stop();
}
hold = false;
}
});
quit.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
System.exit(0);
}
});
}
public boolean holdState()
{
return hold;
}
}
I don't have the specific answer to your specific question, which is one reason I'm answering this as a Community Wiki, but I can state with confidence that your program structure is broken and is not written in a way that respects either object-oriented programming principles, as evidenced by your copious use of static fields, or GUI event-driven coding principles, as evidenced by your while (true) loop. The solution is to completely restructure your program, getting rid of your while (true) loop and instead use notifications / observer design pattern to drive state changes.
I can almost guarantee that if you fix these issues, especially by getting rid of the while (true) loop and replacing it with event notification and listening, your problem with game restart will resolve.
If you need more specific help, you'll want to create and post your valid SSCCE (please see the link for the details). I tried doing this myself with your code, but it's taking me too long, and the effort really should be yours.
A very simplistic example that uses simple notification to change state
import java.awt.CardLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.*;
#SuppressWarnings("serial")
public class Main2 extends JPanel {
private CardLayout cardLayout = new CardLayout();
private MyState myState = MyState.SPLASH;
private MySplash mySplash = new MySplash(this);
private MyPreQuestion myPreQuestion = new MyPreQuestion(this);
private MyQuestion myQuestion = new MyQuestion(this);
public Main2() {
setLayout(cardLayout);
add(mySplash, MyState.SPLASH.toString());
add(myPreQuestion, MyState.PREQUESTION.toString());
add(myQuestion, MyState.QUESTION.toString());
mySplash.startSplashTimer();
}
public void next() {
int index = 0;
for (int i = 0; i < MyState.values().length; i++) {
if (MyState.values()[i] == myState) {
index = i;
}
}
index++;
index %= MyState.values().length;
setState(MyState.values()[index]);
}
public void setState(MyState nextState) {
myState = nextState;
cardLayout.show(this, nextState.toString());
if (myState == MyState.SPLASH) {
mySplash.startSplashTimer();
}
}
private static void createAndShowGui() {
JFrame frame = new JFrame("Main");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new Main2());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
enum MyState {
SPLASH, PREQUESTION, QUESTION // ..., WIN, LOSS
}
#SuppressWarnings("serial")
class NextAction extends AbstractAction {
private Main2 main;
public NextAction(Main2 main) {
super("Next");
putValue(MNEMONIC_KEY, KeyEvent.VK_N);
this.main = main;
}
#Override
public void actionPerformed(ActionEvent e) {
main.next();
}
}
#SuppressWarnings("serial")
abstract class AbstractView extends JPanel {
private Main2 main;
public AbstractView(Main2 main) {
this.main = main;
}
public Main2 getMain() {
return main;
}
public void next() {
main.next();
}
}
#SuppressWarnings("serial")
class MySplash extends AbstractView {
private static final int TIMER_DELAY = 3000;
private Timer timer;
public MySplash(Main2 main) {
super(main);
setPreferredSize(new Dimension(300, 140));
add(new JLabel("My Splash"));
}
public void startSplashTimer() {
timer = new Timer(TIMER_DELAY, e -> {
next();
timer.stop();
});
timer.start();
}
}
#SuppressWarnings("serial")
class MyPreQuestion extends AbstractView {
public MyPreQuestion(Main2 main) {
super(main);
add(new JLabel("Prequestion"));
add(new JButton(new NextAction(main)));
}
}
#SuppressWarnings("serial")
class MyQuestion extends AbstractView {
public MyQuestion(Main2 main) {
super(main);
add(new JLabel("Question"));
add(new JButton(new NextAction(main)));
}
}

Java program hangs on stopping audio

I have written this code for a simple music player, the problem is that when I click openLabel and open a song and then when I pause it by clicking playLabel the program stops execution (program hangs).
import java.awt.*;
import java.awt.event.*;
import java.io.File;
import java.util.Random;
import javax.sound.sampled.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.filechooser.FileNameExtensionFilter;
public class A extends MouseAdapter implements ChangeListener, Runnable {
private ImageIcon playImage = new ImageIcon(getClass().getResource("Images/play.png"));
private ImageIcon pauseImage = new ImageIcon(getClass().getResource("Images/pause.png"));
private ImageIcon openImage = new ImageIcon(getClass().getResource("Images/open.png"));
private JLabel playLabel = new JLabel(playImage);
private JLabel openLabel = new JLabel(openImage);
public JFrame frame = new JFrame();
public JPanel colorPanel = new JPanel();
private enum Status {ON,OFF,PAUSE,END};
private Status playStatus=Status.OFF;
private JSlider slider = new JSlider();
public Clip songClip;
Thread screenThread = new Thread(this);
public static void main(String arg[]) throws Exception {
new A();
}
public A() throws Exception {
setFrame();
setComponents();
}
public void setFrame() {
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
frame.setUndecorated(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(null);
frame.setCursor(new Cursor(Cursor.HAND_CURSOR));
frame.getContentPane().setBackground(Color.BLACK);
frame.setVisible(true);
}
public void setComponents() {
slider.setBounds(0,640,1000,15);
slider.setBackground(Color.BLACK);
slider.addChangeListener(this);
slider.setValue(0);
playLabel.setBounds(450,665,100,100);
playLabel.addMouseListener(this);
openLabel.setBounds(540,690,60,60);
openLabel.addMouseListener(this);
colorPanel.setBackground(Color.BLACK);
colorPanel.setBounds(0,100,1500,500);
frame.add(openLabel);
frame.add(playLabel);
frame.add(colorPanel);
frame.add(slider);
}
public void mouseClicked(MouseEvent clicked) {
if (clicked.getSource() == openLabel) {
openLabel.setIcon(openImage);
open();
}
else if (clicked.getSource()==playLabel && playStatus != Status.OFF) {
if (playStatus == Status.PAUSE) {
songClip.start();
screenThread.resume();
playStatus=Status.ON;
playLabel.setIcon(pauseImage);
}
else if (playStatus == Status.ON) {
songClip.stop();
screenThread.suspend();
playStatus=Status.PAUSE;
playLabel.setIcon(playImage);
}
else if (playStatus==Status.END) {
songClip.setMicrosecondPosition(0);
slider.setValue(0);
songClip.start();
screenThread.resume();
playStatus = Status.ON;
playLabel.setIcon(pauseImage);
}
}
}
public void stateChanged(ChangeEvent e) {
if (playStatus != Status.OFF) {
JSlider jslider = (JSlider)e.getSource();
int position = jslider.getValue();
songClip.setMicrosecondPosition(position * 1000000);
}
}
public void open() {
JFileChooser chooseSong = new JFileChooser();
chooseSong.setFileSelectionMode(JFileChooser.FILES_ONLY);
chooseSong.setFileFilter(new FileNameExtensionFilter(null, "wav"));
int chooseButton = chooseSong.showOpenDialog(null);
File songPath = chooseSong.getSelectedFile();
if ( (chooseButton!=JFileChooser.CANCEL_OPTION) && (songPath!=null) && (songPath.getName() != null) ) {
try {
playLabel.setIcon(pauseImage);
if (playStatus != Status.OFF)
songClip.close();
AudioInputStream songFile = AudioSystem.getAudioInputStream(songPath);
songClip = AudioSystem.getClip();
songClip.open(songFile);
int clipLength = (int)(songClip.getMicrosecondLength() / 1000000);
slider.setMinimum(0);
slider.setMaximum(clipLength);
songClip.start();
if (playStatus == Status.OFF)
screenThread.start();
else if (playStatus != Status.OFF)
screenThread.resume();
playStatus=Status.ON;
}
catch(Exception exp) {
Toolkit.getDefaultToolkit().beep();
JOptionPane.showMessageDialog(null, String.format("ERROR = %s",exp.getClass()));
System.exit(0);
}
}
}
public void run() {
while (true) {
colorPanel.setBackground(new Color(new Random().nextInt(256), new Random().nextInt(256), new Random().nextInt(256)));
if (songClip.getMicrosecondPosition() == songClip.getMicrosecondLength()) {
screenThread.suspend();
playStatus=Status.END;
playLabel.setIcon(playImage);
}
}
}
}
This method has been deprecated, as it is inherently deadlock-prone.
This is the reason that is given for the deprecation of Thread.stop(), .suspend() and .resume(). As you are using these in your code it could be the problem.
You are calling screenThread.suspend(); in the block that responds to clicking the play/pause button. Thread methods suspend() and resume() are deadlock prone - that is, using them often causes hard-to-diagnose issues like the one you're having.
You need to remove the use of these methods by instead polling a variable, as described on this page.

Setting up KeyListeners using the MVC in java

I am trying to make myself a calculator in Java. I figured it would be best to implement the MVC (model view controller) design for my code. I have some of the basics working, the calculator does actually work, the issue is i cannot figure out where i am going wrong with the implementation of listening to keys. At the moment i have the ability to click on the buttons using the action listener and updating the field with a numeric value and the buttons to add, subtract, multiply, divide and also to clear. So really the only thing on my mind at the moment is trying to allow the user (myself) the option to use the number pad on the keyboard to append values to the field, anyways here is my code.
This the view
package Calculator;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionListener;
import java.awt.event.KeyListener;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
public class CalcFrame extends JFrame{
private Dimension d = new Dimension(300,300);
JPanel panel1 = new JPanel();
JPanel panel2 = new JPanel();
JButton equals = new JButton("=");
JButton addBtn = new JButton("+");
JButton subtractBtn = new JButton("-");
JButton multiplyBtn = new JButton("*");
JButton divideBtn = new JButton("/");
JTextArea field = new JTextArea(1,20);
JButton numBtn[] = new JButton[11];
String numTxt[] = {"0","1","2","3","4","5","6","7","8","9","C"};
Color newColor = new Color(10,70,40);
int x = 50, y = 0;
public CalcFrame(){
this.setSize(d);
this.setResizable(false);
// frame.setVisible(true);
this.setTitle("Marks Calculator");
this.setIconImage(new ImageIcon(this.getClass().getResource("emblem.png")).getImage());
for(int i = 0; i < numBtn.length; i++){
numBtn[i] = new JButton(numTxt[i]);
numBtn[i].setSize(50, 30);
}
for(int i = 0; i <numBtn.length; i++){
numBtn[0].setLocation(10,180);
numBtn[1].setLocation(10,140);
numBtn[2].setLocation(65,140);
numBtn[3].setLocation(120,140);
numBtn[4].setLocation(175,140);
numBtn[5].setLocation(10,100);
numBtn[6].setLocation(65,100);
numBtn[7].setLocation(120,100);
numBtn[8].setLocation(175,100);
numBtn[9].setLocation(10,60);
numBtn[10].setLocation(175,20);
panel2.add(numBtn[i]);
}
field.setLocation(10, 10);
field.setSize(280,30);
field.setEditable(false);
field.setFocusable(true);
panel1.setSize(300, 50);
panel1.setLayout(null);
this.add(panel1);
panel2.setSize(300, 250);
panel2.setBackground(newColor);
panel2.setLocation(0, 51);
panel2.setLayout(null);
this.add(panel2);
equals.setLocation(230,180);
equals.setSize(50, 30);
panel2.add(equals);
addBtn.setLocation(230, 140);
addBtn.setSize(50,30);
panel2.add(addBtn);
subtractBtn.setLocation(230, 100);
subtractBtn.setSize(50,30);
panel2.add(subtractBtn);
multiplyBtn.setLocation(230, 60);
multiplyBtn.setSize(50,30);
panel2.add(multiplyBtn);
divideBtn.setLocation(230, 20);
divideBtn.setSize(50,30);
panel2.add(divideBtn);
panel1.add(field);
this.setLocationRelativeTo(rootPane);
this.setLayout(null);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void addKeyL(KeyListener keyp){
addKeyListener(keyp);
}
public void addListener(ActionListener listener){
addBtn.addActionListener(listener);
subtractBtn.addActionListener(listener);
equals.addActionListener(listener);
multiplyBtn.addActionListener(listener);
divideBtn.addActionListener(listener);
for(int i = 0; i < numBtn.length; i++){
numBtn[i].addActionListener(listener);
}
}
public int getFieldText(){
return Integer.parseInt(field.getText());
}
public void setFieldText(){
field.setText("");
}
public void setAnswer(int solution){
field.setText(Integer.toString(solution));
}
}
this is the model
package Calculator;
public class Calculations {
private int total;
public void addNumbers(int a, int b){
total = a + b;
}
public void subtractNumbers(int a, int b){
total = a - b;
}
public void multiplyNumbers(int a, int b){
total = a * b;
}
public void divideNumbers(int a, int b){
total = a / b;
}
public int getTotal(){
return total;
}
}
and this is the controller
package Calculator;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
public class KeyEvents{
private boolean isAdd = false;
private boolean isSubtract = false;
private boolean isDivide = false;
private boolean isMultiply = false;
private CalcFrame view = new CalcFrame();
private Calculations model = new Calculations();
int a = 0, b = 0, answer;
int counter = 0;
public KeyEvents(CalcFrame view, Calculations model){
this.view = view;
this.model = model;
this.view.addListener(new CalcListener());
this.view.addKeyL(new CalcListener());
}
class CalcListener implements ActionListener, KeyListener{
#Override
public void actionPerformed(ActionEvent e) {
if(e.getSource().equals(view.addBtn)){
a = view.getFieldText();
view.field.setText("");
isAdd = true;
isSubtract = false;
isDivide = false;
isMultiply = false;
}
if(e.getSource().equals(view.numBtn[0])){
view.field.append("0");
}
if(e.getSource().equals(view.numBtn[1])){
view.field.append("1");
}
if(e.getSource().equals(view.numBtn[2])){
view.field.append("2");
}
if(e.getSource().equals(view.numBtn[3])){
view.field.append("3");
}
if(e.getSource().equals(view.numBtn[4])){
view.field.append("4");
}
if(e.getSource().equals(view.numBtn[5])){
view.field.append("5");
}
if(e.getSource().equals(view.numBtn[6])){
view.field.append("6");;
}
if(e.getSource().equals(view.numBtn[7])){
view.field.append("7");
}
if(e.getSource().equals(view.numBtn[8])){
view.field.append("8");
}
if(e.getSource().equals(view.numBtn[9])){
view.field.append("9");
}
if(e.getSource().equals(view.numBtn[10])){
view.field.setText("");
}
if(e.getSource().equals(view.subtractBtn)){
a = view.getFieldText();
view.field.setText("");
isAdd = false;
isSubtract = true;
isDivide = false;
isMultiply = false;
}
if(e.getSource().equals(view.multiplyBtn)){
a = view.getFieldText();
view.field.setText("");
isAdd = false;
isSubtract = false;
isDivide = false;
isMultiply = true;
}
if(e.getSource().equals(view.divideBtn)){
a = view.getFieldText();
view.field.setText("");
isAdd = false;
isSubtract = false;
isDivide = true;
isMultiply = false;
}
if(e.getSource().equals(view.equals)){
b = view.getFieldText();
if(isAdd == true){
view.setFieldText();
model.addNumbers(a, b);
view.setAnswer(model.getTotal());
}
if(isSubtract == true){
view.setFieldText();
model.subtractNumbers(a, b);
view.setAnswer(model.getTotal());
}
if(isMultiply == true){
view.setFieldText();
model.multiplyNumbers(a, b);
view.setAnswer(model.getTotal());
}
if(isDivide == true){
view.setFieldText();
model.divideNumbers(a, b);
view.setAnswer(model.getTotal());
}
}
}
#Override
public void keyTyped(KeyEvent e) {
if(e.getSource().equals(KeyEvent.VK_0)){
System.out.println("sjkdhlkj");
}
if(e.getSource().equals(KeyEvent.VK_1)){
view.field.append("1");
}
if(e.getSource().equals(KeyEvent.VK_2)){
view.field.append("2");
}
if(e.getSource().equals(KeyEvent.VK_3)){
view.field.append("3");
}
if(e.getSource().equals(KeyEvent.VK_4)){
view.field.append("4");
}
if(e.getSource().equals(KeyEvent.VK_5)){
view.field.append("5");
}
if(e.getSource().equals(KeyEvent.VK_6)){
view.field.append("6");
}
if(e.getSource().equals(KeyEvent.VK_7)){
view.field.append("7");
}
if(e.getSource().equals(KeyEvent.VK_8)){
view.field.append("8");
}
if(e.getSource().equals(KeyEvent.VK_9)){
view.field.append("9");
}
}
#Override
public void keyPressed(KeyEvent e) {
if(e.getSource().equals(KeyEvent.VK_0)){
System.out.println("sjkdhlkj");
}
if(e.getSource().equals(KeyEvent.VK_1)){
view.field.append("1");
}
if(e.getSource().equals(KeyEvent.VK_2)){
view.field.append("2");
}
if(e.getSource().equals(KeyEvent.VK_3)){
view.field.append("3");
}
if(e.getSource().equals(KeyEvent.VK_4)){
view.field.append("4");
}
if(e.getSource().equals(KeyEvent.VK_5)){
view.field.append("5");
}
if(e.getSource().equals(KeyEvent.VK_6)){
view.field.append("6");
}
if(e.getSource().equals(KeyEvent.VK_7)){
view.field.append("7");
}
if(e.getSource().equals(KeyEvent.VK_8)){
view.field.append("8");
}
if(e.getSource().equals(KeyEvent.VK_9)){
view.field.append("9");
}
}
#Override
public void keyReleased(KeyEvent e) {
if(e.getSource().equals(KeyEvent.VK_0)){
System.out.println("sjkdhlkj");
}
if(e.getSource().equals(KeyEvent.VK_1)){
view.field.append("1");
}
if(e.getSource().equals(KeyEvent.VK_2)){
view.field.append("2");
}
if(e.getSource().equals(KeyEvent.VK_3)){
view.field.append("3");
}
if(e.getSource().equals(KeyEvent.VK_4)){
view.field.append("4");
}
if(e.getSource().equals(KeyEvent.VK_5)){
view.field.append("5");
}
if(e.getSource().equals(KeyEvent.VK_6)){
view.field.append("6");
}
if(e.getSource().equals(KeyEvent.VK_7)){
view.field.append("7");
}
if(e.getSource().equals(KeyEvent.VK_8)){
view.field.append("8");
}
if(e.getSource().equals(KeyEvent.VK_9)){
view.field.append("9");
}
}
}
}
the tl;dr of this is, i am unable to get keyListener to work correctly, i have tried assigning the keyListener to the field, panel1, panel2 and this. seperately. Assistance is appreciated as always.
~UPDATE~
I decided to give GitHub a try and have just put my code up on to it. I hope it would make my code easier to understand or even forkable so a person can mess around with it.
https://github.com/niroshido/TestCalculator/tree/master/Calculator
Use Key Bindings. A simple example:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
public class CalculatorPanel extends JPanel
{
private JTextField display;
public CalculatorPanel()
{
Action numberAction = new AbstractAction()
{
#Override
public void actionPerformed(ActionEvent e)
{
display.setCaretPosition( display.getDocument().getLength() );
display.replaceSelection(e.getActionCommand());
}
};
setLayout( new BorderLayout() );
display = new JTextField();
display.setEditable( false );
display.setHorizontalAlignment(JTextField.RIGHT);
add(display, BorderLayout.NORTH);
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout( new GridLayout(0, 5) );
add(buttonPanel, BorderLayout.CENTER);
for (int i = 0; i < 10; i++)
{
String text = String.valueOf(i);
JButton button = new JButton( text );
button.addActionListener( numberAction );
button.setBorder( new LineBorder(Color.BLACK) );
button.setPreferredSize( new Dimension(50, 50) );
buttonPanel.add( button );
KeyStroke pressed = KeyStroke.getKeyStroke(text);
InputMap inputMap = button.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
inputMap.put(pressed, text);
button.getActionMap().put(text, numberAction);
}
}
private static void createAndShowUI()
{
// UIManager.put("Button.margin", new Insets(10, 10, 10, 10) );
JFrame frame = new JFrame("Calculator Panel");
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.add( new CalculatorPanel() );
frame.pack();
frame.setLocationRelativeTo( null );
frame.setVisible(true);
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowUI();
}
});
}
}
You either need to make sure that whatever component you're adding the KeyListener to has the focus, or you should use key bindings instead.

not redisplaying an image s

Hi everybody I am a bit of stack here. When I run the program and press the button submit it is supposed to change 4 pictures in every 2 seconds.However it is not redisplaying the images. If anyone can give me a hand it would be great. I am using eclipse and the program is compiling and running. Here is the code.
/** Here is the GUI of the program
* class name SlideShowGui.java
* #author Kiril Anastasov
* #date 07/03/2012
*/
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class SlideShowGui extends JPanel implements ActionListener, Runnable
{
JLabel name, comments, images;
JTextField namejtf, commentsjtf, captionjtf;
JButton submit;
ImageIcon pictures1, pictures2, pictures3, pictures4;
//ImageIcon []pictures2 = {galileo1.jpg};
SlideShowGui()
{
name = new JLabel("Name:");
this.add(name);
namejtf = new JTextField(15);
this.add(namejtf);
comments = new JLabel("Comments:");
this.add(comments);
commentsjtf = new JTextField(15);
this.add(commentsjtf);
submit = new JButton("Submit");
this.add(submit);
submit.addActionListener(this);
pictures1 = new ImageIcon("galileo1.jpg");
images = new JLabel(pictures1);
this.add(images);
pictures2 = new ImageIcon("galileo2.jpg");
this.add(images);
pictures3 = new ImageIcon("galileo3.jpg");
this.add(images);
pictures4 = new ImageIcon("galileo4.jpg");
this.add(images);
captionjtf = new JTextField(24);
this.add(captionjtf);
//pictures = new ImageIcon("galileo1.jpg");
// images.setIcon(pictures);
}
public void actionPerformed(ActionEvent ae)
{
Thread t = new Thread(this);
t.start();
if(ae.getSource() == submit)
{
int i = 0;
boolean go = true;
while(go)
{
i++;
System.out.println(i);
try
{
Thread.sleep(2000);
if(i == 1)
{
pictures1 = new ImageIcon("galileo1.jpg");
images.setIcon(pictures1);
System.out.println("picture 1 should be displayed here");
}
if(i == 2)
{
pictures2 = new ImageIcon("galileo2.jpg");
images.setIcon(pictures2);
System.out.println("picture 2 should be displayed here");
}
if(i == 3)
{
pictures3 = new ImageIcon("galileo3.jpg");
images.setIcon(pictures3);
System.out.println("picture 3 should be displayed here");
}
if(i == 4)
{
pictures4 = new ImageIcon("galileo4.jpg");
images.setIcon(pictures4);
System.out.println("picture 4 should be displayed here");
}
if(i == 4)
{
i = 0;
}
}
catch (InterruptedException ie)
{
System.out.println("thread exception");
}
}
}
}
public void run()
{
}
}
/**The driver class of the program. Here is the JFrame
* class name TestSlideShow.java
* #author Kiril Anastasov
* #date 07/03/2012
*/
import java.awt.*;
import javax.swing.*;
public class TestSlideShow
{
public static void main(String[] args)
{
JFrame application = new JFrame();
SlideShowGui panel = new SlideShowGui();
application.add(panel);
application.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
application.setSize(300,600);
application.setLocation(400,100);
application.setVisible(true);
}
}
Always use javax.swing.Timer never use Thread.sleep(...) in Swing atleast. Here try this code, but do replace the path to your images :
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class SlideShow extends JPanel
{
private int i = 0;
private Timer timer;
private JLabel images = new JLabel();
private Icon bg = UIManager.getIcon("OptionPane.warningIcon");
private Icon red = UIManager.getIcon("OptionPane.errorIcon");
private Icon blue = UIManager.getIcon("OptionPane.informationIcon");
private ImageIcon pictures1, pictures2, pictures3, pictures4;
private ActionListener action = new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
boolean go = true;
i++;
System.out.println(i);
if(i == 1)
{
images.setIcon(bg);
System.out.println("picture 1 should be displayed here");
}
if(i == 2)
{
images.setIcon(red);
System.out.println("picture 2 should be displayed here");
}
if(i == 3)
{
images.setIcon(blue);
System.out.println("picture 3 should be displayed here");
}
if(i == 4)
{
images.setIcon(bg);
System.out.println("picture 4 should be displayed here");
}
if(i == 5)
{
go = false;
timer.stop();
System.exit(0);
}
revalidate();
repaint();
}
};
public SlideShow()
{
JFrame frame = new JFrame("SLIDE SHOW");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationByPlatform(true);
frame.getContentPane().add(this);
add(images);
frame.setSize(300, 300);
frame.setVisible(true);
timer = new Timer(2000, action);
timer.start();
}
public static void main(String... args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new SlideShow();
}
});
}
}
The whole if (i == ... part can be simplified. Declare a static class member in SlideShowGUI:
private final static ImageIcon[] icons = {new ImageIcon("galileo1.jpg"),
new ImageIcon("galileo2.jpg"),
new ImageIcon("galileo3.jpg"),
new ImageIcon("galileo4.jpg")};
and use it in the replacement of the if statements:
images.setIcon(icons[i-1]);
System.printf("Picture %s should be displayed%n", i-1);
if (i == 4) {
i = 0;
}
You can simplify your code as Andreas_D mentioned.
Your current design will block the main thread as you call Thread.sleep() to it, this will freeze your application.
If you would like to update the Image, you should implement the update code inside run() method.
So if you detect the user press on submit JButton, create and start the new Thread for updating UI.

Categories