Java Swing (issue with ActionListener) - java

I have a take home assignment where I need to make a sudoku board that displays integers from a file on a board and allows someone to click a JButton and input a missing value.
I have gotten the board to show up using JPanel and printed the text file to the individual buttons but I can't figure out how to get the addActionListener to pick up any of the buttons that are missing values. It only works for the last button that is blank. (Blank buttons are given a value of 0).
my question is why is the last blank button only being targeted. There are 6 in total but only the last one brings up the dialogue box after being clicked?
public class MyCustomeFrame extends JFrame {
private int[][] numbers;
private String[] nums;
JButton b1;
JButton b2;
JButton b3;
JButton b4;
private JPanel p2;
public MyCustomeFrame() {
// Create the border layout
setLayout(new BorderLayout(5, 5));
// Create a new panel for the buttons to be placed on
JPanel p1 = new JPanel();
// Create 3 buttons
b1 = new JButton("Load");
b2 = new JButton("Save");
b3 = new JButton("Check");
// Adds the 3 buttons to the panel
p1.add(b1);
p1.add(b2);
p1.add(b3);
// Create the event handlers for when the button is pressed
b1.addActionListener(new MyButtonHandler());
b2.addActionListener(new MyButtonHandler());
b3.addActionListener(new MyButtonHandler());
// Place the panel south in the window
add(p1, BorderLayout.SOUTH);
p2 = new JPanel();
// Define the grid parameters
p2.setLayout(new GridLayout(9, 9, 5, 5));
// Show the grid
add(p2, BorderLayout.CENTER);
int[][] numbers = new int[9][9];
int rowIdx = 0;
//This is where i read the input file located on my computer and place the numbers on the Sudoku board
try {
BufferedReader bReader = new BufferedReader(new FileReader(
"C:\\Users\\Derek\\Desktop\\input.txt"));
String line = bReader.readLine();
while (line != null) {
nums = line.split(",");
for (int i = 0; i < numbers[0].length; i++) {
numbers[rowIdx][i] = Integer.parseInt(nums[i]);
// This creates the individual buttons that are then placed on the board
if (numbers[rowIdx][i] >= 1) {
p2.add(new JButton(nums[i]));
} else {
//this is where I'm having the issue
b4 = new JButton(" ");
p2.add(b4);
b4.addActionListener(new MyButtonHandler());
}
}
rowIdx++;
line = bReader.readLine();
}
bReader.close();
} catch (FileNotFoundException g) {
System.out.println("File Not Found!");
} catch (IOException g) {
System.out.println("Something went wrong...Try Again");
g.printStackTrace();
}
}
class MyButtonHandler implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == b1) {
System.out.println("Loading File...");
} else if (e.getSource() == b2) {
System.out.println("Saving File...");
try {
BufferedWriter bWriter = new BufferedWriter(new FileWriter(
new File("C:\\SudokuSave.txt"), true));
bWriter.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
} else if (e.getSource() == b3) {
System.out.println("Checking Solution...");
} else if (e.getSource() == b4) {
System.out.println("clicked");
JOptionPane.showInputDialog("Input a number between 1 - 9");
}
}
}
}

The reason for the problem was already pointed out by Vyacheslav in https://stackoverflow.com/a/21803753
Some hints:
You should use proper variable names. Calling a JButton b2 is horrible. When it is a "Load" button, then call it loadButton. When it is a "Save" button, call it saveButton. Code is written (at most) once, but read possibly hundreds of times. And Java code should read like prose, in the best case.
Reading a file with a hard-coded name in the constructor, in order to build the GUI components, is a very bad practice. You should consider creating some "Data model" that contains the information that you can create your GUI from, and split the process of
reading the file and store the data in the data model, and
creating the GUI from a data model.
This will also allow you to handle Exceptions better than by printing
System.out.println("Something went wrong...Try Again");
In order to resolve your problem, you might consider using anonymous listeners. Creating a single ActionListener that is responsible for all buttons is not very flexible. Usually, you only want to associate a click on a button with a single call to a (private) method. So for example, you could write
JButton saveButton = new JButton("Save");
saveButton.addActionListener(new ActionListener() {
{
#Override
public void actionPerformed(ActionEvent) {
saveButtonWasPressed();
}
});
Particularly for the case that you have several buttons wit similar functionality, this approach offers an advantage: You can create anonymous listeners for each button, each of them containing the required information about which button was clicked - roughly applied to your code:
if (numbers[rowIdx][i] == 0) {
JButton b = new JButton(" ");
panel.add(b);
b.addActionListener(createActionListener(rowIdx, i));
}
...
private ActionListener createActionListener(
final int row, final int column) {
ActionListener actionListener = new ActionListener() {
{
#Override
public void actionPerformed(ActionEvent) {
System.out.println("Pressed button in row "+row+", column "+column);
}
};
return actionListener;
}

Your mistake is pretty simple - every iteration of for you are assigning a new JButton object reference to b4 variable so finally b4 refers to last JButton you had created.

Related

How do I prompt an image from a user input more than once onto several different JLabels JAVA

Hello guys I'll do my best to explain this because it's very hard to explain. I'm working on project that requires the user to select which animal image they want to appear several different times. But I can only do it the once on the same JLabel (ImageBlock). Here is my code so you understand.
Main class Animals
public static void main(String[] args) {
JFrame application = new JFrame("Animal Project");
GUI graphicalInterface = new GUI();
application.add(graphicalInterface);
application.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
application.setLocation(200, 200);
application.pack();
application.setVisible(true);
application.setResizable(false);
}
Sub class GUI
public class GUI extends JPanel implements ActionListener {
private JButton animalOption = new JButton();
private JPanel buttonPanel;
private JPanel imagePanel;
private ImageIcon bear;
private ImageIcon tiger;
private ImageIcon lion;
private JLabel imageBlock1;
private JLabel imageBlock2;
private JLabel imageBlock3;
GUI() {
Border blackline = BorderFactory.createLineBorder(Color.black);
//create button panel
buttonPanel = new JPanel();
buttonPanel.setPreferredSize(new Dimension(100, 70));
buttonPanel.setOpaque(true);
buttonPanel.setBackground(Color.white);
buttonPanel.setBorder(blackline);
imagePanel = new JPanel(new GridLayout(3, 3));
imagePanel.setPreferredSize(new Dimension(500, 500));
imagePanel.setOpaque(true);
imagePanel.setBackground(Color.white);
imagePanel.setBorder(blackline);
imageBlock1 = new JLabel();
imageBlock1.setPreferredSize(new Dimension(100, 100));
imageBlock1.setOpaque(true);
imageBlock1.setBackground(Color.white);
imageBlock1.setBorder(blackline);
imageBlock2 = new JLabel();
imageBlock2.setPreferredSize(new Dimension(100, 100));
imageBlock2.setOpaque(true);
imageBlock2.setBackground(Color.white);
imageBlock2.setBorder(blackline);
imageBlock3 = new JLabel();
imageBlock3.setPreferredSize(new Dimension(100, 100));
imageBlock3.setOpaque(true);
imageBlock3.setBackground(Color.white);
imageBlock3.setBorder(blackline);
bear = new ImageIcon("Bear.png");
tiger = new ImageIcon("Tiger.png");
lion = new ImageIcon("Lion.png");
animalOption = new JButton();
//add action listener to each button
animalOption.addActionListener(this);
//set button size
animalOption.setPreferredSize(new Dimension(100, 50));
//set text for each button
animalOption.setText("Animal");
animalOption.setToolTipText("press to select your animal");
//add buttons to gui
buttonPanel.add(animalOption);
this.add(buttonPanel);
this.add(imagePanel);
imagePanel.add(imageBlock1);
imagePanel.add(imageBlock2);
imagePanel.add(imageBlock3);
}
public void actionPerformed(ActionEvent e) {
int choice;
if (e.getSource().equals(animalOption)) { //add DVD Button
choice = selectAnimal();
if (choice == 1) {
imageBlock1.setIcon(bear);
} else if (choice == 2) {
imageBlock1.setIcon(tiger);
} else if (choice == 3) {
imageBlock1.setIcon(lion);
}
}
}
static int selectAnimal() {
int animal = 0;
String DVDYears = JOptionPane.showInputDialog("Please enter animal, type 1 for bear, type 2 for tiger, type 3 for lion");
animal = Integer.parseInt(DVDYears);
return animal;
}
}
After I run the code then press the button I am prompted the input dialogue, if I enter "1" for bear, I get this, which is exactly what I want!
]
But after that is the problem, once I click the button again it won't go to the next imageBlock, it will only overwrite the same image where the Bear already is. This is obviously because I haven't put the code in, but I don't know how to do it and I'm struggling on how to move to the next image block.
Would it require Multithreading? I want to expand this project with different animals and more imageBlock JLabels but I'm starting smaller so I can then expand once I know how to progress. Could anyone please help me I've been stuck on this problem for days and I can't work out how to expand on it, I would greatly appreciate any help and tips.
Forget my old post--I misunderstood what you were asking. I think I get it now. I think what you want is just a variable to store what image block to change. Try this:
Put this up at the top of your class with your other instance variables:
private JLabel currImageBlock = null;
And then change your actionPerformed() method to this
public void actionPerformed(ActionEvent e) {
int choice;
if (currImageBlock == null) {
currImageBlock = imageBlock1;
} else if (currImageBlock == imageBlock1) {
currImageBlock = imageBlock2;
} else if (currImageBlock == imageBlock2) {
currImageBlock = imageBlock3;
} else if (currImageBlock == imageBlock3) {
currImageBlock = imageBlock1;
}
if (e.getSource().equals(animalOption)) { //add DVD Button
choice = selectAnimal();
if (choice == 1) {
currImageBlock.setIcon(bear);
} else if (choice == 2) {
currImageBlock.setIcon(tiger);
} else if (choice == 3) {
currImageBlock.setIcon(lion);
}
}
}
This is a little messy and could probably be made a little more elegant, possibly by using an array of JLabel image blocks instead, but it does what you're asking (I think.) It will cycle through putting the image in every image block.

Using Enter key to use JButton instead of just mouse click?

How would one bind the "Enter" key on a keyboard to press a JButton? Currently trying to figure this out but have no idea on what to do.
Here is my code for reference. What it's supposed to do is create a guessing game (which it does) but I want to add the ability to press enter to click the "Enter" button (jButtonEnter in this case).
package day21;
import java.awt.*;
import java.awt.event.*;
//import java.applet.*;
import javax.swing.*;
//import javax.swing.border.*;
public class Day21 extends JApplet implements ActionListener{
/**
*
*/
private static final long serialVersionUID = 1L;
//All important Variables
JTextArea outTextArea = new JTextArea(10,20);
JScrollPane scroller = new JScrollPane(outTextArea);
static int GuessMe = (int) Math.ceil(Math.random()*1000);//randomizes the number
JPanel jPanelTop = new JPanel();
JPanel jPanelMid = new JPanel();
JPanel jPanelLow = new JPanel();
JLabel jLabelTop = new JLabel("Guess a number between 1 and 1000");
static JTextField jTextFieldInput = new JTextField("Guess Here",25);
JButton jButtonEnter = new JButton("Enter");
JButton jButtonReset = new JButton("Reset");
JButton jButtonClose = new JButton("Close");
public void init(){
this.getContentPane().setBackground(Color.white);
this.setSize(new Dimension(400, 120));
//Top Panel
jPanelTop.setBackground(Color.cyan);
jPanelTop.setBorder(BorderFactory.createRaisedBevelBorder());
jPanelTop.setPreferredSize(new Dimension(14, 40));
jPanelTop.setToolTipText("Top Panel");
this.getContentPane().add(jPanelTop, BorderLayout.NORTH);
jPanelTop.add(jLabelTop);
//Middle Panel
jPanelMid.setBackground(Color.orange);
jPanelMid.setBorder(BorderFactory.createRaisedBevelBorder());
jPanelMid.setPreferredSize(new Dimension(14, 40));
jPanelMid.setToolTipText("Center Panel");
this.getContentPane().add(jPanelMid, BorderLayout.CENTER);
jPanelMid.add(jTextFieldInput);
jPanelMid.add(jButtonEnter);
jButtonEnter.addActionListener(this);
//Lower Panel
jPanelLow.setBackground(Color.black);
jPanelLow.setBorder(BorderFactory.createRaisedBevelBorder());
jPanelLow.setPreferredSize(new Dimension(14, 40));
jPanelLow.setToolTipText("Lower Panel");
this.getContentPane().add(jPanelLow, BorderLayout.SOUTH);
jPanelLow.add(jButtonReset);
jPanelLow.add(jButtonClose);
jButtonClose.addActionListener(this);
jButtonReset.addActionListener(this);
}
public void actionPerformed(ActionEvent e){
double input = 0;
boolean Error = false;
String ErrorMSG = "Error: Please Enter a Number";
try{
input = Double.parseDouble(jTextFieldInput.getText().trim());;
}
catch(NumberFormatException n){
Error = true;
}
if(Error){
JOptionPane.showMessageDialog(rootPane, ErrorMSG); //If variable entered is not a number
}
String correctAnswer = "Hooray! You guessed Correctly! \n Press Reset to play again";
String tooHigh = input + " is too high";
String tooLow = input + " is too low";
if(!Error){
if(e.getSource() == jButtonEnter){
if (input == GuessMe){
jPanelLow.setBackground(Color.green);
JOptionPane.showMessageDialog(rootPane, correctAnswer);
}
if (input > GuessMe){
jPanelLow.setBackground(Color.red);
JOptionPane.showMessageDialog(rootPane, tooHigh);
}
if (input < GuessMe){
jPanelLow.setBackground(Color.red);
JOptionPane.showMessageDialog(rootPane, tooLow);
}
}
}
if(e.getSource() == jButtonReset){
Day21.reset(); //runs the reset() method which resets the window back to it's normal state
}
if(e.getSource() == jButtonClose){
System.exit(1); //exits the program
}
}
public static void reset(){
GuessMe = (int) Math.ceil(Math.random()*1000);//randomizes the number
jTextFieldInput.setText("Guess Here");
}
}
Check out Enter Key and Button for a discussion on this topic and a couple of solutions depending on your exact requirement:
use the root pane to set a default button
use the UIManager to have focus follow the button
use Key Bindings to invoke the default Action
Define a method - processEnterButton() and put all the necessary logic there. Call the method from actionPerformed() if the button was clicked. Also define key binding for the ENTER key and call the processEnterButton() from the binding as well.

Comparing/Switching Selected JButtons within a 2D Array

Similar questions to my own have been asked, but I'm at a bit of a loss as to how to proceed. I really have a poor grasp of some of the more subtle nuances of java, so I apologize if anything isn't clear.
Say for example I wanted to compare one JButton within a 2D array with another. To be more specific, all of these JButton's would be stores within a 2D array and displayed in grid format. All of the buttons would have the same action listener that, upon the button being pressed, calls the setselected() method.
How would I go about comparing one of these selected JButton's with another selected JButton within the same array? And upon doing so, how could I swap the positions or more specifically, the icons of said buttons.
Below, I've included some example code and my own attempt on the subject. I understand that I can use .getSource() to grab a JButton object itself, but would this not only allow me to capture 1 selected button at a time. This is all considering the use of the same actionlistner code for each button, but a secular listener for each button.
The code below sets every icon to 1 of 7 randomly generated image icons. A frame is generated within secular main class. Upon being pressed or "selected" the image icons change to a selected iteration of the same image.
EDIT: Based on Ameer's suggestion, I've run into several nullpointer exceptions that are caused by my actionPerformed method. Is this as a result to my button array not being filled with button objects at this point, or am I simply presuming something within my code?
public class SButtonGame extends JFrame implements ActionListener {
public static ImageIcon[] icons={
new ImageIcon("img1.png"),
new ImageIcon("img2.png"),
new ImageIcon("img3.png"),
new ImageIcon("img4.png"),
new ImageIcon("img5.png"),
new ImageIcon("img6.png"),
new ImageIcon("img7.png"),
};
public static ImageIcon[] selectedIcons={
new ImageIcon("simg1.png"),
new ImageIcon("simg2.png"),
new ImageIcon("simg3.png"),
new ImageIcon("simg4.png"),
new ImageIcon("simg5.png"),
new ImageIcon("simg6.png"),
new ImageIcon("simg7.png"),
};
int rowNum=0;
int colNum=0;
JButton[][] Buttons;
boolean swaptf=false;
JButton CButton; // Selected button "holder". Doesn't accomplish anything I think it should
public SButtonGame(String title) {
//Constructs frame
super(title);
getContentPane().setLayout(null)
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(578,634);
int colLoc=10;
int rowLoc=10;
this.colNum=0;
this.rowNum=0;
for(int r=0; r<8; r++)
{
this.Buttons= new JButton[9][9];
this.rowNum++;
for(int c=0; c<8; c++)
{
ActionListener listner = new ActionListener(){
public void actionPerformed(ActionEvent e)
{
if(e.getSource() instanceof JButton)
{
((JButton) e.getSource()).setSelected(true);
CButton=(JButton)e.getSource();
}
}
};
int ranImg;
ranImg=0+(int)(Math.random()*7);
int sranImg=ranImg;
this.Buttons[this.colNum][this.rowNum]= new JButton(icons[ranImg]);
this.Buttons[this.colNum][this.rowNum].setSelectedIcon(selectedIcons[sranImg]);
this.Buttons[this.colNum][this.rowNum].addActionListener(listner);
this.Buttons[this.colNum][this.rowNum].setSize(59,59);
this.Buttons[this.colNum][this.rowNum].setLocation(rowLoc,colLoc);
rowLoc=rowLoc+69;
this.Buttons[this.colNum][this.rowNum].setVisible(true);
this.Buttons[this.colNum] [this.rowNum].setBorder(BorderFactory.createLineBorder(Color.black));
add(this.Buttons[this.colNum][this.rowNum]);
}
this.colNum++;
colLoc=colLoc+69;
rowLoc=10;
}
JButton Newgame;
Newgame= new JButton("NewGame");
Newgame.setSize(100, 30);
Newgame.setLocation(350, 560);
Newgame.setVisible(true);
add(Newgame);
JButton Quit;
Quit= new JButton("Quit");
Quit.setSize(60, 30);
Quit.setLocation(480, 560);
Quit.setVisible(true);
add(Quit);
New.addActionListener(new ActionListener()
{
//dispose of current frame and generates a new one;
public void actionPerformed(ActionEvent e)
{
dispose();
SButtonGame Frame;
Frame = new SButtonGame("ShinyButtons");
Frame.setVisible(true);
}
});
Quit.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
dispose();
}
});
}
#Override
public void actionPerformed(ActionEvent ae){
if(ae.getSource() instanceof JButton){
JButton sButton;
int rindex=0;
int cindex=0;
((JButton) ae.getSource()).setSelected(true);
sButton=(JButton)ae.getSource();
if(SButtonGame.this.Buttons[(int)sButton.getClientProperty("rownum")][(int)sButton.getClientProperty("colnum")].isEnabled()==true){
}
}
}
public static void main(String[] args)
{
SButtonGame Frame;
Frame = new SButtonGame("ButtonsGame");
Frame.setVisible(true);
}
}
Inside actionPerformed(ActionEvent e) method, you can access the 2D array of buttons by using SButtonGame.this.Buttons (ideally variable name should be buttons starting with small b).
You can then compare the clicked button with the buttons from array and do rest of your stuff.

Input Verifier effect not work by click, just work by tab button

I have a delicate problem!
I have a form that set input verifier to text fields, and when user type a incorrect value, other text fields and radio buttons should be disable.
In second text filed (last name), When user type a incorrect value, other components disable perfectly, But when user edit that value to correct it, (for e.x by removing digit), user should user keyboard tab button to enable other components (radio buttons) and I want to enable with clicking to radio buttons too.
Here is my code:
public class UserDialog3 extends JDialog implements ActionListener {
JButton cancelBtn, okBtn;
JTextField fNameTf, lNameTf;
JRadioButton maleRb, femaleRb;
ButtonGroup group;
JLabel fNameLbl, lNameLbl, genderLbl, tempBtn, temp3, temp2, temp1;
public UserDialog3() {
add(createForm(), BorderLayout.CENTER);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
setLocation(400, 100);
pack();
setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new UserDialog3();
}
});
}
public JPanel createForm() {
JPanel panel = new JPanel();
okBtn = new JButton("Ok");
cancelBtn = new JButton("Cancel");
tempBtn = new JLabel();
fNameLbl = new JLabel("First Name");
lNameLbl = new JLabel("Last Name");
genderLbl = new JLabel("Gender");
temp2 = new JLabel();
temp1 = new JLabel();
maleRb = new JRadioButton("Male");
femaleRb = new JRadioButton("Female");
temp3 = new JLabel();
group = new ButtonGroup();
group.add(maleRb);
group.add(femaleRb);
fNameTf = new JTextField(10);
fNameTf.setName("FnTF");
fNameTf.setInputVerifier(new MyVerifier(new JComponent[]{maleRb, femaleRb, okBtn}));
lNameTf = new JTextField(10);
lNameTf.setName("LnTF");
lNameTf.setInputVerifier(new MyVerifier(new JComponent[]{maleRb, femaleRb, okBtn}));
panel.add(fNameLbl);
panel.add(fNameTf);
panel.add(temp1);
panel.add(lNameLbl);
panel.add(lNameTf);
panel.add(temp2);
panel.add(genderLbl);
JPanel radioPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
radioPanel.add(maleRb);
radioPanel.add(femaleRb);
panel.add(radioPanel);
panel.add(temp3);
panel.add(okBtn);
panel.add(cancelBtn);
panel.add(tempBtn);
panel.setLayout(new SpringLayout());
SpringUtilities.makeCompactGrid(panel, 4, 3, 50, 10, 80, 60);
return panel;
}
#Override
public void actionPerformed(ActionEvent e) {
}
public class MyVerifier extends InputVerifier {
private JComponent[] component;
public MyVerifier(JComponent[] components) {
component = components;
}
#Override
public boolean verify(JComponent input) {
String name = input.getName();
if (name.equals("FnTF")) {
String text = ((JTextField) input).getText().trim();
if (text.matches(".*\\d.*") || text.length() == 0) {
//disable dependent components
for (JComponent r : component) {
r.setEnabled(false);
}
return false;
}
} else if (name.equals("LnTF")) {
String text = ((JTextField) input).getText();
if (text.matches(".*\\d.*") || text.length() == 0) {
//disable dependent components
for (JComponent r : component) {
r.setEnabled(false);
}
return false;
}
}
//enable dependent components
for (JComponent r : component) {
r.setEnabled(true);
}
return true;
}
}
}
The purpose of InputVerifier class is to help clients support smooth focus navigation through GUIs with text fields. Before focus is transfered to another Swing component that requests it, the input verifier's shouldYieldFocus method is called(which ask the verify function to validate data). Focus is transfered only if that method returns true.
Please Try to fix the issues about using InutVerifier, verify and shouldYieldFunction as mentioned in your previous post. If you are not going to change your practice, you will be danger in future. Remove you components enabling and disabling code from verify function.
Your Problem in this post: In this case, what really happening is that, when your data is invalid and you try to lose your input text field focus by clicking another component, your JRadioButtons get disabled. A disabled cant be focused until it is re-enabled. As input-verifier responds with focus-lose event, clicking on the disabled RadioButton isn't resulting in focus navigation, and thus ShouldYieldFocus(which calls verify) is not being called to re-enable your components.
Pressing the tab works, because it is sending the Focus to your second text input field according to swing's focus traversal policy. Hence a focus lose event occur on first input text field and this time InputVerifier's verify function get called which eventually enables your component. To understand the problem better, try rewriting your own example with one JRadioButton and one JTextFeild.
Try using a DocumentListener with your text Field. upon data insertion and removal event, check your data validity using InputVerifier and then, enable/disable related components.
I am writing a sample code snippets to demonstrate, how adding DocumentListener to your fNameTF and lNameTF text fields will resolve your problem:
fNameTF.getDocument().addDocumentListener(new DocumentListener() {
#Override
public void insertUpdate(DocumentEvent e) {
doOnDataValidity(verifier.verify(fNameTF));
}
#Override
public void removeUpdate(DocumentEvent e) {
doOnDataValidity(verifier.verify(fNameTF));
}
#Override
public void changedUpdate(DocumentEvent e) {}
});
doOnValidity(boolean isValid) function is as follows:
public void doOnDataValidity(boolean isDataValid)
{
if(isDataValid)
{
//enable your components
}else
{
//disable your components
}
}
Add a DocumentListener to your lNameTf.getDocument() the same way.
Tutorial Resources: How to use DocumentListener.

JCombo Box not updating selected item / Innerclass access

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);

Categories

Resources