Putting user input into a inner panel onto one line

Hi,

I'm trying to find a way to add the JSpinner and JComboBox text into a panel. I've read some tutorials, but I still can't find a way to add my text into a panel.

Here are some of the details:

-when a JSpinner number is selected, it would appear in the blue bordered panel

-when a JComboBox is selected, it would also appear in the blue bordered panel

so it would look something like this inside the blue bordered panel: 1+2

-so when printed it would be like: Spinner, ComboBox, Spinner

Here's a picture of what I mean in the link:

http://img337.imageshack.us/img337/9863/guidesignql2.jpg

Here's my code:

package 620524.labs;

import java.awt.*;

import java.text.NumberFormat;

import javax.swing.*;

import java.awt.event.*;

import javax.swing.event.ChangeListener;

import javax.swing.event.*;

import java.util.Arrays;

publicclass Lab7extends JFrame

{

private JButton calculateButton;

private String patterns;

JLabel display;

publicstaticvoid main(String[] args)

{

Lab7 lab =new Lab7();

lab.create();

lab.setVisible(true);

}

Lab7()

{

super("Simple Calculator");

create();

}

void create()

{

setDefaultCloseOperation(EXIT_ON_CLOSE);

setLocationRelativeTo(null);

setSize(300, 300);

JPanel mainPanel =new JPanel();

mainPanel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));

mainPanel.setLayout(new BorderLayout(4, 4));

add(mainPanel, BorderLayout.NORTH);

GridLayout gridLayout =new GridLayout(0, 1, 4, 4);

JPanel labelPanel =new JPanel();

mainPanel.add(labelPanel, BorderLayout.WEST);

labelPanel.setLayout(gridLayout);

labelPanel.add(new MyLabel("Number 1"));

labelPanel.add(new MyLabel("Operation"));

labelPanel.add(new MyLabel("Number 2"));

labelPanel.add(new JSeparator());

labelPanel.add(new MyLabel("="));

JPanel fieldPanel =new JPanel();

mainPanel.add(fieldPanel, BorderLayout.CENTER);

fieldPanel.setLayout(gridLayout);

//Spinner 1

JSpinner number1 =new JSpinner();

number1.addChangeListener(new ChangeListener()

{

publicvoid stateChanged(ChangeEvent e)

{

JSpinner spinner = (JSpinner)e.getSource();

spinner.getValue();

//System.out.println(spinner.getValue());

}

}

);

fieldPanel.add(number1);

//ComboBox

final String[] operators =new String[]{"+","-","x","/"};

patterns = operators[0];

final JComboBox operation =new JComboBox(operators);

operation.addActionListener(new ActionListener()

{

publicvoid actionPerformed(ActionEvent e)

{

JComboBox cb = (JComboBox)e.getSource();

//Selecting the options

String newSelection = (String)cb.getSelectedItem();

patterns = newSelection;

System.out.println(patterns);

}

}

);

fieldPanel.add(operation);

//Spinner 2

JSpinner number2 =new JSpinner();

number2.addChangeListener(new ChangeListener()

{

publicvoid stateChanged(ChangeEvent e)

{

JSpinner spinner2 = (JSpinner)e.getSource();

spinner2.getValue();

//System.out.println(spinner2.getValue());

}

}

);

fieldPanel.add(number2);

fieldPanel.add(new JSeparator());

JTextField result =new JTextField();

result.setEditable(false);

fieldPanel.add(result);

//Displaying the work space border

JPanel workspace =new JPanel(new GridLayout(0, 1));

add(workspace, BorderLayout.CENTER);

display =new JLabel(" ");

display.setForeground(Color.blue);

display.setBorder(BorderFactory.createCompoundBorder(

BorderFactory.createLineBorder(Color.blue),

BorderFactory.createEmptyBorder(0,0,0,0)

));

workspace.add(display);

//Displaying the work space content

JLabel content =new JLabel();

//Button

JPanel bottomPanel =new JPanel();

add(bottomPanel, BorderLayout.SOUTH);

calculateButton =new JButton("Calculate");

calculateButton.addActionListener(new ActionListener()

{

publicvoid actionPerformed(ActionEvent e)

{

System.out.println("ok");

}

}

);

bottomPanel.add(calculateButton);

}

publicvoid equationDisplay(JSpinner arg0, JComboBox arg1, JSpinner arg2)

{

System.out.println(arg0 +" " + arg1 +" " + arg2);

}

privateclass MyLabelextends JLabel

{

public MyLabel(String text)

{

super(text);

setHorizontalAlignment(SwingConstants.RIGHT);

}

}

}

[8419 byte] By [vopoa] at [2007-11-27 11:59:46]
# 1

You define the spinners and combo box and label as class variables, not local variables. Then in the actionPerformed method of the "Calculate" button you can get the values from the the above objects and then set the text of the label.

There is no need for the ActionListeners or ChangeListener to be added to the above components.

camickra at 2007-7-29 19:27:29 > top of Java-index,Desktop,Core GUI APIs...
# 2

> You define the spinners and combo box and label as

> class variables, not local variables. Then in the

> actionPerformed method of the "Calculate" button you

> can get the values from the the above objects and

> then set the text of the label.

>

Sorry I'm a bit confused about the spinners and combo box and label that they are class variables. I thought they were local variables.

Also for the "Calculate" button, I tried add the ChangeListener code into the Calculate button inner class, but I get a series of exceptions when I click the button.

Can there be a way to access the anonymous classes, because I can't seem to find a way how to do it. Or is it a better solution to use inner member classes?

vopoa at 2007-7-29 19:27:29 > top of Java-index,Desktop,Core GUI APIs...
# 3

> I thought they were local variables

They are local variables. I am suggesting that you make them class variables. When you make them a class variable then any method in the class can access them.

You don't care what the values of the spinners and combo box are until you click on the "Calculate" button. So the only listener you need in your code is the ActionListener. The code in your listener would then be something like:

System.out.println( spinner1.getValue() );

System.out.println( comboBox.setSeletedItem() );

System.out.println( spinner2.getValue() );

You can then save each of the above 3 variables and format them however you want for you output label.

camickra at 2007-7-29 19:27:29 > top of Java-index,Desktop,Core GUI APIs...
# 4

I tried to add the text into the workspace panel, but unfortunately it does work. I get this message in my "Calculate" button anonymous class:

"The method add(Component) in the type Container is not applicable for the arguments (Object)"

Am I missing something in my code for the text to output onto the panel?

Here's my code:

package 620524.labs;

import java.awt.*;

import java.text.NumberFormat;

import javax.swing.*;

import java.awt.event.*;

import javax.swing.event.*;

import java.util.Arrays;

public class Lab7 extends JFrame

{

private JButton calculateButton;

private String patterns;

private JSpinner number1;

private JComboBox operation;

private JSpinner number2;

JLabel display;

public static void main(String[] args)

{

Lab7 lab = new Lab7();

lab.create();

lab.setVisible(true);

}

Lab7()

{

super("Simple Calculator");

create();

}

void create()

{

setDefaultCloseOperation(EXIT_ON_CLOSE);

setLocationRelativeTo(null);

setSize(300, 300);

JPanel mainPanel = new JPanel();

mainPanel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));

mainPanel.setLayout(new BorderLayout(4, 4));

add(mainPanel, BorderLayout.NORTH);

GridLayout gridLayout = new GridLayout(0, 1, 4, 4);

JPanel labelPanel = new JPanel();

mainPanel.add(labelPanel, BorderLayout.WEST);

labelPanel.setLayout(gridLayout);

labelPanel.add(new MyLabel("Number 1"));

labelPanel.add(new MyLabel("Operation"));

labelPanel.add(new MyLabel("Number 2"));

labelPanel.add(new JSeparator());

labelPanel.add(new MyLabel("="));

JPanel fieldPanel = new JPanel();

mainPanel.add(fieldPanel, BorderLayout.CENTER);

fieldPanel.setLayout(gridLayout);

//Spinner 1

number1 = new JSpinner();

fieldPanel.add(number1);

//ComboBox

final String[] operators = new String[]{"+", "-", "x", "/"};

patterns = operators[0];

operation = new JComboBox(operators);

fieldPanel.add(operation);

//Spinner 2

number2 = new JSpinner();

fieldPanel.add(number2);

//Separator

fieldPanel.add(new JSeparator());

//JTextField for final answer - maybe better to use TextArea instead

final JTextField result = new JTextField();

result.setEditable(false);

fieldPanel.add(result);

//Displaying the work space border

final JPanel workspace = new JPanel(new GridLayout(0, 1));

add(workspace, BorderLayout.CENTER);

display = new JLabel(" ");

display.setForeground(Color.blue);

display.setBorder(BorderFactory.createCompoundBorder(

BorderFactory.createLineBorder(Color.blue),

BorderFactory.createEmptyBorder(0,0,0,0)

));

workspace.add(display);

//Displaying the work space content

JLabel content = new JLabel();

//Button

JPanel bottomPanel = new JPanel();

add(bottomPanel, BorderLayout.SOUTH);

calculateButton = new JButton("Calculate");

calculateButton.addActionListener(new ActionListener()

{

public void actionPerformed(ActionEvent e)

{

System.out.print( number1.getValue() );

System.out.print( operation.getSelectedItem() );

System.out.print( number2.getValue() );

System.out.println("\nok");

workspace.add(number1.getValue());

workspace.add(operation.getSelectedItem());

}

}

);

bottomPanel.add(calculateButton);

}

public void equationDisplay(JSpinner arg0, String arg1, JSpinner arg2)

{

System.out.println(arg0 + " " + arg1 + " " + arg2);

}

private class MyLabel extends JLabel

{

public MyLabel(String text)

{

super(text);

setHorizontalAlignment(SwingConstants.RIGHT);

}

}

}

vopoa at 2007-7-29 19:27:29 > top of Java-index,Desktop,Core GUI APIs...
# 5

why would you want to add those things to a jpanel? You can't just add text or any old objects to a jpanel. They have to be swing components. It doesn't make sense. I would think that you would rather want to update your result textField with a calculated result.

petes1234a at 2007-7-29 19:27:29 > top of Java-index,Desktop,Core GUI APIs...
# 6

you probably want to cast your numberX.getValue() as Integer and your operation.getSelection() as String and use these to do your calculations, then display the result in the result JTextField. But that's just my guess.

petes1234a at 2007-7-29 19:27:29 > top of Java-index,Desktop,Core GUI APIs...
# 7

Yes that is what I'm trying to do too.

But I can't find a way to put the text into the JTextField for the calculated result.

I also have to do the same thing, but display the equation in the blue bordered box.

I have updated my code for the "Calculate" button anonymous class:

-I think I have converted the spinner values into integers

//Button

JPanel bottomPanel = new JPanel();

add(bottomPanel, BorderLayout.SOUTH);

calculateButton = new JButton("Calculate");

calculateButton.addActionListener(new ActionListener()

{

public void actionPerformed(ActionEvent e)

{

//converting spinner to integers

int numvalue = ((Number)number1.getValue()).intValue();

int num2value = ((Number)number2.getValue()).intValue();

System.out.print( numvalue);

System.out.print( operation.getSelectedItem() );

System.out.print( num2value );

System.out.println("\nok");

String text = result.getText();

}

}

);

bottomPanel.add(calculateButton);

vopoa at 2007-7-29 19:27:29 > top of Java-index,Desktop,Core GUI APIs...
# 8

I was trying to show you that by using a System.out.println(...) you could print the value of each component.

So the next logical step was to get each value as a String and then concatenate all the value together in the way you want the output formatted and then use label.setText(...) on the formatted String. Basically do what your equationDisplay(...) method does, except you update the text of your display label.

camickra at 2007-7-29 19:27:30 > top of Java-index,Desktop,Core GUI APIs...
# 9

> I was trying to show you that by using a

> System.out.println(...) you could print the value of

> each component.

>

> So the next logical step was to get each value as a

> String and then concatenate all the value together in

> the way you want the output formatted and then use

> label.setText(...) on the formatted String. Basically

> do what your equationDisplay(...) method does, except

> you update the text of your display label.

I'm not sure if I am doing this right so far, can you give me some input on my code.

Here's my code:

//Button

JPanel bottomPanel = new JPanel();

add(bottomPanel, BorderLayout.SOUTH);

calculateButton = new JButton("Calculate");

calculateButton.addActionListener(new ActionListener()

{

public void actionPerformed(ActionEvent e)

{

JLabel label = new JLabel();

//converting spinner to integers

int numvalue = ((Number)number1.getValue()).intValue();

int num2value = ((Number)number2.getValue()).intValue();

String s = new String();

String one = s.valueOf(numvalue);

String two = s.valueOf(operation.getSelectedItem());

String three = s.valueOf(num2value);

label.setText(one + two + three);

workspace.add(label);

System.out.println("\nok");

}

}

);

bottomPanel.add(calculateButton);

vopoa at 2007-7-29 19:27:30 > top of Java-index,Desktop,Core GUI APIs...
# 10

> display = new JLabel(" ");

> display.setForeground(Color.blue);

> display.setBorder(BorderFactory.createCompoundBorder

> (BorderFactory.createLineBorder(Color.blue),

> BorderFactory.createEmptyBorder(0,0,0,0) ));

> workspace.add(display);

You have already created and added a label to your workspace.

You don't add a new label to the workspace. All you need to do is refresh the text of the label with the values from the 3 components (at least thats what I think you are trying to do).

If that doesn't help, then I don't understand your problem.

camickra at 2007-7-29 19:27:30 > top of Java-index,Desktop,Core GUI APIs...
# 11

> > display = new JLabel(" ");

> > display.setForeground(Color.blue);

> >

> display.setBorder(BorderFactory.createCompoundBorder

> > (BorderFactory.createLineBorder(Color.blue),

> > BorderFactory.createEmptyBorder(0,0,0,0) ));

> > workspace.add(display);

> You have already created and added a label to your

> workspace.

>

> You don't add a new label to the workspace. All you

> need to do is refresh the text of the label with the

> values from the 3 components (at least thats what I

> think you are trying to do).

>

> If that doesn't help, then I don't understand your

> problem.

Here's my problem, I'm trying to make the spinner and combobox text to appear in the workspace panel.

-when the program starts, the workspace panel should begin with:0+0

-when one of the spinners or combobox is changed, they should also change too at the same time:1-0

-to calculate the numbers, the user has to click the "calculate" button, then the answer will appear in the textfield

I hope thats specific enough about my problem

vopoa at 2007-7-29 19:27:30 > top of Java-index,Desktop,Core GUI APIs...
# 12

> I hope thats specific enough about my problem

Yes, its clearer.

So you go back to your orignal design where you have listeners on the spinners and the combo box. When an event is fired you get the values from all three components (in a String) formate and update your label with the combined values of all three components. You listener would simple invoke a common routine shared be the listener. Since all the variables are class variable, then can be referenced from any method.

Then when you click the calculate button you get the number values of the spinners and the mathematical operater from the combo box and to your calculation to get the result and then update the result label.

camickra at 2007-7-29 19:27:30 > top of Java-index,Desktop,Core GUI APIs...
# 13

> > I hope thats specific enough about my problem

>

> Yes, its clearer.

>

> So you go back to your orignal design where you have

> listeners on the spinners and the combo box. When an

> event is fired you get the values from all three

> components (in a String) formate and update your

> label with the combined values of all three

> components. You listener would simple invoke a common

> routine shared be the listener. Since all the

> variables are class variable, then can be referenced

> from any method.

How can I combine the different listeners into one from the original?

With the anonymous classes, I can't seem to retrieve the strings from those classes.

Here's my code:

-I have updated the code back to the original design

-I tried to combine the strings together from the listeners, but it doesn't seem that it will grab them.

package 620524.labs;

import java.awt.*;

import java.text.DecimalFormat;

import java.text.NumberFormat;

import javax.swing.*;

import java.awt.event.*;

import javax.swing.event.*;

import java.util.Arrays;

public class Lab7 extends JFrame

{

private JButton calculateButton;

private String patterns;

private JSpinner number1;

private JComboBox operation;

private JSpinner number2;

JLabel display;

public static void main(String[] args)

{

Lab7 lab = new Lab7();

lab.create();

lab.setVisible(true);

}

Lab7()

{

super("Simple Calculator");

create();

}

void create()

{

setDefaultCloseOperation(EXIT_ON_CLOSE);

setLocationRelativeTo(null);

setSize(300, 300);

JPanel mainPanel = new JPanel();

mainPanel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));

mainPanel.setLayout(new BorderLayout(4, 4));

add(mainPanel, BorderLayout.NORTH);

GridLayout gridLayout = new GridLayout(0, 1, 4, 4);

JPanel labelPanel = new JPanel();

mainPanel.add(labelPanel, BorderLayout.WEST);

labelPanel.setLayout(gridLayout);

labelPanel.add(new MyLabel("Number 1"));

labelPanel.add(new MyLabel("Operation"));

labelPanel.add(new MyLabel("Number 2"));

labelPanel.add(new JSeparator());

labelPanel.add(new MyLabel("="));

JPanel fieldPanel = new JPanel();

mainPanel.add(fieldPanel, BorderLayout.CENTER);

fieldPanel.setLayout(gridLayout);

//Spinner 1

number1 = new JSpinner(new SpinnerNumberModel(0,0-100, 0+100, 1));

number1.addChangeListener(new ChangeListener()

{

public void stateChanged(ChangeEvent e)

{

JSpinner spinner = (JSpinner)e.getSource();

int numvalue = ((Number)number1.getValue()).intValue();

String s = new String();

String one = s.valueOf(numvalue);

}

}

);

fieldPanel.add(number1);

//ComboBox

final String[] operators = new String[]{"+", "-", "x", "/"};

patterns = operators[0];

operation = new JComboBox(operators);

operation.addActionListener(new ActionListener()

{

public void actionPerformed(ActionEvent e)

{

JComboBox cb = (JComboBox)e.getSource();

//Selecting the options

String s = new String();

String two = s.valueOf(operation.getSelectedItem());

}

}

);

fieldPanel.add(operation);

//Spinner 2

number2 = new JSpinner();

number2.addChangeListener(new ChangeListener()

{

public void stateChanged(ChangeEvent e)

{

JSpinner spinner2 = (JSpinner)e.getSource();

int num2value = ((Number)number2.getValue()).intValue();

String s = new String();

String three = s.valueOf(num2value);

}

}

);

fieldPanel.add(number2);

//Separator

fieldPanel.add(new JSeparator());

//JTextField for final answer - maybe better to use TextArea instead

final JTextField result = new JTextField();

result.setEditable(false);

fieldPanel.add(result);

//Displaying the work space border

final JPanel workspace = new JPanel(new GridLayout(0, 1));

add(workspace, BorderLayout.CENTER);

display = new JLabel(" ");

display.setForeground(Color.blue);

display.setBorder(BorderFactory.createCompoundBorder(

BorderFactory.createLineBorder(Color.blue),

BorderFactory.createEmptyBorder(0,0,0,0)

));

JLabel la = new JLabel();

la.setText(one + two + three);/*<--*/

workspace.add(display);

//Displaying the work space content

JLabel content = new JLabel();

//Button

JPanel bottomPanel = new JPanel();

add(bottomPanel, BorderLayout.SOUTH);

calculateButton = new JButton("Calculate");

calculateButton.addActionListener(new ActionListener()

{

public void actionPerformed(ActionEvent e)

{

System.out.println("\nok");

}

}

);

bottomPanel.add(calculateButton);

}

public void equationDisplay(JSpinner arg0, String arg1, JSpinner arg2)

{

System.out.println(arg0 + " " + arg1 + " " + arg2);

}

private class MyLabel extends JLabel

{

public MyLabel(String text)

{

super(text);

setHorizontalAlignment(SwingConstants.RIGHT);

}

}

}

vopoa at 2007-7-29 19:27:30 > top of Java-index,Desktop,Core GUI APIs...
# 14

I give up. I said you create a common routine this is invoked from the listeners.

Here is a simple example. It doesn't matter whether your class implements the interface or whether you use an annonymmous inner class. The point is the code in the listener is one line of code so the method can be shared by the ChangeListener and the ActionListener.

import java.awt.*;

import java.awt.event.*;

import javax.swing.*;

import javax.swing.event.*;

public class SpinnerVopo extends JFrame implements ChangeListener

{

JSpinner spinner1;

JSpinner spinner2;

JLabel display;

public SpinnerVopo()

{

spinner1 = new JSpinner(new SpinnerNumberModel(0,0,10,1));

spinner1.addChangeListener( this );

getContentPane().add(spinner1, BorderLayout.WEST);

spinner2 = new JSpinner(new SpinnerNumberModel(0,0,100,10));

spinner2.addChangeListener( this );

getContentPane().add(spinner2, BorderLayout.EAST);

display = new JLabel(" ");

display.setHorizontalAlignment(JLabel.CENTER);

getContentPane().add(display, BorderLayout.SOUTH);

}

public void stateChanged(ChangeEvent e)

{

formatDisplay();

}

private void formatDisplay()

{

display.setText(spinner1.getValue() + " : " + spinner2.getValue());

}

public static void main(String[] args)

{

JFrame frame = new SpinnerVopo();

frame.setDefaultCloseOperation( EXIT_ON_CLOSE );

frame.pack();

frame.setLocationRelativeTo( null );

frame.setVisible( true );

}

}

Now for you calculate button, you still have access to the components but you need to convert the values in the components to numbers so you can use them in your mathematical calculation.

camickra at 2007-7-29 19:27:30 > top of Java-index,Desktop,Core GUI APIs...
# 15

Thanks its very useful, my code finally prints.

vopoa at 2007-7-29 19:27:34 > top of Java-index,Desktop,Core GUI APIs...