Java GUI Programming Only Restarts once - java

I have a program here that changes an avatars hat and earrings
the problem is that it only restarts once (the load button only works once)
This is what I have:
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import javax.swing.JTextArea;
public class Lab14_Navarro extends JFrame {
private int x,y,z;
private Container game;
private JComboBox Head;
private JComboBox Ear;
private JLabel Avatar;
private JTextArea details;
private String []Hat = {"No Hat", "Captain Hat", "Black Leather Hat"};
private JButton load;
private String []Earrings = {"No Earrings", "Silver Dangling Earrings", "Gold Dangling Earrings"};
private ImageIcon [] Accessories =
{ new ImageIcon("blackleather.PNG"),//0
new ImageIcon("blackleather_goldear.PNG"),//1
new ImageIcon("blackleather_silverear.PNG"),//2
new ImageIcon("captainhat.PNG"),//3
new ImageIcon("captainhat_goldear.PNG"),//4
new ImageIcon("captainhat_silverear.PNG"),//5
new ImageIcon("goldear.PNG"),//6
new ImageIcon("noaccessories.PNG"),//7
new ImageIcon("silverear.PNG")};//8
/**
* Creates a new instance of <code>Lab14_Navarro</code>.
*/
public Lab14_Navarro() {
getContentPane().removeAll();
setTitle("Avatar!");
setSize(250,450);
setLocationRelativeTo(null);
game = getContentPane();
game.setLayout(new FlowLayout());
Head = new JComboBox(Hat);
Ear = new JComboBox(Earrings);
Avatar = new JLabel(Accessories[7]);
load = new JButton("Load Image");
details = new JTextArea("AVATAR DETAILS: "+"\n"+" Hat: "+Hat[Head.getSelectedIndex()]+"\n"+" Earrings: "+Earrings[Ear.getSelectedIndex()]);
game.add(Avatar);
game.add(Head);
game.add(Ear);
game.add(load);
game.add(details, BorderLayout.SOUTH);
setVisible(true);
details.setEditable(false);
Head.addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent e){
JComboBox temphead = (JComboBox) e.getSource();
int temphat = (int) temphead.getSelectedIndex();
x = temphat;
}
});
Ear.addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent e){
JComboBox tempear = (JComboBox) e.getSource();
int tempearrings = (int) tempear.getSelectedIndex();
y = tempearrings;
}
});
load.addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent e){
getContentPane().removeAll();
if(x==0&&y==0){
z = 7;
}
if(x==0&&y==1){
z = 8;
}
if(x==0&&y==2){
z = 6;
}
if(x==1&&y==0){
z = 3;
}
if(x==1&&y==1){
z = 5;
}
if(x==1&&y==2){
z = 4;
}
if(x==2&&y==0){
z = 0;
}
if(x==2&&y==1){
z = 2;
}
if(x==2&&y==2){
z = 1;
}
setTitle("Avatar");
setSize(250,450);
setLocationRelativeTo(null);
game = getContentPane();
game.setLayout(new FlowLayout());
Head = new JComboBox(Hat);
Ear = new JComboBox(Earrings);
Avatar = new JLabel(Accessories[z]);
load = new JButton("Load Image");
details = new JTextArea("AVATAR DETAILS: "+"\n"+" Hat: "+Hat[x]+"\n"+" Earrings: "+Earrings[y]);
game.add(Avatar);
game.add(Head);
game.add(Ear);
game.add(load);
game.add(details, BorderLayout.SOUTH);
setVisible(true);
details.setEditable(false);
}
});
}
public static void main(String[] args) {
Lab14_Navarro fs = new Lab14_Navarro();
fs.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
Any help is accepted thanks
I just started Java so I'm not that good... yet

When you write, for the second time:
load = new JButton("Load Image");
you're creating a new button, however, you are not giving it a new ActionListener
On another note, you don't need to create a new Button, your original load button is still there, you need only to add it to the contentPane again.

Related

Java Tetris 2 player multiplayer GUI not working properly

basically i am working on a tetris game and i want to implement a 2 player versus mode.
for now i have a working single player and now i want to make a gui for a 2 player multiplayer. (i will make a second keylistener and a endGame condition later)
however, when i add both gamepanels (what displays the state of the game after retreiving the state of the game from the boardhandler (1 or 2 depending on which player)) i dont get a correct display/gui.
this is what it looks like:
https://gyazo.com/58f37beab249c975cd4acdb8ae0e0154
this is what it should look like (but i want 2 boards displayed since this screenshot is from singleplayerwindow):
https://gyazo.com/4aecf061109844504a05387fb3d39e8f
anyone know what i am doing wrong and/or how i could fix it ?
thank you <3
package gui;
import tetris.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
public class MultiPlayerWindow extends JPanel
{
private GameLoop gameLoop1 ;
private GameLoop gameLoop2 ;
private boolean gameLoopHasStarted1 ;
private boolean gameLoopHasStarted2 ;
private BoardHandler bh1 ;
private BoardHandler bh2 ;
private HighScoreList highScoreList;
private HumanInput inputController ;
private HumanInput inputController2 ;
private JPanel scorePanel;
private JPanel rightPanel;
public MultiPlayerWindow( MainMenu mainMenu ){
//create the variables
Board board1 = new Board(10 , 20 ) ;
Board board2 = new Board(10 , 20 ) ;
final HumanInput inputController1 = new HumanInput() ;
final HumanInput inputController2 = new HumanInput() ;
this.bh1 = new BoardHandler(board1 , true) ;
this.bh2 = new BoardHandler(board2 , true) ;
this.highScoreList = new HighScoreList() ;
//behaviour
this.addKeyListener(inputController1);
this.addKeyListener(inputController2);
this.setFocusable(true);
this.requestFocusInWindow() ;
this.setLayout(new GridBagLayout());
//create panels
scorePanel = new JPanel() ;
scorePanel.setLayout(new GridBagLayout());
scorePanel.setSize(Config.LEFTPANEL_SIZE);
rightPanel = new JPanel() ;
rightPanel.setLayout(new GridBagLayout());
rightPanel.setSize(Config.RIGHTPANEL_SIZE);
//create the ScoreBoard
final ScoreBoard scoreBoard = new ScoreBoard() ;
GridBagConstraints d = new GridBagConstraints() ;
d.gridx = 0 ;
d.gridy = 0 ;
scorePanel.add(scoreBoard , d) ;
d.insets = new Insets(30,10,10,0);
//add a timer to update ScoreBoard
new Timer(1000, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
//System.out.println("Trying to update score");
scoreBoard.setScore(gameLoop1.getScore());
scoreBoard.setScore(gameLoop2.getScore());
}
}).start();
//create the Highscore Board
HighScoreBoard highScoreBoard = new HighScoreBoard(highScoreList);
d = new GridBagConstraints();
d.gridx = 0;
d.gridy = 1;
d.insets = new Insets(30,10,10,0);
scorePanel.add(highScoreBoard, d);
//create the combobox to choose between tetris and pentris
String[] optionStrings = {"Tetris", "Pentris"};
final JComboBox optionList = new JComboBox(optionStrings);
optionList.setSelectedIndex(0);
optionList.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if(optionList.getSelectedIndex() == 0)
{
bh1.switchToTetris();
bh2.switchToTetris();
}
else if(optionList.getSelectedIndex() == 1)
{
bh1.switchToPentris();
bh2.switchToPentris();
}
}
});
optionList.addFocusListener(new FocusListener() {
#Override
public void focusGained(FocusEvent e) {
optionList.requestFocus();
}
#Override
public void focusLost(FocusEvent e) {
}
});
d = new GridBagConstraints();
d.gridx = 0;
d.gridy = 2;
d.weightx = 0.5;
d.insets = new Insets(30,10,10,0);
scorePanel.add(optionList, d);
//add the scorePanel
d = new GridBagConstraints();
d.gridx = 1;
d.gridy = 0;
this.add(scorePanel, d);
final GamePanel gamePanel1 = new GamePanel(board1);
final GamePanel gamePanel2 = new GamePanel(board2);
gamePanel1.setSize(Config.GAMEPANEL_SIZE);
gamePanel2.setSize(Config.GAMEPANEL_SIZE);
d = new GridBagConstraints();
d.gridx = 0;
d.gridy = 0;
this.add(gamePanel1, d);
d = new GridBagConstraints();
d.gridx = 2;
d.gridy = 0;
this.add(gamePanel2, d);
//set the Thread
gameLoop1 = new GameLoop(bh1, inputController1, gamePanel1, highScoreList);
gameLoop2 = new GameLoop(bh2, inputController2, gamePanel2, highScoreList);
gameLoop1.start();
gameLoop2.start();
gameLoopHasStarted1 = false;
gameLoopHasStarted2 = false;
//add the buttons
JPanel buttonPanel = new JPanel();
buttonPanel.setAlignmentX(30);
buttonPanel.setLayout(new GridLayout(3,1,10,10));
d = new GridBagConstraints();
d.gridx = 0;
d.weightx = 0.2;
d.gridy = 0;
d.insets = new Insets(200,20,0,20);
rightPanel.add(buttonPanel, d);
//backbutton
d = new GridBagConstraints();
d.gridx = 0;
d.gridy = 1;
d.anchor = GridBagConstraints.SOUTH;
d.insets = new Insets(20, 20, 0, 20);
rightPanel.add(new BackButton(mainMenu), d);
//add the right panel
d = new GridBagConstraints();
d.gridx = 3;
d.gridy = 0;
this.add(rightPanel, d);
final JButton startButton = new JButton("Start");
startButton.requestFocus(false);
startButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if(!gameLoopHasStarted1 && !gameLoopHasStarted2)
{
try{
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run(){
gameLoopHasStarted1 = true;
gameLoopHasStarted2 = true;
gameLoop1.startNewGame();
gameLoop2.startNewGame();
optionList.setEnabled(false);
requestFocusInWindow();
startButton.setEnabled(false);
}
});
}
catch(Exception expenction)
{
expenction.printStackTrace();
}
}
}
});
buttonPanel.add(startButton);
//pause button
final JButton pauseButton = new JButton("Pause ");
buttonPanel.add(pauseButton);
pauseButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if(!gameLoop1.isPaused() && !gameLoop2.isPaused()) {
gameLoop1.setPaused(true);
gameLoop2.setPaused(true);
pauseButton.setText("Unpause");
}
else if(gameLoop1.isPaused()&& gameLoop2.isPaused())
{
gameLoop1.setPaused(false);
gameLoop2.setPaused(false);
pauseButton.setText("Pause ");
}
}
});
//reset button
JButton resetButton = new JButton("Reset");
buttonPanel.add(resetButton);
resetButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
bh1.resetBoard();
bh2.resetBoard();
optionList.setEnabled(true);
if(gameLoop1.isRunning() && gameLoop2.isRunning())
{
gameLoop1.apruptGameEnd();
gameLoop2.apruptGameEnd();
}
gameLoopHasStarted1 = false;
gameLoopHasStarted2 = false;
gamePanel1.repaint();
gamePanel2.repaint();
startButton.setEnabled(true);
gameLoop1.setPaused(false);
gameLoop2.setPaused(false);
pauseButton.setText("Pause");
scoreBoard.setScore(0);
}
});
//focuslistener for inputController
this.addFocusListener(new FocusListener() {
#Override
public void focusGained(FocusEvent e) {
}
#Override
public void focusLost(FocusEvent e) {
requestFocusInWindow();
}
});
}
public Dimension getPreferredSize()
{
return Config.SINGLE_PLAYER_SIZE;
}
}
fixed it.
public Dimension getPreferredSize()
{
return Config.SINGLE_PLAYER_SIZE;
}
this last part was what was messing it up, the rest of the code works fine but was previously then (for some tbh unknown reason) messed up by this. not 100% sure why...

JPanel doesn't load when called after another JPanel

I'm building a GUI, my program runs a series of tests. I end up closing my first JPanel window, and opening another one. When I run the second GUI window's class, it works just great. But after closing the first one, the window will come up, but no components will display. Is this a memory issue? What can I do about it?
Code:
package GUI;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
#SuppressWarnings("serial")
public class guiRun extends JFrame {
public guiRun() {
JPanel Window = new JPanel();
getContentPane().add(Window);
JLabel greeting = new JLabel("Automated Module Tester-Running");
JLabel Browser = new JLabel("Current Browser:");
JLabel cFailures = new JLabel("Current Fails:");
JLabel cSuccess = new JLabel("Current Successes:");
JLabel RunTime = new JLabel("Total RunTime:");
JLabel totalTests = new JLabel("Total Tests:");
JLabel Username = new JLabel("Username Under Test:");
JLabel Router = new JLabel("Router Under Test:");
JLabel TestType = new JLabel("Test Type: ");
final JLabel RunTimetime = new JLabel("00:00:00");
final JLabel cBrowser = new JLabel(currentBrowser);
final JLabel Failures = new JLabel(Integer.toString(tFails));
final JLabel Successes = new JLabel(Integer.toString(tSuccesses));
final JLabel Total = new JLabel (Integer.toString(tFails+tSuccesses));
final JLabel cUsername = new JLabel(currentUser);
final JLabel cRouter = new JLabel(currentRouter);
final JLabel theTestType = new JLabel(currentTest);
JButton End = new JButton("End Test");
JLabel loopProgress = new JLabel("Loop Progress:");
final JProgressBar PBar = new JProgressBar(currentProgress);
Window.setLayout(null);
greeting.setBounds(350,10,200,40);
Browser.setBounds(670,150,150,20);
cBrowser.setBounds(695,170,100,30);
totalTests.setBounds(100,130,100,20);
Total.setBounds(250,130,50,20);
cFailures.setBounds(100,170,100,20);
Failures.setBounds(250,170,50,20);
cSuccess.setBounds(100,210,150,20);
Successes.setBounds(250,210,50,20);
RunTime.setBounds(100,250,150,20);
RunTimetime.setBounds(250,250,100,20);
TestType.setBounds(350,150,150,25);
theTestType.setBounds(500,150,100,25);
Username.setBounds(350,175,150,25);
Router.setBounds(350,200,150,25);
cUsername.setBounds(500,175,100,25);
cRouter.setBounds(500,200,100, 25);
End.setBounds(320, 320, 200, 60);
loopProgress.setBounds(375,390,200,40);
PBar.setValue(currentProgress);
PBar.setMaximum(maxProgress);
PBar.setBounds(100, 430, 700, 50);
End.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
ActionListener updateClockAction = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
PBar.setValue(currentProgress);
PBar.setMaximum(maxProgress);
theTestType.setText(currentTest);
cRouter.setText(currentRouter);
cUsername.setText(currentUser);
Total.setText(Integer.toString(tFails+tSuccesses));
Successes.setText(Integer.toString(tSuccesses));
Failures.setText(Integer.toString(tFails));
cBrowser.setText(currentBrowser);
secs++;
if (secs>=60){
mins++;
secs = 0;
}
if (mins >=60){
hours++;
mins = 0;
}
RunTimetime.setText(hours+":"+mins+":"+secs);
}
};
//ActionListener
Timer time = new Timer(1000, updateClockAction);
time.start();
Window.add(Username);
Window.add(cUsername);
Window.add(Router);
Window.add(cRouter);
Window.add(theTestType);
Window.add(TestType);
Window.add(End);
Window.add(totalTests);
Window.add(Total);
Window.add(cFailures);
Window.add(cSuccess);
Window.add(Successes);
Window.add(Failures);
Window.add(RunTimetime);
Window.add(RunTime);
Window.add(Browser);
Window.add(cBrowser);
Window.add(greeting);
Window.add(loopProgress);
Window.add(PBar);
setTitle("Module Tester - Running ");
setSize(900,600);
setResizable(false);
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public void setBrowser(String thebrowser){currentBrowser = thebrowser;}
public void setUser(String theUser){currentUser = theUser;}
public void setRouter(String theRouter){currentRouter = theRouter;}
public void setProgress(int set){currentProgress = set;}
public void setMaxProgress(int max){maxProgress = max;}
public void addFail(){tFails++;}
public void addSuccess(){tSuccesses++;}
public void setCurrentTest(String test){currentTest = test;}
private
int hours = 0;
int mins = 0;
int secs = 0;
String currentBrowser;
String currentUser;
String currentRouter;
int currentProgress = 0;
int maxProgress = 100;
int tFails = 0;
int tSuccesses = 0;
String currentTest;
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
guiRun window = new guiRun();
window.setVisible(true);
}
});
}
}
use window.repaint() or jpanel.repaint()

DocumentListener Java, How do I prevent empty string in JTextBox?

I have been working on a personal project to get better with programming. My goal is to make it much more robust, I am just starting. I am a current computer science student. Anyway, I am working on making a portion of the program as shown. I calculates the hourly wage and provides some outputs I havent implemented yet. I'm using DocumentListener so it it will automatically calculate. I am getting an error when the the text is removed completely from a box.I tried to fix it with the if statement:
if (tipMon.equals("") || tipMon == null) {
tipMon.setText("0");
}
Here is what I have so far. It's not done yet and I apologize for the noob code. I started 2 months ago with actual coding.
import java.awt.GridLayout;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.JOptionPane;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.Document;
import javax.swing.text.FieldView;
public class deliveryDocListener extends JFrame implements ActionListener,
DocumentListener{
private JLabel mon, tues, wed, thurs, fri, sat, sun, hourlyWage, blank, row2, monWage,
tuesWage,wedWage,thursWage, friWage, satWage, sunWage, total, totalTips, totalHours,
totalHourlyEarnings, totalPay, weekPay;
private JTextField hourlyWageInput, tipMon, tipTues, tipWed, tipThurs, tipFri, tipSat, tipSun,
hourMon, hourTues, hourWed, hourThurs, hourFri, hourSat, hourSun;
public deliveryDocListener(){
super("Delivery Helper v0.1 Alpha");
setLayout(new GridLayout(0,4));
hourlyWage = new JLabel("Hourly Wage: ");
add(hourlyWage);
hourlyWageInput = new JTextField("7.25", 5);
add(hourlyWageInput);
blank = new JLabel();
add(blank);
blank = new JLabel();
add(blank);
row2 = new JLabel("Day of the Week");
add(row2);
row2 = new JLabel("Tips");
add(row2);
row2 = new JLabel("Hours Worked");
add(row2);
row2 = new JLabel("Hourly Earnings");
add(row2);
mon = new JLabel("Monday");
add(mon);
tipMon = new JTextField("0");
Document tipMonListener = tipMon.getDocument();
//Document class doc variable stores what happens in the getDocument()
//method, getDocument() i think is what checked it real time we shall see
tipMonListener.addDocumentListener(this);
//add listener to he text field, this refers to most recent object (tipMon = new JTextField("0");"
//notice how its purple is the same as new where the object got made?
add(tipMon);
hourMon = new JTextField("0");
Document hourMonListener = hourMon.getDocument();
hourMonListener.addDocumentListener(this);
add(hourMon);
monWage = new JLabel("0");
add(monWage);
tues = new JLabel("Tuesday");
add(tues);
tipTues = new JTextField("0");
add(tipTues);
hourTues = new JTextField("0");
add(hourTues);
tuesWage = new JLabel("0");
add(tuesWage);
wed = new JLabel("Wednesday");
add(wed);
tipWed = new JTextField("0");
add(tipWed);
hourWed = new JTextField("0");
add(hourWed);
wedWage = new JLabel("0");
add(wedWage);
thurs = new JLabel("Thursday");
add(thurs);
tipThurs = new JTextField("0");
add(tipThurs);
hourThurs = new JTextField("0");
add(hourThurs);
thursWage = new JLabel("0");
add(thursWage);
fri = new JLabel("Friday");
add(fri);
tipFri = new JTextField("0");
add(tipFri);
hourFri = new JTextField("0");
add(hourFri);
friWage = new JLabel("0");
add(friWage);
sat = new JLabel("Saturday");
add(sat);
tipSat = new JTextField("0");
add(tipSat);
hourSat = new JTextField("0");
add(hourSat);
satWage = new JLabel("0");
add(satWage);
sun = new JLabel("Sunday");
add(sun);
tipSun = new JTextField("0");
add(tipSun);
hourSun = new JTextField("0");
add(hourSun);
sunWage = new JLabel("0");
add(sunWage);
blank = new JLabel();
add(blank);
blank = new JLabel();
add(blank);
blank = new JLabel();
add(blank);
blank = new JLabel();
add(blank);
total = new JLabel("Total: ");
add(total);
totalTips = new JLabel("totalTipsOutput");
add(totalTips);
totalHours = new JLabel("totalHoursOutput");
add(totalHours);
totalHourlyEarnings = new JLabel("totalHourlyEarningsOutput");
add(totalHourlyEarnings);
blank = new JLabel();
add(blank);
blank = new JLabel();
add(blank);
blank = new JLabel();
add(blank);
blank = new JLabel();
add(blank);
blank = new JLabel();
add(blank);
blank = new JLabel();
add(blank);
totalPay = new JLabel("Gross Income: ");
add(totalPay);
weekPay = new JLabel("totalPayOutput");
add(weekPay);
}
#Override
public void changedUpdate(DocumentEvent e) {
// TODO Auto-generated method stub
}
#Override
public void insertUpdate(DocumentEvent e) {
//executes when someone enters text into input
String tipMonStr = tipMon.getText();
//monWage.setText(tipMonStr);
String hourMonStr = hourMon.getText();
double x = Double.parseDouble(tipMonStr);
double y = Double.parseDouble(hourMonStr);
double z = Double.parseDouble(hourlyWageInput.getText());
if (tipMonStr.length() == 0) {
tipMon.setText("0");
}
if (hourMonStr.length() == 0) {
y = 0;
hourMonStr = "0";
}
if (hourlyWageInput.getText().length() == 0) {
z = 0;
//String z = "0";
}
monWage.setText(Double.toString((z*y+x)/y));
//bug when nothing in cell because no number (0) to use in math
}
#Override
public void removeUpdate(DocumentEvent e) {
//executes when someone enters text into input
String tipMonStr = tipMon.getText();
//monWage.setText(tipMonStr);
String hourMonStr = hourMon.getText();
double x = Double.parseDouble(tipMonStr);
double y = Double.parseDouble(hourMonStr);
double z = Double.parseDouble(hourlyWageInput.getText());
monWage.setText(Double.toString((z*y+x)/y));
if (tipMon.equals("") || tipMon == null) {
tipMon.setText("0");
}
}
public void updateLog(DocumentEvent e, String action) {
monWage.setText(Double.toString(5));
}
#Override
public void actionPerformed(ActionEvent arg0) {
monWage.setText(Double.toString(5));
}
}
As #HFOE suggests, InputVerifier is the right choice, but verify() "should have no side effects." Instead, invoke calcProduct() in shouldYieldFocus().
/**
* #see http://stackoverflow.com/a/11818946/230513
*/
private class MyInputVerifier extends InputVerifier {
private JTextField field;
private double value;
public MyInputVerifier(JTextField field) {
this.field = field;
}
#Override
public boolean shouldYieldFocus(JComponent input) {
if (verify(input)) {
field.setText(String.valueOf(value));
calcProduct();
return true;
} else {
field.setText(ZERO);
field.selectAll();
return false;
}
}
#Override
public boolean verify(JComponent input) {
try {
value = Double.parseDouble(field.getText());
return true;
} catch (NumberFormatException e) {
return false;
}
}
}
I'll make this an answer: I wouldn't use a DocumentListener for this purpose as it seems to me the wrong tool for the job. For one, it is continually listening and updating the results while the user is still entering data, data that is as yet incomplete, into the JTextField. Much better would be to use an ActionListener added to a JButton or to your JTextFields.
I suppose you could use a FocusListener, but even that concerns me since it is quite low-level.
Also: consider using an InputVerifier to validate your input.
Also: consider displaying your tabular data in a JTable where the 1st and 2nd columns are editable but the others are not.
Edit
I'm not sure if this is kosher, but it could work if you do your calculation from within the verifier. For example, updated for generality:
import javax.swing.*;
/**
* #see http://stackoverflow.com/a/11818183/522444
*/
public class VerifierEg {
private static final String ZERO = "0.0";
private JTextField field1 = new JTextField(ZERO, 5);
private JTextField field2 = new JTextField(ZERO, 5);
private JTextField resultField = new JTextField(ZERO, 10);
private void createAndShowGui() {
resultField.setEditable(false);
resultField.setFocusable(false);
JPanel mainPanel = new JPanel();
final JTextField[] fields = {field1, field2};
mainPanel.add(field1);
mainPanel.add(new JLabel(" x "));
mainPanel.add(field2);
mainPanel.add(new JLabel(" = "));
mainPanel.add(resultField);
for (JTextField field : fields) {
field.setInputVerifier(new MyInputVerifier(field));
}
JFrame frame = new JFrame("VerifierEg");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private void calcProduct() {
double d1 = Double.parseDouble(field1.getText());
double d2 = Double.parseDouble(field2.getText());
double prod = d1 * d2;
resultField.setText(String.valueOf(prod));
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
VerifierEg eg = new VerifierEg();
eg.createAndShowGui();
}
});
}
/**
* #see http://stackoverflow.com/a/11818946/230513
*/
private class MyInputVerifier extends InputVerifier {
private JTextField field;
private double value;
public MyInputVerifier(JTextField field) {
this.field = field;
}
#Override
public boolean shouldYieldFocus(JComponent input) {
if (verify(input)) {
field.setText(String.valueOf(value));
calcProduct();
return true;
} else {
field.setText(ZERO);
field.selectAll();
return false;
}
}
#Override
public boolean verify(JComponent input) {
try {
value = Double.parseDouble(field.getText());
return true;
} catch (NumberFormatException e) {
return false;
}
}
}
}
use JSpinner or JFormattedTextField with Number instance, then DocumentListener should be works correctly, no needed to parse String to Number instance
otherwise you have to use DocumentFilter for JTextField for filtering non numeric chars, rest (counting) stays unchanged, stil required robust parsing String to the Number instance

Update JLabel every X seconds from ArrayList<List> - Java

I have a simple Java program that reads in a text file, splits it by " " (spaces), displays the first word, waits 2 seconds, displays the next... etc... I would like to do this in Spring or some other GUI.
Any suggestions on how I can easily update the words with spring? Iterate through my list and somehow use setText();
I am not having any luck. I am using this method to print my words out in the consol and added the JFrame to it... Works great in the consol, but puts out endless jframe. I found most of it online.
private void printWords() {
for (int i = 0; i < words.size(); i++) {
//How many words?
//System.out.print(words.size());
//print each word on a new line...
Word w = words.get(i);
System.out.println(w.name);
//pause between each word.
try{
Thread.sleep(500);
}
catch(InterruptedException e){
e.printStackTrace();
}
JFrame frame = new JFrame("Run Text File");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel textLabel = new JLabel(w.name,SwingConstants.CENTER);
textLabel.setPreferredSize(new Dimension(300, 100));
frame.getContentPane().add(textLabel, BorderLayout.CENTER);
//Display the window. frame.setLocationRelativeTo(null);
frame.pack();
frame.setVisible(true);
}
}
I have a window that get's created with JFrame and JLable, however, I would like to have the static text be dynamic instead of loading a new spring window. I would like it to flash a word, disappear, flash a word disappear.
Any suggestions on how to update the JLabel? Something with repaint()? I am drawing a blank.
Thanks!
UPDATE:
With the help from the kind folks below, I have gotten it to print correctly to the console. Here is my Print Method:
private void printWords() {
final Timer timer = new Timer(500, null);
ActionListener listener = new ActionListener() {
private Iterator<Word> w = words.iterator();
#Override
public void actionPerformed(ActionEvent e) {
if (w.hasNext()) {
_textField.setText(w.next().getName());
//Prints to Console just Fine...
//System.out.println(w.next().getName());
}
else {
timer.stop();
}
}
};
timer.addActionListener(listener);
timer.start();
}
However, it isn't updating the lable? My contructor looks like:
public TimeThis() {
_textField = new JTextField(5);
_textField.setEditable(false);
_textField.setFont(new Font("sansserif", Font.PLAIN, 30));
JPanel content = new JPanel();
content.setLayout(new FlowLayout());
content.add(_textField);
this.setContentPane(content);
this.setTitle("Swing Timer");
this.pack();
this.setLocationRelativeTo(null);
this.setResizable(false);
//_textField.setText("loading...");
}
Getting there... I'll post the fix once I, or whomever assists me, get's it working. Thanks again!
First, build and display your GUI. Once the GUI is displayed, use a javax.swing.Timer to update the GUI every 500 millis:
final Timer timer = new Timer(500, null);
ActionListener listener = new ActionListsner() {
private Iterator<Word> it = words.iterator();
#Override
public void actionPerformed(ActionEvent e) {
if (it.hasNext()) {
label.setText(it.next().getName());
}
else {
timer.stop();
}
}
};
timer.addActionListener(listener);
timer.start();
Never use Thread.sleep(int) inside Swing Code, because it blocks the EDT; more here,
The result of using Thread.sleep(int) is this:
When Thread.sleep(int) ends
Example code:
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.image.BufferedImage;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Random;
import javax.swing.*;
//http://stackoverflow.com/questions/7943584/update-jlabel-every-x-seconds-from-arraylistlist-java
public class ButtonsIcon extends JFrame implements Runnable {
private static final long serialVersionUID = 1L;
private Queue<Icon> iconQueue = new LinkedList<Icon>();
private JLabel label = new JLabel();
private Random random = new Random();
private JPanel buttonPanel = new JPanel();
private JPanel labelPanel = new JPanel();
private Timer backTtimer;
private Timer labelTimer;
private JLabel one = new JLabel("one");
private JLabel two = new JLabel("two");
private JLabel three = new JLabel("three");
private final String[] petStrings = {"Bird", "Cat", "Dog",
"Rabbit", "Pig", "Fish", "Horse", "Cow", "Bee", "Skunk"};
private boolean runProcess = true;
private int index = 1;
private int index1 = 1;
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
ButtonsIcon t = new ButtonsIcon();
}
});
}
public ButtonsIcon() {
iconQueue.add(UIManager.getIcon("OptionPane.errorIcon"));
iconQueue.add(UIManager.getIcon("OptionPane.informationIcon"));
iconQueue.add(UIManager.getIcon("OptionPane.warningIcon"));
iconQueue.add(UIManager.getIcon("OptionPane.questionIcon"));
one.setFont(new Font("Dialog", Font.BOLD, 24));
one.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
two.setFont(new Font("Dialog", Font.BOLD, 24));
two.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
three.setFont(new Font("Dialog", Font.BOLD, 10));
three.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
labelPanel.setLayout(new GridLayout(0, 3, 4, 4));
labelPanel.add(one);
labelPanel.add(two);
labelPanel.add(three);
//labelPanel.setBorder(new LineBorder(Color.black, 1));
labelPanel.setOpaque(false);
JButton button0 = createButton();
JButton button1 = createButton();
JButton button2 = createButton();
JButton button3 = createButton();
buttonPanel.setLayout(new GridLayout(0, 4, 4, 4));
buttonPanel.add(button0);
buttonPanel.add(button1);
buttonPanel.add(button2);
buttonPanel.add(button3);
//buttonPanel.setBorder(new LineBorder(Color.black, 1));
buttonPanel.setOpaque(false);
label.setLayout(new BorderLayout());
label.add(labelPanel, BorderLayout.NORTH);
label.add(buttonPanel, BorderLayout.SOUTH);
Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
label.setPreferredSize(new Dimension(d.width / 3, d.height / 3));
add(label, BorderLayout.CENTER);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
setVisible(true);
startBackground();
startLabel2();
new Thread(this).start();
printWords(); // generating freeze Swing GUI durring EDT
}
private JButton createButton() {
JButton button = new JButton();
button.setBorderPainted(false);
button.setBorder(null);
button.setFocusable(false);
button.setMargin(new Insets(0, 0, 0, 0));
button.setContentAreaFilled(false);
button.setIcon(nextIcon());
button.setRolloverIcon(nextIcon());
button.setPressedIcon(nextIcon());
button.setDisabledIcon(nextIcon());
nextIcon();
return button;
}
private Icon nextIcon() {
Icon icon = iconQueue.peek();
iconQueue.add(iconQueue.remove());
return icon;
}
// Update background at 4/3 Hz
private void startBackground() {
backTtimer = new javax.swing.Timer(750, updateBackground());
backTtimer.start();
backTtimer.setRepeats(true);
}
private Action updateBackground() {
return new AbstractAction("Background action") {
private static final long serialVersionUID = 1L;
#Override
public void actionPerformed(ActionEvent e) {
label.setIcon(new ImageIcon(getImage()));
}
};
}
// Update Label two at 2 Hz
private void startLabel2() {
labelTimer = new javax.swing.Timer(500, updateLabel2());
labelTimer.start();
labelTimer.setRepeats(true);
}
private Action updateLabel2() {
return new AbstractAction("Label action") {
private static final long serialVersionUID = 1L;
#Override
public void actionPerformed(ActionEvent e) {
two.setText(petStrings[index]);
index = (index + 1) % petStrings.length;
}
};
}
// Update lable one at 3 Hz
#Override
public void run() {
while (runProcess) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
one.setText(petStrings[index1]);
index1 = (index1 + 1) % petStrings.length;
}
});
try {
Thread.sleep(300);
} catch (Exception e) {
e.printStackTrace();
}
}
}
// Note: blocks EDT
private void printWords() {
for (int i = 0; i < petStrings.length; i++) {
String word = petStrings[i].toString();
System.out.println(word);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
three.setText(word);
}
three.setText("<html> Concurency Issues in Swing<br>"
+ " never to use Thread.sleep(int) <br>"
+ " durring EDT, simple to freeze GUI </html>");
}
public BufferedImage getImage() {
int w = label.getWidth();
int h = label.getHeight();
GradientPaint gp = new GradientPaint(0f, 0f, new Color(
127 + random.nextInt(128),
127 + random.nextInt(128),
127 + random.nextInt(128)),
w, w,
new Color(random.nextInt(128), random.nextInt(128), random.nextInt(128)));
BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = bi.createGraphics();
g2d.setPaint(gp);
g2d.fillRect(0, 0, w, h);
g2d.setColor(Color.BLACK);
return bi;
}
}
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import javax.swing.*;
class TimeThis extends JFrame {
private static final long serialVersionUID = 1L;
private ArrayList<Word> words;
private JTextField _textField; // set by timer listener
public TimeThis() throws IOException {
_textField = new JTextField(5);
_textField.setEditable(false);
_textField.setFont(new Font("sansserif", Font.PLAIN, 30));
JPanel content = new JPanel();
content.setLayout(new FlowLayout());
content.add(_textField);
this.setContentPane(content);
this.setTitle("Swing Timer");
this.pack();
this.setLocationRelativeTo(null);
this.setResizable(false);
_textField.setText("loading...");
readFile(); // read file
printWords(); // print results
}
public void readFile(){
try {
BufferedReader in = new BufferedReader(new FileReader("adameve.txt"));
words = new ArrayList<Word>();
int lineNum = 1; // we read first line in start
// delimeters of line in this example only "space"
char [] parse = {' '};
String delims = new String(parse);
String line = in.readLine();
String [] lineWords = line.split(delims);
// split the words and create word object
//System.out.println(lineWords.length);
for (int i = 0; i < lineWords.length; i++) {
Word w = new Word(lineWords[i]);
words.add(w);
}
lineNum++; // pass the next line
line = in.readLine();
in.close();
} catch (IOException e) {
}
}
private void printWords() {
final Timer timer = new Timer(100, null);
ActionListener listener = new ActionListener() {
private Iterator<Word> w = words.iterator();
#Override
public void actionPerformed(ActionEvent e) {
if (w.hasNext()) {
_textField.setText(w.next().getName());
//Prints to Console just Fine...
//System.out.println(w.next().getName());
}
else {
timer.stop();
}
}
};
timer.addActionListener(listener);
timer.start();
}
class Word{
private String name;
public Word(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
public static void main(String[] args) throws IOException {
JFrame ani = new TimeThis();
ani.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ani.setVisible(true);
}
}
I got it working with this code... Hope it can help someone else expand on their Java knowledge. Also, if anyone has any recommendations on cleaning this up. Please do so!
You're on the right track, but you're creating the frame's inside the loop, not outside. Here's what it should be like:
private void printWords() {
JFrame frame = new JFrame("Run Text File");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel textLabel = new JLabel("", SwingConstants.CENTER);
textLabel.setPreferredSize(new Dimension(300, 100));
frame.getContentPane().add(textLabel, BorderLayout.CENTER);
//Display the window. frame.setLocationRelativeTo(null);
frame.pack();
frame.setVisible(true);
for (int i = 0; i < words.size(); i++) {
//How many words?
//System.out.print(words.size());
//print each word on a new line...
Word w = words.get(i);
System.out.println(w.name);
//pause between each word.
try{
Thread.sleep(500);
}
catch(InterruptedException e){
e.printStackTrace();
}
textLabel.setTest(w.name);
}
}

JComboBox is throwing a NullPointerException when told to addItemListener()

I am getting a NullPointerException on line 27 (listOfWindTurbines.addItemListener(new dropDownListener());) when I try to run my program. Please Help!
import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
public class PlannerMain {
JFrame frame;
JButton makeMap;
JPanel panel;
JLabel outcome;
JComboBox listOfWindTurbines;
String[] windTurbineSpace = new String[10];
Integer[] windTurbineLengths = new Integer[10];
Integer[] windTurbineWidths = new Integer[10];
JTextField lengthOfRoom, widthOfRoom, widthObjectNeeds, lengthObjectNeeds;
int lengthOfRoomInt, widthOfRoomInt, widthObjectNeedsInt, lengthObjectNeedsInt, largerObjectMeasurement, numberOfItems, numberOfItemsShort;
public static void main(String[] args){
PlannerMain p = new PlannerMain();
}
public PlannerMain(){
windTurbineLengths[0] = 1;
windTurbineWidths[0] = 1;
for(int i = 0;i<=9;i++){
int wNum = i + 1;
windTurbineSpace[i] = "Windturbine "+ wNum;
}
listOfWindTurbines.addItemListener(new dropDownListener());
frame = new JFrame("Minecraft Land Planner");
outcome = new JLabel();
panel = new JPanel();
makeMap = new JButton("Make Map");
lengthOfRoom = new JTextField("Length of Room");
widthOfRoom = new JTextField("Width of Room");
widthObjectNeeds = new JTextField("Width Object Needs");
lengthObjectNeeds = new JTextField("Length Object Needs");
listOfWindTurbines = new JComboBox(windTurbineSpace);
makeMap.addActionListener(new makeMapListener());
frame.setSize(580,550);
frame.add(panel);
panel.add(makeMap);
panel.add(lengthOfRoom);
panel.add(widthOfRoom);
panel.add(lengthObjectNeeds);
panel.add(widthObjectNeeds);
panel.add(listOfWindTurbines);
panel.add(outcome);
frame.setVisible(true);
}
class makeMapListener implements ActionListener{
public void actionPerformed(ActionEvent e) {
lengthOfRoomInt = Integer.parseInt(lengthOfRoom.getText());
widthOfRoomInt = Integer.parseInt(widthOfRoom.getText());
lengthObjectNeedsInt = Integer.parseInt(lengthObjectNeeds.getText());
widthObjectNeedsInt = Integer.parseInt(widthObjectNeeds.getText());
if(lengthObjectNeedsInt<=widthObjectNeedsInt){
largerObjectMeasurement = widthObjectNeedsInt;
}
if(widthObjectNeedsInt<=lengthObjectNeedsInt){
largerObjectMeasurement = lengthObjectNeedsInt;
}
numberOfItems = (lengthOfRoomInt/lengthObjectNeedsInt)*(widthOfRoomInt/widthObjectNeedsInt);
outcome.setText(String.valueOf(numberOfItems));
lengthOfRoom.setSize(30, 20);
widthOfRoom.setSize(30, 20);
widthObjectNeeds.setSize(30, 10);
lengthObjectNeeds.setSize(100, 20);
}
}
class dropDownListener implements ItemListener{
public void itemStateChanged(ItemEvent event) {
if(event.getStateChange() == ItemEvent.SELECTED){
lengthObjectNeeds.setText(Integer.toString(windTurbineLengths[listOfWindTurbines.getSelectedIndex()]));
widthObjectNeeds.setText(Integer.toString(windTurbineLengths[listOfWindTurbines.getSelectedIndex()]));
}
}
}
}
You need to initialize the listOfWindTurbines variable, for example:
JComboBox listOfWindTurbines = new JComboBox();

Categories