JCombo Box not updating selected item / Innerclass access - java

I am making a simple calculator in Java, I'm pretty new to Java but I've done a lot of work with languages like it.
The problem is, I need to have the combo box select an item and have it kept up to date, either in a place holder, or in the box itself.
This is the basic class that sets up the frame and everything.
private void initComponents()
{
//TODO:make controls here
//TODO:DONE
JFrame calculator = new JFrame("Steven Seppälä");
calculator.setLayout(new GridLayout(2, 2, 0, 0));
calculator.setSize(400,300);
//"calculator" is the holder for which all the
//items must attach to
calculator.add(new JLabel("Enter the first fraction('1/2')"));
// calculator.add(new JToolBar.Separator(new Dimension(0,10)));
calculator.add(field1);
// calculator.add(new JToolBar.Separator(new Dimension(0,10)));
//TODO: ADD COMBO BOX HERE
String[] operationList = {"+","-","*","/"};
JComboBox operationBox = new JComboBox(operationList);
calculator.add(operationBox);
/*Tried doing the following as well, but it just gave the index 0 consistantly
without changeing, regaurdless of if it did change or not */
// String thing = operationBox.getSelectedItem().toString();
// System.out.println("Selected Operation is: " + thing);
// operationCall = operationBox.getSelectedItem();
operationBox.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
//DEBUGGING
operationBox.getSelectedItem().toString();
}
});
calculator.add(new JLabel("Enter the next fraction('3/4')\n",1));
// calculator.add(new JToolBar.Separator(new Dimension(0,0)));
calculator.add(field2);
// calculator.add(new JToolBar.Separator(new Dimension(0,0)));
JButton Cal = new JButton("Calculate");
calculator.add(Cal);
Cal.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
//DEBUGGING
System.out.println("Finalizing Calculations...");
calculations();
}
});
//sets exit conditions and the visibility of the window
calculator.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
calculator.setVisible(true);
calculator.add(new JLabel(results));
//TODO: add to(?) frame
//TODO:DONE
}
The action listener for the Calculate button works fine, but when I compile as it is now, I get the error message :
FractionFrame.java:53: error: local variable operationBox is accessed from within inner class; needs to be declared final
System.out.println(operationBox.getSelectedItem().toString());
^

In the ActionListener you can access the combo box by using:
JComboBox comboBox = (JComboBox)e.getSource();

Instead of:
JComboBox operationBox = new JComboBox(operationList);
Make it:
final JComboBox operationBox = new JComboBox(operationList);

Related

Have a Button Group in Java where all buttons can be deselected?

I want to have a Button Group in which either only one option is selected or none of them are. At the moment, I can get it to have no options ticked by default, and then if one of them is ticked only one of them can be ticked, but I also want to be able to untick the button that was selected. Is this possible?
EDIT: Ideally without having a clear all button, as it would ruin the symmetry of my GUI. Also, here is my code thus far:
ButtonGroup option = new ButtonGroup();
for(int i = 0; i < n; i++) {
JCheckBox check = new JCheckBox("", false);
option.add(check);
row3b.add(check);
}
Just use the clearSelection() method of ButtonGroup :
ButtonGroup.clearSelection()
Clears the selection such that none of the buttons in the ButtonGroup
are selected.
This snippet demonstrates how you can clear selections using ButtonGroup.clearSelection():
//The buttons
JFrame frame = new JFrame("Button test");
JPanel panel = new JPanel();
JRadioButton btn1 = new JRadioButton("Button1");
JRadioButton btn2 = new JRadioButton("Button2");
JButton clearbutton = new JButton("Clear");
panel.add(btn1);
panel.add(btn2);
panel.add(clearbutton);
frame.add(panel);
frame.setVisible(true);
frame.pack();
//The Group, make sure only one button is selected at a time in the group
ButtonGroup btngroup = new ButtonGroup();
btngroup.add(btn1);
btngroup.add(btn2);
btn1.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
// Do whatever you want here
}
});
btn2.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
// Do whatever you want here
}
});
clearbutton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
// Clear all selections
btngroup.clearSelection();
}
});
As you can see, this creates two JRadioButtons and adds them to group then makes a button that clears selections. Really simple. Or you could create your own radio button class that allows for the unchecking of the button, which is also doable relatively easily.

How to get the values from JPanel components like drop down, text fields which are getting created on a fly

I have a JPanel which consists of a dropdown and a text field inside my JFrame. There is a button in my JFrame, when user clicks on that button, application adds new JPanel with the same components i.e. drop down and a text field. So, for this I have created a function which gets called on clicking on the button using ActionListener.
Everything works fine from GUI side but the problem is when user is done with adding JPanels and entering the values in these drop downs and text fields, it will click on Submit button. Upon clicking on Submit button, I should be able to fetch the values from all drop downs and text fields. This is a challenge, since I am using the same functions to create JPanels, I can't call its name to get the values since that will give me the last JPanel values.
Any suggestion how I should go about this? I have added the screenshot of my JFrame and the function to create the JPanel. Any help is appreciated. Thanks.
public static void AddPanel(final Container pane) {
panel1 = new JPanel();
String text = "<html><b>Property" + nooftimes + " :</b></html>";
JLabel label = new JLabel(text);
label.setPreferredSize(new Dimension(80, 30));
panel1.add(label);
panel1.add(new JLabel("Please enter the property"));
DefaultComboBoxModel<String> model = new DefaultComboBoxModel<String>();
model.addElement("value1");
model.addElement("value2");
model.addElement("value3");
model.addElement("value4");
model.addElement("value5");
final JComboBox<String> comboBox1 = new JComboBox<String>(model);
AutoCompleteDecorator.decorate(comboBox1);
comboBox1.setPreferredSize(new Dimension(120, 22));
panel1.add(comboBox1);
final JTextField txtfield1 = new JTextField(
"Please enter your value here");
txtfield1.setPreferredSize(new Dimension(200, 22));
panel1.add(txtfield1);
txtfield1.addFocusListener(new FocusListener() {
public void focusGained(FocusEvent e) {
txtfield1.setText("");
}
public void focusLost(FocusEvent e) {
// nothing
}
});
container.add(panel1);
nooftimes++;
frame.revalidate();
frame.validate();
frame.repaint();
}
Screenshot:
}
You could return the JPanel and store it in a List<JPanel>. When you click your submit-Button you are able to iterate through the JPanels and its Components.
public class Application {
private static List<JPanel> panels = new ArrayList<>();
private static Container someContainer = new Container();
public static void main(String[] args) {
panels.add(addPanel(someContainer));
panels.add(addPanel(someContainer));
panels.add(addPanel(someContainer));
submit();
}
public static JPanel addPanel(final Container pane) {
JPanel panel1 = new JPanel();
// shortened code
final JComboBox<String> comboBox1 = new JComboBox<String>();
panel1.add(comboBox1);
final JTextField txtfield1 = new JTextField("Please enter your value here");
txtfield1.setText(String.valueOf(Math.random()));
panel1.add(txtfield1);
return panel1;
}
private static void submit() {
for (JPanel panel : panels) {
Component[] components = panel.getComponents();
for (Component comp : components) {
// Cast comp to JComboBox / JTextField to get the values
if (comp instanceof JTextField) {
JTextField textField = (JTextField) comp;
System.out.println(textField.getText());
}
}
}
}
}
You could simply have a class (extending JPanel) with specific methods to add your components , and to get inputs from user (i.e. get the combo box selected index and text from textfield ).
Every time you add a panel, you don't call a static method, but you create an instance of this class, keeping the reference somewhere (for example adding it to an arraylist).
But you could consider a different scenario: personally i don't like to add components "on fly", you could have a component (for example another JComboBox), where user can select the number of values he needs.
You decide a default value (for example 4), so at the beginning you create 4 panels of your class, and you can use a simple array containing them.
If the user changes the number of panels, you could dispose frame and create a new one.
Of course this solution does not woork good if you want to keep inputs inserted, or if the frame construction takes a lot of time.
Here there is a screenshot of a gui i created: user can select the number of partials, when the choice changes i just recreate the panels below,containing the textfields (which are memorized in a two-dimensional array).

JAVA converting pounds to kilo, vice versa. action listener

my program has a calculator layout, theres 9 buttons with clear , negative and convert. and 2 radio buttons that when you select one it converts the numbers you entered.
i have designed it, but im not sure how to do the action listener part.
i think i just need help starting off the code .
// import packages
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
// class
public class Lab31Panel extends JPanel implements ActionListener
{
// data declarations
private JRadioButton k2pButton;
private JRadioButton p2kButton;
private ButtonGroup weight;
private JPanel selectConversion;
private JButton jb0,jb1,jb2,jb3,jb4,jb5,jb6,jb7,jb8,jb9,jbminus,jbclear,jbconvert;
private JTextArea display;
//constructor to initiate data and set up GUI
public Lab31Panel()
{
setLayout( new BorderLayout() );
// organizing radio buttons and their behaviours
k2pButton = new JRadioButton( "Kilograms to Pounds" );
p2kButton = new JRadioButton( "Pounds to Kilograms" );
weight = new ButtonGroup();
weight.add( k2pButton );
weight.add( p2kButton );
// adding components to panel to be south of the GUI
selectConversion = new JPanel();
selectConversion.add( k2pButton );
selectConversion.add( p2kButton );
add( selectConversion, BorderLayout.SOUTH );
//setting up west area of GUI
JPanel westPanel = new JPanel();
JPanel convert = new JPanel();
// setting up components for the west of the GUI
westPanel.setLayout(new GridLayout(5,3));
westPanel.add(jb0 = new JButton("0"));
westPanel.add(jb1 = new JButton("1"));
westPanel.add(jb2 = new JButton("2"));
westPanel.add(jb3 = new JButton("3"));
westPanel.add(jb4 = new JButton("4"));
westPanel.add(jb5 = new JButton("5"));
westPanel.add(jb6 = new JButton("6"));
westPanel.add(jb7 = new JButton("7"));
westPanel.add(jb8 = new JButton("8"));
westPanel.add(jb9 = new JButton("9"));
westPanel.add(jbminus = new JButton("-"));
westPanel.add(jbclear = new JButton("clear"));
westPanel.add(jbconvert = new JButton("convert"));
add(westPanel, BorderLayout.WEST);
//setting up east components
JPanel eastPanel = new JPanel();
eastPanel.setLayout(new BorderLayout());
display = new JTextArea();
eastPanel.add(display,BorderLayout.CENTER);
add(eastPanel);
// add listeners to radio buttons
p2kButton.addActionListener(this);
k2pButton.addActionListener(this);
//add listeners to all textfields
} //end constructor
public void actionPerformed(ActionEvent e)
{
}
} // end class
Suggestions:
First and foremost, don't use the same ActionListener for all the buttons.
In that vein, don't have your program implement ActionListener.
Instead, create one ActionListener for the numeric buttons
And one or perhaps better, three, for the operations buttons.
In the numeric buttons, the code should be clear -- put the numbers into the display.
In the operations button listeners, the actions will depend on which operation was pressed.
If the convert button is pressed, then extract your numeric data from the field holding it,
Convert text to number using a parsing method.
Calculate your conversion
And then display it.
ALSO
I would not add any ActionListener to the JRadioButtons since you really don't want any action to occur when pressed.
Instead have the convert button's ActionListener check to see which JRadioButton is selected, and base the conversion equation on this selection.
Something like:
// add listeners to radio buttons // **** no, don't do this
// p2kButton.addActionListener(this);
// k2pButton.addActionListener(this);
jbclear.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
// TODO code to clear the JTextField
// usually this will involve setText("")
}
});
jbconvert.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
// TODO code to convert
// first get JRadioButton selection -- which one is set
// then get data from text component
// convert it to number (but catching for NumberFormatException)
// do conversion based on the selected JRadioButton
// and display usually with a call to setText(...)
}
});

How can I pass an ArrayList between two separate JTabbedPanes

I have a program utilizing JTabbedPane. On one pane I have a button that updates an arrayList of objects based on input from the same pane.
What I would like to happen is have the second pane update itself with the object information based on the arrayList in the first pane.
However, I am not sure how to pass the list between the panes. Is there some way to push the array to pane #2 when the update button on the first pane is pressed?
Here is the main file. Instantiating the two tabs
public class Assignment6 extends JApplet
{
private int APPLET_WIDTH = 650, APPLET_HEIGHT = 350;
private JTabbedPane tPane;
private StorePanel storePanel;
private PurchasePanel purchasePanel;
private ArrayList computerList;
public void init()
{
computerList = new ArrayList();
storePanel = new StorePanel(computerList, purchasePanel);
purchasePanel = new PurchasePanel(computerList);
tPane = new JTabbedPane();
tPane.addTab("Store Inventory", storePanel);
tPane.addTab("Customer Purchase", purchasePanel);
getContentPane().add(tPane);
setSize (APPLET_WIDTH, APPLET_HEIGHT); //set Applet size
}
}
The first panel instantiates a button listener that applies all of the logic to the array list "compList"
private class ButtonListener implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
//Add Computer to list
Computer comp = new Computer();
comp.setBrandName(brandField.getText());
comp.setPrice(Double.parseDouble(priceField.getText()));
comp.setMemory(Integer.parseInt(memoryField.getText()));
comp.setCPU(typeField.getText(), Integer.parseInt(speedField.getText()));
compList.add(comp);
}
stringField.setText(listString);
alertLabel.setText("Computer Added");
}
}
Here is the other pane. The for loop at the end is what I need to push the arrayList to. After it receives the list, it populates a box with a checkbox for each object in the list
public PurchasePanel(ArrayList compList)
{
west = new JPanel();
east = new JPanel();
totalField = new JTextField();
this.compList = compList;
setLayout(new GridLayout(0,2));
add(west);
add(east);
east.setLayout(new BorderLayout());
east.add(currentTotalLabel, BorderLayout.NORTH);
east.add(totalField, BorderLayout.CENTER);
west.setLayout( new BoxLayout(west, BoxLayout.Y_AXIS));
for(Object c : compList){
System.out.println("Made it");
NumberFormat fmt = NumberFormat.getCurrencyInstance();
String str = ("BrandName:" + (((Computer) c).getBrandName() +"CPU:" + (((Computer) c).getCPU() +"Memory:" + ((Computer) c).getMemory() + "M" +"Price:" + fmt.format(((Computer) c).getPrice()))));
JCheckBox chk = new JCheckBox(str);
west.add(chk);
}
}
}
You can use the same listener used to update the first ArrayList, to update the second pane. Something like:
jButton1.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
// Update the first ArrayList
// Update the second pane
}

ActionListener Anonymous class between two JPanel

I'm trying to get to panels to work with each other RECURSIVELY.
When I'm on the main GUI I have the first JPanel with a Button Add Client,
Once clicked it brings me to the JPanel with a Form and then I recuperate those values,
and send them away in a JTable in the first JPanel the Main GUI.
When I then try to insert a second record. I get a blank GUI. I'm not too sure what I am doing wrong. How can I implement multiple time the same action to repeat ? Which is Load up the form, enter the information, push it on the Table, and the process repeats as much as I need it.
This is the Add Client button declaration in the MAIN GUI
Button btn_AddClient = new Button("Add Client");
btn_AddClient.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
panel.setVisible(false);
contentPane.setVisible(false);
setContentPane(contentPaneClient);
}
});
btn_AddClient.setBounds(259, 12, 70, 22);
contentPane.add(btn_AddClient);
This is the Add Button of the Form in the second Panel
JButton btnAdd = new JButton("Add");
btnAdd.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
setContentPane(contentPaneClient);
panel.setVisible(true);
contentPane.setVisible(true);
contentPaneClient.setVisible(false);
LigneJTab l = new LigneJTab(textFieldPrenomClient.getText(),textFieldNomClient.getText(), textFieldAdresseClient.getText(), chckbxHomme.isSelected(), Sport.FOOTBALL);
myModel.addLine(l);
setContentPane(contentPane);
}
});
btnAdd.setBounds(263, 40, 117, 29);
contentPaneClient.add(btnAdd);
JButton btnAdd = new JButton("Add");
btnAdd.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
//setContentPane(contentPaneClient);
//panel.setVisible(true);
//contentPane.setVisible(true);
//contentPaneClient.setVisible(false);
LigneJTab l = new LigneJTab(textFieldPrenomClient.getText(),textFieldNomClient.getText(), textFieldAdresseClient.getText(), chckbxHomme.isSelected(), Sport.FOOTBALL);
myModel.addLine(l);
panel.setVisible(true);
contentPane.setVisible(true);
setContentPane(contentPane);
}
});
btnAdd.setBounds(263, 40, 117, 29);
contentPaneClient.add(btnAdd);
Commented the top part and added the setContentPane(contentPane); and that worked !
Thanks !
Another idea: You don't need to swap out the content panes to ask for data. A much more elegant way is using a modal dialog box. To make one, first create a dialog class:
public class MyDialog extends JDialog {
public MyDialog(Frame parent) {
super(parent);
setModalityType(Dialog.ModalityType.APPLICATION_MODAL);
// add components to getContentPane()
// to close dialog, use setVisible(false) in listeners
}
public OutputData getData() {
OutputData data = new OutputData();
show();
// show only returns after a setVisible(false)
data.field = textField.getText();
// for example, repeat as many times as necessary
return data;
}
}
To invoke this dialog from the JFrame, use the following code:
MyDialog dialog = new MyDialog(this);
OutputData data = dialog.getData()
// now retrieve fields from data

Categories

Resources