Apparently my Google-fu skills are bit lacklustre and I can't figure out how to get JTextField when pressing a JButton.
Please note that I've removed some parts of the code for ease of reading.
If you see some variable that's not defined assume that it was part of that code.
As it stands, the code works fine.
public final class Main {
// Some removed code was here
private void prepareGUI() {
// Top right stuff
JPanel topRightPanel = new JPanel();
topRightPanel.setLayout(new FlowLayout());
JLabel topRightLabel = new JLabel("Address");
JTextField topRightTextField = new JTextField("", 15);
topRightTextField.setName("add_address");
JButton topRightButton = new JButton("Add");
topRightButton.setName("add_btn");
topRightPanel.add(topRightLabel);
topRightPanel.add(topRightTextField);
topRightPanel.add(topRightButton);
mainFrame.add(topRightPanel);
// The button in question. Very suggestive name, I know.
topRightButton.addActionListener(new GenericButtonListener());
genericButtonListener.setKernel(kernel);
// some other non relevant stuff here
mainFrame.setVisible(true);
}
}
public class GenericButtonListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
JButton btn = (JButton) e.getSource();
String btnName = btn.getName();
if(btnName.toLowerCase().contains("add_btn")) {
addBtn(btn);
}
}
public void addBtn(JButton button){
SshFileIO sshFileIO = kernel.getFileIO();
// Get field text here
}
}
My current dilemma is how to get said textfield value inside GenericButtonListener.
I realize that I can use getText to get the text field value, however I don't have access to that variable inside the actionPerformed function.
I suppose this is more of a scoping problem rather than anything else.
I just need some pointing in the right direction, no hand holding required.
It's painfully obvious that I'm very new to Java.
Please try to get a reference of topRightTextField with the constructor of GenericButtonListener. Store as property of the class and use it inside actionPerformed.
Change this one:
topRightButton.addActionListener(new GenericButtonListener());
To this:
topRightButton.addActionListener(new GenericButtonListener(topRightTextField));
And inside class GenericButtonListener add field:
private JTextField topRightTextField;// set it in the constructor
And then use it inside of your method actionPerformed.
Have a nice coding and good luck!
Related
I am currently writing a program which takes an input from a user which is a file, and an integer. Both of these fields are entered into the gui, and then when the user clicks the button I prompt them on screen with, the program should then store the two inputs into variables for later use when it comes to searching the file. The issue is that for swing, there needs to be an
ActionListener which is formatted like this:
0 JButton okButton = new JButton("OK");
1 okButton.addActionListener(new ActionListener() {
2 public void actionPerformed(ActionEvent e) {
3 //(WHERE I'M HAVING THE ISSUE)
4 }
5 });
My issue is that the user's click is registered, and then the code within the actionPerformed function (line 2-3) executes, but since it is in its own function, it cannot save to any variables which are made outside of it (which would be above line 0). It also cannot return any values since actionPerformed's return is supposed be void. Not only this, but you can't fully alter the gui inside of this function, so I cannot write the rest of the code inside of it. Is there any way for me to store the two inputs the user puts into my gui as variables which I can use for the rest of my program? For clarification, this is what I want to happen:
String userInput = null;
JButton okButton = new JButton("OK");
okButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//userInput = (the string the user submitted)
}
});
mainFrame.add(okButton);
mainFrame.setVisible(true);
//(And from here on use the updated user input as I need)
Overall I don't understand how to take information from a user input in my gui and store it for later.
ActionListener is a functional interface which means that, since JDK 8, you can implement it with a method reference.
Declare the GUI components, that the user uses to enter the file and the integer, as class member variables so that you can reference them from the method that implements ActionListener, for example:
public class Gui {
private javax.swing.JTextField fileTextField;
private javax.swing.JSpinner integerSpinner;
private void createAndDisplayGui() {
javax.swing.JButton button = new javax.swing.JButton("Hit me!");
button.addActionListener(this::performAction);
}
// 'ActionListener' implementation.
private void performAction(java.awt.event.ActionEvent event) {
String file = fileTextField.getText();
}
}
The name of the method that implements ActionListener interface can be any name you like. It just has to take the same parameters (as method actionPerformed) and return the same value, i.e. void in the case of method actionPerformed which is the sole method in interface ActionListener. Also note that the method need not be public.
If it were me, I'd use a JPanel and JOptionPane
JPanel p = new JPanel();
JTextField tf = new JTextField(); // For the file name. You can use a JFileChooser also
JTextField tf2 = new JTextField(); // For the number;
p.setLayout(new GridLayout(1,2));
p.add(tf);
p.add(tf2);
int result = JOptionPane.showConfirmDialog(null, p);
String fileName = null;
if (result == JOptionPane.OK_OPTION) {
fileName = tf.getText();
}
I'm making a simple conversion tool to convert dollars to euro's and vice versa.
The whole purpose is just to experiment and learn this cool tool, java.
I have a JLabel at the top with an icon of a euro to indicate the starting currency. I have a button bellow this that I want to use to change that icon to a dollar one.
I am currently plying around with an ActionListener and trying different variations of setIcon/setIconImage (every itteration I can think of seeing that nothing has worked thus far).
public class MoneyConverter extends JFrame implements ActionListener{
//add label and icon showing base conversion currency
JLabel startcur = new JLabel("<--- Starting Curency", new ImageIcon("C:\\Users\\Russel\\Desktop\\1euro.gif"), SwingConstants.CENTER);
JButton euro = new JButton("Swap to Euro");
JButton dollar = new JButton("Swap to Dollar");
I then set up a
public MoneyConverter(){}
method and add all my components to a grid layout and add ActionLister's to my convert buttons.
e.g.
dollar.addActionListener(this);
euro.addActionListener(this);
After the usual code (setVisible and the likes that I will omit for your sake as I don't see it interfering with this, please let me know if I should include it all)
public void ActionPerformed (ActionEvent e){
Object source = e.getSource();
if (source.equals(euro)){
startcur.setIcon(new ImageIcon("C:\\Users\\Russel\\Desktop\\1.gif"));
}
}
This part has been changed many times and is the main reason for this post, how do I change this icon in the JLabel? - I will also be setting the conversion rate in here depending if they choose to start with dollars or euros. (Rate won't be actual rate.)
First, create and store a new ImageIcon
ImageIcon image = new ImageIcon(getClass().getResource("/nameOfImage.jpg"));
Then put this in your Action Listener
label.setIcon(image);
label.setText("");
You have to make sure you have a resource folder set up for your project. You can read how to do that in IntelliJ or Eclipse
You are also declaring the actionPerformed() wrong. I suggest reading up on this You should be doing it like this.
#Override
public void actionPerformed(ActionEvent e)
{
}
Conventionally, in java, method names start with a lower case letter and Classes start with an upper case.
The whole purpose is just to experiment and learn this cool tool, java.
Then I'll show you how to improve this program in a number of ways.
//Don't make your Swing class implement Actionlistener and add it as a
//listener to itself in the constructor before it's fully initialized
public class MoneyConverter extends JFrame {
//These don't have to be loaded at runtime, so make them into constants
//Java variables and methods follow thisNamingConvention
private static final Icon euroIcon = new ImageIcon("C:\\Users\\Russel\\Desktop\\1euro.gif");
private static final Icon dollarIcon = new ImageIcon("C:\\Users\\Russel\\Desktop\\1dollar.gif");
//These you probably want to use later so save them as private class variables
//Make them final so you can access them in the ActionListeners below
private final JLabel currencyLabel;
private final JButton euroButton;
private final JButton dollarButton;
public MoneyConverter() {
//These are declared final and are are therefore usually set first in constructor
this.currencyLabel = new JLabel("<--- Starting Curency", euroIcon, SwingConstants.CENTER);
this.euroButton = new JButton("Swap to Euro");
this.dollarButton = new JButton("Swap to Dollar");
//Write your own separate ActionListener for each button
euroButton.addActionListener(new ActionListener() {
#Override
public void run() {
currencyLabel.setIcon(euroIcon);
//These two are required for you to see the effect
//This should also be the solution to your initial problem
currencyLabel.revalidate();
currencyLabel.repaint();
}
});
dollarButton.addActionListener(new ActionListener() {
#Override
public void run() {
currencyLabel.setIcon(dollarIcon);
currencyLabel.revalidate();
currencyLabel.repaint();
}
});
//Add your components here using whatever layout manager you want.
}
public static void main(String []args){
//Start new Swing applications like this to prevent it from
//clogging the rest of the program
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new MoneyConverter();
}
});
}
}
I have two buttons and in the second one I want to use a variable made in the first button. So Netbeans is generating code of the button. ActionEvent generated by netbeans is
"private void buttonActionPerformed(java.awt.event.ActionEvent evt)"
and I cant change it. I tried to change button to public in button setting. I changed it to public but in code it is still private. I dont know what to do. Anyone know where the problem might be?
Thanks.
What you want to do is, there is a blank line above the private void buttonActionPerformed(ActionEvent evt) you create your variable in that line the example: int a; now the a will turn green. This is called a global variable
JFrame jtfMainFrame;
JButton jbnButton1, jbnButton2;
JTextField jtfInput;
JPanel jplPanel;
//Declaring the string variable setText
String setText;
public JButtonDemo2() {
jtfMainFrame = new JFrame("Which Button Demo");
jtfMainFrame.setSize(50, 50);
jbnButton1 = new JButton("Button 1");
jbnButton2 = new JButton("Button 2");
jtfInput = new JTextField(20);
jplPanel = new JPanel();
jbnButton1.setMnemonic(KeyEvent.VK_I); //Set ShortCut Keys
jbnButton2.setMnemonic(KeyEvent.VK_I);
jbnButton1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//Setting the setText variable
setText = "Do whatever you want";
}
});
jbnButton2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//Displaying the setText variable
jtfInput.setText(setText);
}
});
jplPanel.setLayout(new FlowLayout());
jplPanel.add(jtfInput);
jplPanel.add(jbnButton1);
jplPanel.add(jbnButton2);
jtfMainFrame.getContentPane().add(jplPanel, BorderLayout.CENTER);
jtfMainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jtfMainFrame.pack();
jtfMainFrame.setVisible(true);
}
Simply declare it as a global means when the class definition starts at that time declare the variable which you want to use at the two buttons click and change the value of variable according to your use.
No need to change the ActionPerformed(). All you have to do is declare the variable as a global variable and then do whatever the task inside the button's ActionPerformed().
I do not understand what is happening in my code, when I fire a button with attached action listener, reading the JTextField getText() value shows as null, even though all fields contain text. Furthermore when I debugged the code and stopped just before this line the JTextField object showed as null as well, like it was never initialised in the first place.
I'm not sure whether I can keep all these JLabel and JTextField as class members and then just freely read from them.
public class EditPartGUI extends JFrame {
private JLabel manufacturerLabel;
private JTextField manufacturerTextField;
private JButton submit;
private ActionListener submitListener;
public EditPartGUI(Part part) {
JPanel panel = new JPanel();
this.setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));
panel.add(initialiseField("Manufacturer: ", manufacturerLabel, part.getManufacturer(), manufacturerTextField));
JPanel sub = new JPanel();
submit = new JButton("Submit");
submitListener = new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println(submit().toString());
}
};
submit.addActionListener(submitListener);
sub.add(submit);
panel.add(sub);
this.add(panel);
}
public JPanel initialiseField(String label, JLabel contentLabel, String value, JTextField contentTextField) {
JPanel contentPanel = new JPanel();
contentLabel = new JLabel(label, JLabel.TRAILING);
contentTextField = new JTextField(10);
contentTextField.setText(value);
contentLabel.setLabelFor(contentTextField);
contentPanel.add(contentLabel);
contentPanel.add(contentTextField);
return contentPanel;
}
public Part submit() {
Part p = new Part();
p.setManufacturer(this.manufacturerTextField.getText()); // <---- this is where NullPointerException shows
return p;
}
}
I'm not sure whether I can keep all these JLabel and JTextField as class members and then just freely read from them.
Yes you can and that is the solution to your problem.
Just use the following when you
//private JTextField manufacturerTextField;
private JTextField manufacturerTextField = new JTextField();
and don't try to create the text field in your initialiseField() method. Of course you will need to do the same with the label.
so I could avoid repeating the same code for each field (there are a lot more of them in my actual code).
If you want to have many panels with those fields, then you need to create a custom class to create the panel and then the text fields and labels will be part of that class, not your main class.
The problem is, that you assume that the method initialiseField is assigning the argument contentTextField to manufactererTextField. This won't work in Java as David Wallace already stated.
If you want to avoid repeating the same code, try to create a method that returns the initialised TextField and assign it in the constructor.
I have a button to clear the text fields in the program that I am putting together but when I click it, it doesn't clear them. Here is my code plus the code for the button. I don't know what is wrong this is the way I shown to set up GUI's and this is the way it has always worked for me.
public class GradeCalculator extends JFrame implements ActionListener {
Container c;
JTextField gradeWeight1,gradeWeight2,gradeWeight3,gradeWeight4,gradeWeight5,gradeWeight6,
gradeWeight7,gradeWeight8,gradeWeight9,gradeWeight10;
JTextField gradeAch1,gradeAch2,gradeAch3,gradeAch4,gradeAch5,gradeAch6,gradeAch7,
gradeAch8,gradeAch9,gradeAch10;
JLabel score , weight;
JButton btnGPA, btnClear,btnCalc;
JPanel northP, southP;
public void actionPerformed(ActionEvent e) {
if(e.getSource() == btnClear){
gradeAch1.setText(null);
gradeWeight1.setText(null);
gradeAch2.setText(null);
gradeWeight2.setText(null);
gradeAch3.setText(null);
gradeWeight3.setText(null);
gradeAch4.setText(null);
gradeWeight4.setText(null);
gradeAch5.setText(null);
gradeWeight5.setText(null);
gradeAch6.setText(null);
gradeWeight6.setText(null);
gradeAch7.setText(null);
gradeWeight7.setText(null);
gradeAch8.setText(null);
gradeWeight8.setText(null);
gradeAch9.setText(null);
gradeWeight9.setText(null);
gradeAch10.setText(null);
gradeWeight10.setText(null);
}
}
public GradeCalculator(){
super("Grade Calculator");
c = getContentPane();
c.setLayout(null);
JPanel northP = new JPanel();
northP.setLayout(null);
northP.setBorder(BorderFactory.createTitledBorder("Enter your grades"));
northP.setSize(330,460);
northP.setLocation(2,0);
c.add(northP);
JLabel score = new JLabel("Grade you recieved..");
score.setSize(130,20);
score.setLocation(20,30);
northP.add(score);
JLabel weight = new JLabel("Weight of the grade..");
weight.setSize(140,20);
weight.setLocation(190,30);
northP.add(weight);
JButton btnClear = new JButton("New Calculation");
btnClear.setSize(150,20);
btnClear.setLocation(90,530);
btnClear.addActionListener(this);
btnClear.setMnemonic(KeyEvent.VK_N);
c.add(btnClear);
}
public static void main(String[] args) {
GradeCalculator app = new GradeCalculator();
app.setSize(350,600);
app.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
app.setVisible(true);
}
}
First General Suggestions:
First off, your code is begging you to use arrays or ArrayLists. This will simplify your code greatly and make it much easier to enhance, debug, and fix.
Don't set the text to null but rather to "", the empty String.
Don't set sizes or locations of any components but rather use the layout managers to do this for you.
Now for your problem:
I'm guessing here, because your code does not show us your error, but I suspect that you're calling setText(...) on the wrong references, on JButtons that aren't part of your displayed GUI. Is the listener code in a different class from that of the displayed GUI? Are you misusing inheritance by having the listener code class extend the GUI?
Or does your code have more than one btnClear variable? Are you creating the button with a "shadow" variable, one that is re-declared in a construtor or method while the class field is null?
___________________________________________________________
Please show us more information and code for a more detailed and accurate answer.
Edit
Solution: it's my second point, that you're shadowing your btnClear variable. Don't re-declare it!
e.g.,
public GradeCalculator(){
super("Grade Calculator");
// ... etc...
// **** here ****
JButton btnClear = new JButton("New Calculation");
// .... etc...
}
change to:
public GradeCalculator(){
super("Grade Calculator");
// ... etc...
// **** here ****
btnClear = new JButton("New Calculation");
// .... etc...
}
The reason this is important, by re-declaring the variable in the constructor, you create a new variable that is visible only inside of the constructor. The btnClear field in the class is null since you never initialize it.