How do I know if increment/decrement on JSpinner is pressed? - java

I have a few JSpinners and they are numeric values starting at 10 and can be incremented until 99.
In my program the user has 15 points to disperse evenly across 6 skills. Every JSpinner has an EventListener to detect if its pressed, but more specifically I need to know which button was pressed so I know which action to take. They dont want to take a point off of strength and have it decrement the Total Points by 1, Instead if the Decrement is pressed it should Add 1.
What would be the best method to execute this?
(Also I am using NetBeans so a bit of the program is autoGenerated.)

Presumably you are somewhere inside a ChangeListener's stateChanged method - take a look at ChangeEvent#getSource()
Ok, your edit made my original answer pretty pointless.
Would creating your own SpinnerModel be a viable option?

I encountered the same problem, this is how I solved the implementation for my actions scenario:
First I collect all arrow buttons:
private static HashMap<String, BasicArrowButton> getSpinnerButtons(JSpinner spinner, String[] arrowNames) {
final Stack<String> arrows = new Stack<String>();
arrows.addAll( Arrays.asList( arrowNames ) );
final HashMap<String, BasicArrowButton> buttons = new HashMap<String, BasicArrowButton>();
while (buttons.size()<2) {
for (final Component c : spinner.getComponents()) {
if (c instanceof BasicArrowButton) {
final BasicArrowButton bab = (BasicArrowButton)c;
for (final String sName : arrows) {
if (sName.equals(bab.getName())&&!buttons.containsKey(sName)) {
buttons.put(sName,bab);
break;
}
}
}
}
}
return buttons;
}
Then I attach some listener:
final String KEY_PROP = ".DIRECTION";
final String BS = spinner.getName(), BN="Spinner.nextButton", BP="Spinner.previousButton";
final String BSKEY = BS+KEY_PROP, BNKEY = BN+KEY_PROP, BPKEY = BP+KEY_PROP;
final HashMap<String, BasicArrowButton> buttons = getSpinnerButtons(spinner, new String[]{BN,BP});
spinner.putClientProperty( BSKEY, 1000);
spinner.putClientProperty( BNKEY, buttons.get(BN).getDirection()*+10000);
spinner.putClientProperty( BPKEY, buttons.get(BP).getDirection()*-10000);
final PropertyChangeListener pcl = new PropertyChangeListener() {
#Override
public void propertyChange(PropertyChangeEvent evt) {
final JSpinner spinnerRef = ((JSpinner)evt.getSource());
final String pName = evt.getPropertyName();
final short swing = Short.parseShort( String.valueOf(evt.getOldValue()) );
final short val = Short.parseShort( String.valueOf(evt.getNewValue()) );
if (Math.abs(swing)<2D)
System.out.printf("This is a DIRECTION CHANGE\nOld Direction=%s;\nNew Direction=%s;\nProp Value: %s", swing, val, spinnerRef.getClientProperty(pName) ).println();
else //arrows
System.out.printf("This is the CURRENT DIRECTION\nArrow=%s;\nDirection=%s;\nProp Value: %s", swing, val, spinnerRef.getClientProperty(pName) ).println();
System.out.println("==============");
}
};
spinner.addPropertyChangeListener(BSKEY, pcl);
spinner.addPropertyChangeListener(BNKEY, pcl);
spinner.addPropertyChangeListener(BPKEY, pcl);
final ActionListener spinnerActions = new ActionListener() {
private short oldDir=0;
#Override
public void actionPerformed(ActionEvent e) {
final BasicArrowButton bab = ((BasicArrowButton)e.getSource());
final short swingDir = (short)bab.getDirection();
final short newDir = (swingDir!=SwingConstants.NORTH&&swingDir!=SwingConstants.WEST) ? Integer.valueOf(-1).shortValue() : Integer.valueOf(+1).shortValue();
bab.getParent().firePropertyChange(bab.getName()+KEY_PROP, swingDir*1000, newDir);
bab.getParent().firePropertyChange(bab.getParent().getName()+KEY_PROP, oldDir, newDir);
this.oldDir=newDir;
}
};
buttons.get(BP).addActionListener(spinnerActions);
buttons.get(BN).addActionListener(spinnerActions);

Related

Remove label before I click in java

ı have problem about delete a empty string values like we can see in picture,
in the first time if here is empty he give a error but after that even we write some strings in that blank,its still giving the same error how can ı delete this label before the sending again How can ı fix that problem ı tried some codes but nothing worked well please help about that
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
public class ui {
public static void main(String[] args) {
uiVision();
}
public static void uiVision() {
ImageIcon eyes = new ImageIcon("a.png");
Globals.jf.setTitle("Deneme Uygulamasi");
Globals.jf.setLocation(100,200);
JLabel label1,label2,label3;
Globals.jf.getContentPane().setLayout(new FlowLayout());
JTextField isim = new JTextField(20);
JTextField soyisim = new JTextField(20);
JTextField pasaport = new JTextField(20);
JTextField mail = new JTextField(20);
JPasswordField passwordField = new JPasswordField(10);
JPasswordField passwordField2 = new JPasswordField(10);
JButton buton1 = new JButton("Send");
JButton buton2 = new JButton(eyes);
JButton buton3 = new JButton(eyes);
JButton buton4 = new JButton("!");
label1 = new JLabel("Name:");// -8
label2 = new JLabel("Surname:");// -9
label3 = new JLabel("Passaport-ID:");//+ 10
JLabel label4 = new JLabel("Mail:");// +10
JLabel label5 = new JLabel("Password:");//+10
JLabel label6 = new JLabel("Re-Password:");// +20
buton1.setBounds(170,400,150,30);
buton2.setBounds(320,190,50,30);
buton3.setBounds(320,230,50,30);
buton4.setBounds(370,230,50,30);
isim.setBounds(170,30,150,30);
soyisim.setBounds(170,70,150,30);
pasaport.setBounds(170,110,150,30);
mail.setBounds(170,150,150,30);
passwordField.setBounds(170,190,150,30);
passwordField2.setBounds(170,230,150,30);
label1.setBounds(125,30,150,30);
label2.setBounds(106,70,150,30);
label3.setBounds(90,110,150,30);
label4.setBounds(132,150,150,30);
label5.setBounds(105,190,150,30);
label6.setBounds(91,230,150,30);
Globals.jf.add(buton1);Globals.jf.add(buton2);Globals.jf.add(buton3);
Globals.jf.add(label1);Globals.jf.add(label2);Globals.jf.add(label3);Globals.jf.add(label4); Globals.jf.add(label5);Globals.jf.add(label6);
Globals.jf.add(isim);Globals.jf.add(soyisim);Globals.jf.add(pasaport);Globals.jf.add(mail);Globals.jf.add(passwordField);Globals.jf.add(passwordField2);
Globals.jf.setSize(1000,500);
buton2.addActionListener(l -> {
if ( passwordField.getEchoChar() != '\u0000' ) {
passwordField.setEchoChar('\u0000');
} else {
passwordField.setEchoChar((Character) UIManager.get("PasswordField.echoChar"));
}
});
buton3.addActionListener(l -> {
if ( passwordField2.getEchoChar() != '\u0000' ) {
passwordField2.setEchoChar('\u0000');
} else {
passwordField2.setEchoChar((Character) UIManager.get("PasswordField.echoChar"));
}
});
buton1.addActionListener(e -> {
checkEmpty(isim.getText(),label1.getText(),label1);
checkEmpty(soyisim.getText(),label2.getText(),label2);
checkEmpty(pasaport.getText(),label3.getText(),label3);
checkEmpty(mail.getText(),label4.getText(),label4);
ExitWhenLoopEnd();
Globals.globalInt = 0;
System.out.println(passwordField.getPassword());
System.out.println(passwordField2.getPassword());
Globals.clickCount++;
});
Globals.jf.setLayout(null);
Globals.jf.setVisible(true);
Globals.jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void checkEmpty(String value,String label,JLabel labelname) {
Integer syc = Integer.valueOf(0);
if(value != null && !value.trim().isEmpty()) {
if(Globals.globalInt != 4) {
Globals.globalInt++;
}
syc = 1;
}
else {
CreateEmptyMessageError(label,labelname,Globals.jf);
syc = -1;
}
System.out.println(syc);
}
public static void CreateEmptyMessageError(String labelError,JLabel label,JFrame jf) {
Globals.labelx = new JLabel(labelError.split(":")[0]+" is empty!");
Globals.labelx.setBounds(label.getBounds().x+250,label.getBounds().y,label.getWidth(),label.getHeight());
Globals.labelx.setForeground(Color.RED);
jf.add(Globals.labelx);
jf.revalidate();
jf.repaint();
}
public class Globals {
public static int globalInt = 0;
public static JLabel labelx = null;
public static JFrame jf = new JFrame();
public static int clickCount = 0;
public static int lastVal = 0;
public static int syc = 0;
}
public static void ExitWhenLoopEnd() {
if(Globals.globalInt == 4) {
System.exit(0);
}
}
}
Your problem is that you're creating a new JLabel and adding it to the GUI each time CreateEmptyMessageError(...) is called, and by doing this, you have no reference to this object, and no way to change its state.
The solution is to not do this, to instead create the error message label when you create the GUI itself, assign it to an instance field, and in that method above to not create a new JLabel object but rather to set the text of the existing object, one that shows a warning if the JTextField is empty, and one that sets the JLabel text to the empty String, "", if the JTextField has text.
Also,
As Progman has suggested in comments, avoid the use of static fields and methods unless the use suggests that these should be used, and this isn't the case here. Instead, use private instance fields and methods. This will make your code easier to mock/test/extend and re-use, this reduces potential for hard to identify bugs by reducing your code's cyclomatic complexity and coupling.
Avoid the use of null layouts and setBounds(...) and instead learn and use the layout managers.
Learn and use Java naming conventions. Variable names should all begin with a lower letter while class names with an upper case letter. Learning this and following this will allow us to better understand your code, and would allow you to better understand the code of others.
Give your fields names that describe what they represent, making your code self-commenting and easier to understand.

How to add text and delete text using GUI in Java

I am creating a dumb phone (like old traditional phone) and I'm using GUI programming. I need help with dialing the numbers. I don't know how to get the numbers to pop up on the display and stay there, and also use the delete button to delete the numbers that is up on the display too. I will post a youtube link so you can see a sample run.
I am currently stuck on passing the text from the button of each number that should display the number, however it's displaying the text of the button. I also, don't know how to keep the number there when other buttons are pressed without it being reset.
Here is my code:
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Date;
import javax.swing.*;
public class DumbPhone extends JFrame
{
private static final long serialVersionUID = 1L;
private static final int WIDTH = 300;
private static final int HEIGHT = 500;
private static final String CALL_BUTTON_TEXT = "Call";
private static final String TEXT_BUTTON_TEXT = "Text";
private static final String DELETE_BUTTON_TEXT = "Delete";
private static final String CANCEL_BUTTON_TEXT = "Cancel";
private static final String SEND_BUTTON_TEXT = "Send";
private static final String END_BUTTON_TEXT = "End";
private static final String CALLING_DISPLAY_TEXT = "Calling...";
private static final String TEXT_DISPLAY_TEXT = "Enter text...";
private static final String ENTER_NUMBER_TEXT = "Enter a number...";
private JTextArea display;
private JButton topMiddleButton;
private JButton topLeftButton;
private JButton topRightButton;
private JButton[] numberButtons;
private JButton starButton;
private JButton poundButton;
private boolean isNumberMode = true;
private String lastPressed = "";
private int lastCharacterIndex = 0;
private Date lastPressTime;
public DumbPhone()
{
setTitle("Dumb Phone");
setSize(WIDTH, HEIGHT);
setDefaultCloseOperation(EXIT_ON_CLOSE);
createContents();
setVisible(true);
topLeftButton.setEnabled(false);
}
private void createContents()
{
//create JPanel, and JTextArea display
JPanel panel = new JPanel(new GridLayout(5,3));
display = new JTextArea();
display.setPreferredSize(new Dimension(280, 80));
display.setFont(new Font("Helvetica", Font.PLAIN, 32));
display.setLineWrap(true);
display.setEnabled(false);
panel.add(display);
//create JButtons
topLeftButton = new JButton(DELETE_BUTTON_TEXT);
topMiddleButton = new JButton((CALL_BUTTON_TEXT));
topRightButton = new JButton((TEXT_BUTTON_TEXT));
numberButtons = new JButton[10];
numberButtons[1] = new JButton("<html><center>1<br></center></html>");
numberButtons[2] = new JButton("<html><center>2<br>ABC</center></html>");
numberButtons[3] = new JButton("<html><right>3<br>DEF</right></html>");
numberButtons[4] = new JButton("<html><center>4<br>GHI</center></html>");
numberButtons[5] = new JButton("<html><center>5<br>JKL</center></html>");
numberButtons[6] = new JButton("<html><center>6<br>MNO</center></html>");
numberButtons[7] = new JButton("<html><center>7<br>PQRS</center></html>");
numberButtons[8] = new JButton("<html><center>8<br>TUV</center></html>");
numberButtons[9] = new JButton("<html><center>9<br>WXYZ</center></html>");
numberButtons[0] = new JButton("<html><center>0<br>space</center></html>");
poundButton = new JButton("#");
starButton = new JButton("*");
//add JButtons to buttons JPanel
panel.add(topLeftButton);
panel.add(topMiddleButton);
panel.add(topRightButton);
panel.add(numberButtons[1]);
panel.add(numberButtons[2]);
panel.add(numberButtons[3]);
panel.add(numberButtons[4]);
panel.add(numberButtons[5]);
panel.add(numberButtons[6]);
panel.add(numberButtons[7]);
panel.add(numberButtons[8]);
panel.add(numberButtons[9]);
panel.add(starButton);
panel.add(numberButtons[0]);
panel.add(poundButton);
//add Listener instance (inner class) to buttons
topLeftButton.addActionListener(new Listener());
topMiddleButton.addActionListener(new Listener());
topRightButton.addActionListener(new Listener());
//JButton[] array = new JButton[10];
for (int i = 0; i < numberButtons.length; i++)
{
numberButtons[i].addActionListener(new Listener());
numberButtons[i] = new JButton(String.valueOf(i));
}
starButton.addActionListener(new Listener());
poundButton.addActionListener(new Listener());
//add display and buttons to JFrame
setLayout(new BorderLayout());
add(display, BorderLayout.NORTH);
add(panel, BorderLayout.CENTER);
}
private class Listener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
if(e.getSource() == topLeftButton)
{
if(lastPressTime == null)
{
display.setText(ENTER_NUMBER_TEXT);
}
else
{
topLeftButton.setEnabled(true);
lastCharacterIndex--;
lastPressed = lastPressTime.toString();
}
}
else if(e.getSource() == topMiddleButton)
{
if(lastPressTime == null || lastCharacterIndex == 0)
{
display.setText(ENTER_NUMBER_TEXT);
}
else
{
display.setText(CALLING_DISPLAY_TEXT);
}
}
else if(e.getSource() == topRightButton)
{
if(lastPressTime == null || lastCharacterIndex == 0)
{
display.setText(TEXT_DISPLAY_TEXT);
}
else
{
display.setText(CALLING_DISPLAY_TEXT);
}
}
else
{
topLeftButton.setEnabled(true);
if (e.getSource() instanceof JButton)
{
//String text = ((JButton) e.getSource()).getText();
display.setText(lastPressed + " f" + numberButtons[lastCharacterIndex].getText());
}
}
Date currentPress = new Date();
long currentTime = currentPress.getTime();
if(lastPressTime != null)
{
//long lastPressTime = lastPressTime.getTime();
//subtract lastPressTime from currentPress time to find amount of time elapsed since last button pressed.
}
lastPressTime = currentPress;
String buttonLetters = ""; // Parse Letter from button (e.g "abc").
//update lastCharacterIndex.
lastCharacterIndex++;
lastCharacterIndex = lastCharacterIndex % buttonLetters.length();
}
}
for example, if I push the button 2, instead of giving me "2", it will give me < html>< center>2ABC < / center >< / html >
Therefore, I need help with
Having the numberButtons, when pushed to show the numbers that were pushed.
Be able to delete those numbers.
Here is the link to the sample run: https://www.youtube.com/watch?v=evmGWlMSqqg&feature=youtu.be
Try starting the video 20 seconds in.
to delete the number, you can use the labelname.setText("")
At a basic level, you simply want to maintain the "numbers" separately from the UI. This commonly known as a "model". The model lives independently of the UI and allows the model to be represented in any number of possible ways based on the needs of the application.
In your case, you could use a linked list, array or some other simple sequential based list, but the easiest is probably to use a StringBuilder, as it provides the functionality you require (append and remove) and can make a String very simply.
So, the first thing you need to do is create an instance of model as an instance level field;
private StringBuilder numbers = new StringBuilder(10);
this will allow the buffer to be accessed any where within the instance of the class.
Then you need to update the model...
else
{
topLeftButton.setEnabled(true);
if (e.getSource() instanceof JButton)
{
String text = numberButtons[lastCharacterIndex].getText();
numbers.append(text);
}
}
To remove the last character you can simply use something like...
if (numbers.length() > 0) {
numbers.deleteCharAt(numbers.length() - 1);
}
Then, when you need to, you update the UI using something like...
display.setText(numbers.toString());
Now, this is just basic concepts, you will need to take the ideas and apply it to your code base

How to wait a thread to finish to back to the previous code

I have a question regarding threads. I have a method that reads an Excel spreadsheet and saves the data in a database. However, this method also checks the contents of a cell is an expected value, and if not, a frame must be called for the user to choose the most appropriate option. As it is written the code, it is not waiting for the frame open for the user to choose an option so he returns to the initial loop.
(For the post would not be too long, I have omitted parts of the code, leaving only what matters)
The following parts of the code:
public HashMap<String, Historico> importaDadosDoExcel(){
HashMap<String, Historico> mapa = new HashMap<String, Historico>();
HSSFCell cell= null;
HSSFRow row = null;
Historico update = new Historico();
int rowsCount = 0;
String[] statusStr = {"Aguardando Boleto", "Aguardando Lançamento", "Em Workflow","Liberado para Tesouraria", "Pago", "Outros"};
String aux;
for (int i = 1; i <= rowsCount; i++) {
cell = row.getCell(ActvUtils.u.devolveNumColuna("D"));
aux = ActvUtils.u.devolveCampoLido(cell);
if (Arrays.asList(statusStr).contains(aux)) {
update.setStatus(aux);
}else{
//Here, I would like the frame was called (passing as a parameter the value read in the cell) to which the user then chooses the best option, then, that choice was setted in the object.
Runnable runnable = new EscolheStatus(aux);
Thread thread = new Thread(runnable);
thread.start();
//Here, I would like to read the option that the user chose on a string, some like:
// String str = runnable.getStatus();
}
}
return mapa;
}
And now, my frame class:
public class EscolheStatus extends JFrame implements ActionListener,Runnable{
private String[] statusStr = {"Aguardando Boleto", "Aguardando Lançamento", "Em Workflow","Liberado para Tesouraria", "Pago", "Outros"};
private JRadioButton boleto;
private JRadioButton lancamento;
private JRadioButton workflow;
private JRadioButton tesouraria;
private JRadioButton pago;
private JRadioButton outros;
private String status;
private String statusEncontrado;
public EscolheStatus(String statusEncontrado){
this.statusEncontrado = statusEncontrado;
boleto = new JRadioButton(statusStr[0]);
boleto.addActionListener(this);
lancamento = new JRadioButton(statusStr[1]);
lancamento.addActionListener(this);
workflow = new JRadioButton(statusStr[2]);
workflow.addActionListener(this);
tesouraria = new JRadioButton(statusStr[3]);
tesouraria.addActionListener(this);
pago = new JRadioButton(statusStr[4]);
pago.addActionListener(this);
outros = new JRadioButton(statusStr[5]);
outros.addActionListener(this);
ButtonGroup group = new ButtonGroup();
group.add(boleto);
group.add(lancamento);
group.add(workflow);
group.add(tesouraria);
group.add(pago);
group.add(outros);
JPanel radioPanel = new JPanel();
radioPanel.setLayout(new GridLayout(6, 1));
radioPanel.add(boleto);
radioPanel.add(lancamento);
radioPanel.add(workflow);
radioPanel.add(tesouraria);
radioPanel.add(pago);
radioPanel.add(outros);
radioPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), "Status '" + statusEncontrado + "' não reconhecido. Escolha:" ));
setContentPane(radioPanel);
pack();
this.setSize(350, 200);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLocationRelativeTo(null);
this.setVisible(true);
teste();
}
#Override
public void actionPerformed(ActionEvent ev) {
Object opcao = ev.getSource();
if(opcao.equals(boleto)){
status = statusStr[0];
}else if(opcao.equals(lancamento)){
status = statusStr[1];
}else if(opcao.equals(workflow)){
status = statusStr[2];
}else if(opcao.equals(tesouraria)){
status = statusStr[3];
}else if(opcao.equals(pago)){
status = statusStr[4];
}else if(opcao.equals(outros)){
status = statusStr[5];
}
this.dispose();
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
#Override
public void run() {
new EscolheStatus(statusEncontrado);
}
}
Here's an example of what MasterBlaster suggested (if it's only to stop the thread to require user input):
Thread worker = new Thread(new Runnable() {
#Override
public void run() {
long start = System.currentTimeMillis();
while( (System.currentTimeMillis() - start) < 10000) {
System.out.println( "opening dialog" );
String result = JOptionPane.showInputDialog( "Tell me something!" );
System.out.println("user entered: " + result);
}
System.out.println("finished");
}
});
worker.run();
This will open a dialog and wait for the input again and again until the thread ran for at least 10 seconds.
You should be able to adapt that to your needs.
Of course, if multiple (worker) threads need to communicate you could use Thread.join() to wait for the other thread to finish or wait() and notify() if both threads need to run in parallel and one would just have to finish some task and then continue.
Edit: // String str = runnable.getStatus(); implies you want to get some information about a still running thread. In that case you could use a shared object to write to and read from (you might need some synchronization).

Why will my program not play the next song in the array?

I have been working on this code for a really long time and i just can't seem to figure out my problem. i want to be able to play a list of songs one right after another and i thought i would be able to do that with a simple recursive method that delays the average length of a song, and have it call the next song and play it... However it only plays the very first song and then stops after that and nothing else happens... I have asked countless people to look at this and nobody can help me out.. And no this is not a school project, it is a music player that my mother would like me to use at a party in the next upcoming weekend, so this is like my last ditch effort... Any help with this would be greatly appreciated!!!
private JLabel messageLabel;
private JButton playlist;
private JPanel panel;
BufferedImage image;
AudioStream audioStream1, audioStream2, audioStream3;
//Object[] music = new Object[3];
private final int WINDOW_WIDTH = 800;
private final int WINDOW_HEIGHT = 525;
// File destinationss
private String s1 = "C:\\Users\\Tony\\Desktop\\Java\\NetBeansProjects\\Gui Stuff\\src\\No_Pressure.wav";
private String s2 = "C:\\Users\\Tony\\Desktop\\Java\\NetBeansProjects\\Gui Stuff\\src\\Grateful_Dead_-_Touch_of_Grey.wav";
private String s3 = "C:\\Users\\Tony\\Desktop\\Java\\NetBeansProjects\\Gui Stuff\\src\\Stairway_to_Heaven_Led_Zeppelin_Lyrics.wav";
InputStream in1 = new FileInputStream(s1);
InputStream in2 = new FileInputStream(s2);
InputStream in3 = new FileInputStream(s3);
private ArrayList music;
public JukeBoxWithArrays() throws IOException {
music = new ArrayList();
audioStream1 = new AudioStream(in1);
audioStream2 = new AudioStream(in2);
audioStream3 = new AudioStream(in3);
music.add(audioStream1);
music.add(audioStream2);
music.add(audioStream3);
setTitle("Juke Box Playlist");
setSize(WINDOW_WIDTH, WINDOW_HEIGHT);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
messageLabel = new JLabel("Click the Button to play the playlist");
// Create the Playlist button
playlist = new JButton("Playlist number 1");
// Register the event Listener
playlist.addActionListener(new PlaylistListener());
// Create the panel
panel = new JPanel();
image = ImageIO.read(new File("C:\\Users\\Tony\\Desktop\\Java\\NetBeansProjects\\Gui Stuff\\src\\jukebox2.jpg"));
panel.add(messageLabel);
panel.add(playlist);
panel.add((new JLabel(new ImageIcon(image))));
// Add the panel to the Content Pane
add(panel);
// Display the Window
setVisible(true);
}
private class PlaylistListener implements ActionListener {
int x = 0;
public void actionPerformed(ActionEvent e) {
try {
playMusic(x);
} catch (InterruptedException ex) {
Logger.getLogger(JukeBoxWithArrays.class.getName()).log(Level.SEVERE, null, ex);
}
}
public void playMusic(int x) throws InterruptedException {
if (x > music.size()) {
AudioPlayer.player.stop((InputStream) music.get(x));
} else {
AudioPlayer.player.start((InputStream) music.get(x));
}
Thread.sleep(5 * 60 * 1000); // I believe this is where I am running into my problem
playMusic(x++);
}
}
#SuppressWarnings("restriction")
public static void main(String[] args) throws Exception {
JukeBoxWithArrays jbwa = new JukeBoxWithArrays();
jbwa.pack();
}
}
It seems your code is failing for the same reason this:
private static int x = 0;
public static void main(String[] args) throws ParseException {
int x = 0;
doSomething(x);
doSomething(x);
doSomething(x);
doSomething(x);
doSomething(x);
}
private static void doSomething(int x) {
System.out.println(x++);
}
Outputs this:
0
0
0
0
0
Your Listener has an x field, that your are passing by value between the methods. You should remove the x argument on playMusic(), so everytime it increments x, it would use the object field instead.

Java - Listen to variable change

First of all i am brand new to Java : /
I have been trying to solve this problem on my own for about 2 days now but cant get around it the problem is i am trying to implement a variable change listener. I have tried without successes to implement Observer and Observable to my project but whit no successes at best i came up by wrapping some elements of the code in to while loops but that well fails.
Any how this is my class and if you look at it i have some global variables defined after the constructor i need to listen for a change in all of those global variables if one changes i would like to execute a method.
I have been told JavaFX has methods that can listen to variables can someone confirm this.
Anyhow thanks for help in advance.
public class Tower_Controller {
public Tower_Controller() {
}
//Global variables
String isSelected = null;
int hasModules = 0;
int cap_s = 0;
int cpu_s = 0;
int cap = 0;
int cpu = 0;
int shield = 0;
int armor = 0;
double em = 00.00;
double th = 00.00;
double ki = 00.00;
double ex = 00.00;
public void invoke() {
Invoke_GUI runnable = new Invoke_GUI();
final JLabel tower_name = runnable.tower_name;
final JComboBox tower_select = runnable.tower_select;
final JTree module_browser = runnable.module_browser;
final JTree selected_modules = runnable.selected_modules;
final JProgressBar cap_bar = runnable.cap_bar;
final JProgressBar cpu_bar = runnable.cpu_bar;
final JLabel em_res = runnable.em;
final JLabel th_res = runnable.thermic;
final JLabel ki_res = runnable.kinetic;
final JLabel ex_res = runnable.explosive;
tower_select.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (isSelected != null) {
Events evt = new Events();
evt.towerSelected(isSelected);
} else {
tower_name.setText(tower_select.getSelectedItem().toString());
isSelected = tower_name.toString();
}
}
});
removeTower(tower_name);
runnable.setVisible(true);
}
public void updateValues(final JProgressBar cap_bar, final JProgressBar cpu_bar, final JLabel em_res,
final JLabel th_res, final JLabel ki_res, final JLabel ex_res){
cap_bar.setMaximum(cap);
cap_bar.setString(cap_s + " / " + cap);
cap_bar.setStringPainted(true);
cpu_bar.setMaximum(cpu);
cpu_bar.setString(cpu_s + " / " + cpu);
cpu_bar.setStringPainted(true);
String em_v = String.valueOf(em);
em_res.setText(em_v);
String th_v = String.valueOf(th);
th_res.setText(th_v);
String ki_v = String.valueOf(ki);
ki_res.setText(ki_v);
String ex_v = String.valueOf(ex);
ex_res.setText(ex_v);
}
public void updateList(final ArrayList<String> nodes, final JTree selected_modules) {
DefaultMutableTreeNode nod = new DefaultMutableTreeNode();
for (int i = 0; i < nodes.size(); i++) {
nod.add(new DefaultMutableTreeNode(nodes.get(i)));
}
selected_modules.setModel(new DefaultTreeModel(nod));
}
public void removeTower(final JLabel tower_name) {
tower_name.addMouseListener(new MouseListener() {
#Override
public void mouseClicked(MouseEvent e) {
if (hasModules == 1 & isSelected != null) {
Events evt = new Events();
evt.towerHasModules();
} else if (isSelected == null) {
} else {
tower_name.setText("No Control Tower selected");
isSelected = null;
}
}
#Override
public void mousePressed(MouseEvent e) {
}
#Override
public void mouseReleased(MouseEvent e) {
}
#Override
public void mouseEntered(MouseEvent e) {
}
#Override
public void mouseExited(MouseEvent e) {
}
});
}
public JLabel setTowerName(JLabel a, String name) {
a.setText(name);
return a;
}
}
The general procedure to be notified of a change to a variable is as follows:
First, make the variables private.
Create two methods for each variable, one which sets its value to an argument (often called setX(), where X is the variable name), the other which retrieves its value (getX())
Everywhere you need to read or set the variable, call the methods instead.
In the setX() method, call notifyObserver() on your Observers, in a loop.
And there you go! Now every time the variable is changed, registered Observers are notified. The key part of this solution is that the variables have to be private, so that no code can set their values without going through the setX() methods.

Categories