Java Method Call Expected - java

This is a java program with two buttons used to change an integer value and display it.
However in IntelliJIDEA the two lines with
increase.addActionListener(incListener());
decrease.addActionListener(decListener());
keep displaying errors 'Method call expected'.
I am not sure what to do to fix this.
Any help will be greatly appreciated
Thanks
Note: the full code is attached below.
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Main extends JDialog {
public JPanel contentPane;
public JButton decrease;
public JButton increase;
public JLabel label;
public int number;
public Main() {
setContentPane(contentPane);
setModal(true);
increase = new JButton();
decrease = new JButton();
increase.addActionListener(incListener());
decrease.addActionListener(decListener());
number = 50;
label = new JLabel();
}
public class incListener implements ActionListener {
public void actionPerformed (ActionEvent event) {
number++;
label.setText("" + number);
}
}
public class decListener implements ActionListener {
public void actionPerformed (ActionEvent event) {
number--;
label.setText("" + number);
}
}
public static void main(String[] args) {
Main dialog = new Main();
dialog.pack();
dialog.setVisible(true);
System.exit(0);
}
}

incListener and declListener are classes, not methods.
Try
increase.addActionListener(new incListener());
btw, rename your classes names to make them start with an uppercase

It's simple: use new incListener() instead of incListener(). The later is trying to call a method named incListener, the former creates an object from the class incListener, which is what we want.

incListener and decListener are a classes but not a methods, so you must call new to use them, try this:
increase.addActionListener(new incListener());
decrease.addActionListener(new decListener());
sorry for my bad english

substitute the lines with
increase.addActionListener( new incListener());
decrease.addActionListener( new decListener());

Make these changes:
public Main() {
contentPane = new JPanel();
setContentPane(contentPane);
setModal(true);
increase = new JButton("inc");
decrease = new JButton("dec");
contentPane.add(increase);
contentPane.add(decrease);
increase.addActionListener(new incListener());
decrease.addActionListener(new decListener());
number = 50;
label = new JLabel(number+"");
contentPane.add(label);
}

It's sad but I had to Google this same error... I was staring at a method that returned a class. I left off the new operator.
return <class>(<parameters>)
vs
return new <class>(<parameters>)

Whenever a string object is created using new operator a new object is created which is what your program is looking for.
The following link is useful in learning about the difference between a string and a new string.
What is the difference between "text" and new String("text")?

Related

I have a small eror in my code here (swing-java-JFrame)

First I am a beginner in java. I'm making a window with small button and a label (with 0 in default position), when I click on the button the label will change to 1 and when I tap another click the button will be 2. But, I have an error in calling the method.
my code:
package prototype;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class Prototype {
public static int count;
public static JLabel l;
public void Proto()
{
JFrame f = new JFrame();
JButton b = new JButton("click");
JLabel lo = new JLabel("0");
JPanel p = new JPanel();
f.setBounds(120,120,500,500);
b.addActionListener(new MyAction());
p.add(lo);
p.add(b);
f.getContentPane().add(p,BorderLayout.CENTER);
f.show();}
public class MyAction implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
count++;
l.setText(Integer.toString(count));}
public static void main(String[] args) {
//I want to call the proto method but it give me an eror
new proto();
}}}
public class Prototype extends JFrame{
private static int count;
private JLabel l;
public Prototype() {
super();
JButton b = new JButton("click");
l = new JLabel("0");
JPanel p = new JPanel();
b.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
count++;
l.setText(Integer.toString(count));
}
});
p.add(l);
p.add(b);
this.getContentPane().add(p, BorderLayout.CENTER);
this.pack();
this.setVisible(true);
}
public static void main(String...args){
Prototype p=new Prototype();
}
}
I changed the method to a constructor, to have the possibility of creating a object of type Prototype and directly create a frame with it. Also I extended the class with JFrame to not need to create an extra JFrame. Next step was to remove the ActionListener class and creating a new ActionListener while adding it to the button. In my eyes this is useful if you have several buttons with different functionalities, so you can see the function of the button directly just by looking at the code of the button. and the last step was to create a new Object of type Prototype in the main method
If I we're you use a SwingWorker instead of manually setting the text of JLabel. Because this is not a proper way updating your GUI. This should be done using SwingWorker. Please read about publish and processmethod.

When using JPanels in java how can you display user input data in one class to another

I've been having some difficulty with this. Basically I want a user to enter a name in one Java class and have that data displayed in another. I try using gets but I keep getting 'null'. Also how would you do this if I wanted to get an int from my class (exampl) to display in my second class. Would it basically be the same?
Here's an example to show what I mean
1st class
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Exampl extends JFrame implements ActionListener {
JLabel intro = new JLabel("Welcome What is your name?");
JTextField answer = new JTextField(10);
JButton button = new JButton("Enter");
final int WIDTH = 330;
final int HEIGHT = 330;
JLabel greeting = new JLabel("");
JButton next =new JButton("Next");
String name = answer.getText();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Exampl() {
super("Welcome");
setSize(WIDTH, HEIGHT);
setLayout(new FlowLayout());
add(intro);
add(answer);
add(button);
add(greeting);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
button.addActionListener(this);
setVisible(true);
}
public void actionPerformed(ActionEvent event) {
Object source = event.getSource();
if (source == button) {
String greet = "Hello there" + name;
greeting.setText(greet);
add(next);
next.addActionListener(this);
if(source==next)
dispose();
new Hello();
}
}
public static void main(String[] args) {
Exampl frame= new Exampl();
frame.setVisible(true);
}
}
2nd class
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Hello extends JFrame implements ActionListener {
String name;
JLabel hi = new JLabel("Nice to see you "+name);
JButton button = new JButton("Enter");
final int WIDTH = 330;
final int HEIGHT = 330;
JLabel greeting = new JLabel("");
JButton next =new JButton("Next");
public Hello() {
super("Welcome");
setSize(WIDTH, HEIGHT);
setLayout(new FlowLayout());
add(hi);
add(button);
add(greeting);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
button.addActionListener(this);
setVisible(true);
}
public void actionPerformed(ActionEvent event) {
Object source = event.getSource();
if (source == button) {
String greet = "example " + name;
greeting.setText(greet);
add(next);
}
}
public static void main(String[] args) {
Exampl frame= new Exampl();
frame.setVisible(true);
}
}
My recommendations for you:
Don't extend JFrame, instead extend JPanel. See: Extends Frame vs creating it inside the program and Why shouldn't you extend JFrame and other components
Don't use multiple JFrames. See The use of multiple JFrames, good / bad practice? (BAD) instead you might want to try using Card Layout or JDialogs
What do you mean by extend? do you mean "public class Hello extends Exampl"? I'm new to java so I don't know much.
From that comment on another answer, you might want to learn the basics first in console applications before going into a GUI application which adds more complexity to your programs and thus your learning.
I'm planning on doing a project where I add the inputted name and a random int into a file so I can store it. Or would it make more sense to add that code into the same class?
From that comment, you can create a public method which returns the value in a JTextField in the format you need, then call that method from the other class, for example:
public String getUserName() {
return userNameField.getText();
}
public int getDigit() {
try {
return Integer.parseInt(digitField.getText());
} catch (NumberFormatException nfe) {
nfe.printStackTrace();
}
return -1; //In case it's not a number, or return 0, or whatever you need
}
//------In another class------//
int digit = object1.getDigit(); //Where object1 is an instance of the other class where those methods are defined
Make a getter in first class and extends second one class then use super.getter();

Java: Counting clicks on button

I am trying to do something similiar as cookie clicker, nevertheless it does not work. I have not managed to create a "counter" that shows the amount of clicks. This is what I got hitherto, any ideas?
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Stocks implements ActionListener {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Stocks().createGui();
}
});
}
public void createGui() {
JFrame frame = new JFrame("Clicker");
frame.setSize(175, 200);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel(new GridBagLayout());
frame.add(panel);
frame.getContentPane().add(panel, BorderLayout.WEST);
GridBagConstraints c = new GridBagConstraints();
JButton button1 = new JButton("Click this");
c.gridx = 0;
c.gridy = 0;
c.insets = new Insets(40, 40, 40, 40);
panel.add(button1, c);
button1.addActionListener(this);
}
You can have a variable int cnt = 0; inside your Stocks class and everytime someone clicks on the button you increase cnt by one in the actionPerformed method.
As you said, your actionPerformed method is empty, meaning you coded your application to do nothing when the button is clicked.
This answer is assuming you only have one component using that class as ActionListener:
In earlier versions of Java, it would be:
#Override
public void actionPerformed(ActionEvent e) {
counter++;
}
Java 8, however, provides us with Lambda expressions, and allows this to be a lot easier (with less code).
button1.addActionListener(event -> counter++);
You don't need to create an implementation of ActionListener, Java 'll take care of this for you. If you write your code like this, it is even easier if you have more components using that class as ActionListener, since you won't be able to mix them up.
If you need them to call shared parts of code, you can still call methods from within the Lambda expression
button1.addActionListener(event -> {callSharedMethod(); counter++;});
In this example, first the shared method will be called. After that, the counter will be augmented, which will/might only be done from clicking this button.
You should first add a counter as a attribute of your class `Stock``
public class Stocks {
private int counter;
Initialize counter variable with 0:
public static void main(String[] args) {
this.counter = 0;
And then add the action listener to increase the variable:
button1.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
counter++;
}
});
I'm surprised nobody proposed resolving this by inheritance. The button you want is a JButton but slightly more specialized (it must count the number of clicks performed on itself).
public final class CountButton extends JButton {
private int counter = 0;
public CountButton(String text) {
super(text);
addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
counter++;
}
});
}
public final int getCounter() {
return counter;
}
}

Variable sized array of JTextFields and other widgets

public class Creator extends JFrame {
JLabel[] pos;
JTextField[] monInitFi;
JPanel panel, statusP, inputP;
JTextField numMonsFi;
JButton goB, initRollB;
int numMons;
public Creator() {
panel = new JPanel();
createInputP();
panel.add(inputP);
add(panel);
}
//The Input board
public JPanel createInputP() {
inputP = new JPanel();
numMonsFi = new JTextField(3);
inputP.add(numMonsFi);
goB = new JButton("Go");
goB.addActionListener(new goBListener());
inputP.add(goB);
return inputP;
}
//Creates the initiative input board.
public JPanel createStatusP() {
statusP = new JPanel();
monInitFi = new JTextField[numMons];
for (int i = 0; i < numMons; i++) {
monInitFi[i] = new JTextField(3);
statusP.add(monInitFi[i]);
}
initRollB = new JButton("Roll");
statusP.add(initRollB);
return statusP;
}
//The button listener, should update numMons, and create and add the initiative panel.
public class goBListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
numMons = Integer.parseInt(numMonsFi.getText());
createStatusP();
panel.add(statusP);
}
}
public static void main(String[] args) {
Creator c = new Creator();
c.setVisible(true);
c.setSize(1000, 600);
c.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
c.setTitle("D&D 4e Encounter Tracker");
}
}
So this is only a sample of what I'm trying to do, but I cant even get the basics to work. When I run this the statusP(JPanel) does not show up, and I'm not sure if it's because its not running, or because it won't work.
I've tried putting the createStatusP() method in the GUI constructor but only the JButton will appear as if the for loop doesn't run.
Any help would be much appreciated.
In your goBListener's actionPerformed method, you should be calling panel.revalidate() to force the panel to be relaid out which will trigger a repaint, after you have added the statusP panel.
You should also try and follow Java naming conventions, the goBListener should start with an uppercase, GoBListener, it will make it easier for others to read (but will also make it easier for you to read other peoples code)
Instead of arrays, you might consider using some of List, this is a personal thing, but List is generally more flexible. Take a look at Collections for more details
This is because you call createInputP() as it's a procedure , but it's not ! it's a function it will return something that is in this case inputP panel ! so what's actually happening is overridable method call in constructor ! so the solution is add final keyword before createInputP() method !!
// final keyword after public keyword!
public final JPanel createInputP(){ ..... }
And modify goBListener like below :
public class goBListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
numMons = Integer.parseInt(numMonsFi.getText());
panel.revalidate();
panel.add(createStatusP());
}
}
Dang !! That's it !!

Java getter not working?

Ok so i have a comboBox, and a JTextField, whenever i chose the quantity, it would be displayed on the textfield. I have another class, which will retrieve the whatever inside the textfield, but the order class doesn't retrieve the information from catalogue class.
class Catalogue extends JPanel {
String[] h1Quantity = {"0","1","2","3","4","5","6","7","8","9","10"};
h1CBox = new JComboBox <String> (h1Quantity);
h1CBox.setSelectedIndex(0);
h1CBox.addActionListener (new Listener());
h1CBox.setPreferredSize ( new Dimension (50,30));
JLabel noBooks = new JLabel ("Quantity");
booksF = new JTextField(8);
public class Listener implements ActionListener {
public void actionPerformed (ActionEvent event) {
int total = h1CBox.getSelectedIndex();
booksF.setText(Integer.toString(total));
}
}
public String booksFText() {
return booksF.getText();
}
}
class Order extends JPanel {
Catalogue catalogue ;
public Order (Catalogue catalogue)
{
this.catalogue = catalogue;
JPanel panel = new JPanel ();
String text2= catalogue.booksFText();
textArea1 = new JTextArea (text2, 20, 35);
add(textArea1);
add(panel);
}
}
I'm new to java so please keep it simple. thanks alot.
You have 2 constructors in the Order class and catalogue is only set in the first one. Set this in the second contructor as well and the NPE should go away (although hard to know for sure without the stacktrace!)
Always try to post complete code. and stack trace too.
See your order class.
class Order extends JPanel {
public Order (Catalogue catalogue)
{
add(textArea);
}
}
If you use the second constructor , then the class variable catalogue will not be given memory. Thus NULL POINTER EXCEPTION . The code inside the second constructor has been moved to the first one.
The other reason may be that the variable being passed in order constructor is not defined properly. Should be done something like this.
Catalogue catalogue = new Catalogue();
Order order = new Order(catalogue);
See Updated Catalogue class.
class Catalogue extends JPanel {
String[] h1Quantity = {"0","1","2","3","4","5","6","7","8","9","10"};
JComboBox<String> h1CBox ; //Assuming you forgot to define it.
JLabel noBooks ;
JTextField booksF ;
//Define a new constructor
public Catalogue () {
//set jlabel
noBooks = new JLabel ("Quantity");
//set combobox
h1CBox = new JComboBox <String> (h1Quantity);
h1CBox.setSelectedIndex(0);
h1CBox.addActionListener (new Listener());
h1CBox.setPreferredSize ( new Dimension (50,30));
//set textfield
booksF = new JTextField(8);
//add UI items to your panel class
add(h1CBox); //combobox
add(noBooks); // label
add(booksF); // textfield
}
public class Listener implements ActionListener {
public void actionPerformed (ActionEvent event) {
int total = h1CBox.getSelectedIndex();
booksF.setText(Integer.toString(total));
}
}
public String booksFText() {
return booksF.getText();
}
}
Always define your UI like this . Of course , there are better ways . Thus code looks clean and you understand things. Learn to put comments to remind you what you tried to do somewhere.
The MAIN Class
public class Main {
static JTextArea textArea = new JTextArea(40,40);
static class Order extends JPanel{
public Order(){
add(textArea);
}
}
static class Catalogue extends JPanel{
....
private ActionListener listener = new ActionListener(){
public void actionPerformed(ActionEvent event){
textArea.setText(h1CBox.getSelectedIndex()+"");
}
};
}
public static void main(String args[]){
//Construct a frame and add panels and you are good to go.
}
}
One last suggestion, if you plan on NOT changing the data of textarea yourself , use textfield or label instead of textarea. Sometimes the text inside textarea is set , but user is unable to see because of improper bounds . So , to be sure just replace the textarea with label or textfield. Cheers :)

Categories

Resources