So I am trying to write a program using swing components so whenever the user clicks on a button, a different word shows up in the text box. I keep getting an error saying "non static method buttons() cannot be referenced from a static context" I checked other answers on how to fix it with the same error, but I still don't understand it. it appears here:
color.buttons();
And this is my code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class color {
private JFrame f;
private JLabel label;
private JPanel controlPanel;
private JButton button1;
private JButton button2;
private JButton button3;
private JTextField textbox;
public color() {
prepareGUI();
}
public static void main(String args[]) {
color c = new color();
color.buttons();
}
private void prepareGUI() {
f = new JFrame("Colors");
f.setSize(400, 400);
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent windowEvent) {
System.exit(0);
}
});
label = new JLabel("", JLabel.CENTER);
label.setBounds(20, 105, 200, 25);
textbox = new JTextField("", JTextField.CENTER);
textbox.setBounds(20, 75, 125, 50);
f.add(label);
f.add(textbox);
f.setVisible(true);
}
private void buttons() {
label.setText("Click a Button to Reveal Text");
textbox.setText("Which Color?");
JButton button1 = new JButton("Blue");
button1.setBounds(10, 305, 120, 75);
JButton button2 = new JButton("Red");
button2.setBounds(140, 305, 120, 75);
JButton button3 = new JButton("Yellow");
button3.setBounds(270, 305, 120, 75);
button1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
textbox.setText("Blue");
}
});
button2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
textbox.setText("Red");
}
});
button3.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
textbox.setText("Yellow");
}
});
controlPanel.add(button1);
controlPanel.add(button2);
controlPanel.add(button3);
f.setVisible(true);
}
}
You should try c.buttons(); instead of color.buttons();
As non static methods can not be directly referenced, you need an object to do that.
Where as if the method is static then you can use color.buttons();.
The static declaration is used when a field is associated with a class, rather than with any particular object. Now, let's consider your code:
public static void main(String args[]) {
color c = new color();
color.buttons();
}
Of course, the main method has to be static in order to initially run your code. By extension, everything within your static main method must also be static or in other words must be able to run without being directly associated with any object. Therefore, you cannot call color.buttons() since the method is not a static method.
You have two solutions:
Make the method static. Of course, it might not actually make sense to make it static in this case but sometimes in other cases it might be appropriate.
Call the method in the new, instantiated color object, c, as such: c.buttons(); OR call buttons() inside the constructor color().
For clarity, the second solution, in your code, would look like the following:
public color() {
prepareGUI();
buttons();
}
OR
public static void main(String args[]) {
color c = new color();
c.buttons();
}
Calling c.buttons() inside of the static main method is possible since the buttons() method is a method associated with the instantiated object, c.
Finally, some best practices and tips:
You should read the Java Naming Conventions and apply it to your code. For example, your class should be capitalized to be Color instead of color. Following naming conventions makes it easier for other people to read your code because naming conventions are a sort of contract that developers agree on.
You should not call Java Swing methods outside of the Event Dispatch Thread (EDT) as most Swing methods are not thread-safe. Calling Swing methods outside the EDT may result in hard-to-find problems later on.
You can't call a non-static method from a static method in java.
In your case, you are trying to call method buttons() which is a non-static method, where as main method (where you are calling buttons method) is a static method.
Change your main method like this.
public static void main (String args[]){
color c = new color();
c.buttons();
}
In this way you are calling the member function of an object.
Related
public static void main(String[] args) {
ControlledBall ball2 = new ControlledBall(12,2);
JFrame window = new JFrame("Controlled Ball");
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
JButton stop = new JButton("Stop");
stop.setSize(4,400);
stop.setVisible(true);
stop.setText("Stop");
stop.addActionListener(new Action());
i get an error on the last line that says 'controlledball.this cannot be referenced from a static context'
when i try the following technique instead of calling the stop() method i just change the values i need to change:
stop.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
x= 0;
y = 0;
}
});
i get the error non-static field 'x' cannot be referenced from a static context...
the question is, from the main method how can i change the values of x and y which are declared in another method?
There are may ways you can solve this problem. A good suggestion is to probably create a custom ActionListener that holds a reference to the Object you want to change. For example, you could have:
class StopListener implements ActionListener {
private ControlledBall ball;
public StopListener(ControlledBall ball) {
this.ball = ball;
}
#Override
public void actionPerformed(ActionEvent e) {
ball.stop(); // sets x and y to zero
}
}
Then you can just instantiate and use that class as an ActionListener:
stop.addActionListener(new MyListener(ball2));
This should help you organize your code and keep it clean and maintainable.
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.
Basically i have some code to make an interface that allows me to submit a request and it pulls the necessary information from a txt File. For some reason wheni execute my StartUp for the code, sometimes the button isnt there, one text box dominates the screen, all the textboxes overlap... Its weird.
Anyway heres the GUI Code
public class Menu {
SubmitCode submit = new SubmitCode();
public static JFrame frame;
public static JTextField field;
public static Button btn;
public static TextArea txtComm;
public static TextArea txtSites;
public static TextArea txtProg;
public static Dimension dim = new Dimension(40, 10);
public Menu() {
frame = new JFrame();
frame.setTitle("Welcome :)");
frame.pack();
frame.setResizable(false);
frame.setVisible(true);
frame.setLocationRelativeTo(null);
}
public static void open() {
Menu.main(null); // Opens up the main method of the class
}
public static void main(String args[]) {
field = new JTextField();
btn = new Button();
txtComm = new TextArea();
txtSites = new TextArea();
txtProg = new TextArea();
field.setText("What do you want to do?");
field.setSize(390, 20);
field.setLocation(0, 125);
btn.setVisible(true);
btn.setLabel("Click to Submit");
btn.setSize(90, 20);
btn.setLocation(400, 125);
txtComm.setVisible(true);
txtComm.setText("Commands: ");
txtComm.setSize(150, 100);
txtComm.setLocation(10, 10);
txtComm.setEditable(false);
frame.add(txtComm);
txtSites.setVisible(true);
txtSites.setText("Sites: ");
txtSites.setSize(150, 100);
txtSites.setLocation(170, 10);
txtSites.setEditable(false);
frame.add(txtSites);
txtProg.setVisible(true);
txtProg.setText("Programmes: ");
txtProg.setSize(150, 100);
txtProg.setLocation(330, 10);
txtProg.setEditable(false);
frame.add(txtProg);
frame.setSize(500, 175);
frame.add(field, BorderLayout.SOUTH);
frame.add(btn);
btn.addActionListener( new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
System.out.println("Do Something Clicked");
SubmitCode.main(null);
}
});
}
}
Suggestions:
Don't use static methods/fields, except when a specific need arises or for the main method. You do not have the need here.
Instead use valid classes, classes with constructors, instance (non-static) fields and instance methods.
Don't needlessly mix AWT and Swing components but instead use just Swing components. So JTextArea, not TextArea, JButton, not Button, etc....
For instance, your Menu constructor is wasted code that is never called due to your misuse and over-use of statics.
Don't set sizes, use null layouts and absolute positioning such as with setBounds.
Instead read up on and use the layout managers.
Don't pepper your code with useless bits such as most of your calls to setVisible(true).
Call setVisible(true) on the top level window, here your JFrame, after adding all components.
Do read the relevant tutorials as this is all very well explained there. Google Java Swing Tutorials and check the very first hit.
This bit scares me: SubmitCode.main(null); and suggests that you're trying to call the static main method of another class from within a GUI. You should avoid doing this, and instead have your SubmitCode class use good OOP techniques including non-static methods and fields, constructors, etc...
Ok, here is my problem. Class B is a class that build a GUI ,which has a textField and button. class A has an instance of class B.Now I enter some value in the textfield, when I click the button, in class A I want to print out the value I just enter in the textfield, how can I achieve that?
Code below may better explain what I want to achieve:
public class A
{
B myB = new B();
(when the JButton was clicked,
how can I get the new textfield value here?)
}
public class B
{
JLabel myLabel;
JButton myButton;
public B()
{
getContentPane().setLayout(null);
myLabel = new JLabel();
myLabel.setLocation(0,0);
myLabel.setSize(100,30);
myLabel.setBackground( new Color(-6710887) );
myLabel.setText("");
getContentPane().add(myLabel);
myButton = new JButton();
myButton.setLocation(0,50);
myButton.setSize(100,30);
myButton.setBackground( new Color(-16737895) );
myButton.setText("Submit");
getContentPane().add(myButton);
myButton.addActionListener(this);
setSize(400,400);
setVisible(true);
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void actionPerformed(ActionEvent e)
{
(how can I pass this "myLabel.getText()" value to class A when
this action performed?)
}
}
Can anybody help me finish this little program? Thanks in advance!
You need to expose the value in text field with a method in class B. Then class A can call that method. What it actually sounds like though is that class A (or something else) should be a ActionListener for your button.
However, a bigger problem is that you don't have a text field you just have a label in class B. This code is a good reason why you shouldn't use a GUI builder, especially when learning Swing.
Some reading:
http://docs.oracle.com/javase/tutorial/uiswing/components/textfield.html
http://docs.oracle.com/javase/tutorial/uiswing/events/
I often make an "App" class that ties all my GUI-builder-built components together. Any GUI builder worth anything lets you add getters to the generated source code. Add some getters to the GUI-built components to retrieve key elements of the GUI, then let the App class use the getters to interact with the components as necessary. This won't win any MVC/MVVM/MVP design awards, but it gets the job done, which ought to count for something.
public class App {
private B _b;
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
App app = new App();
app.run();
}
});
}
void run() {
_b = new B();
_b.getMainButton().addActionListener(new MainButtonListener());
_b.setVisible(true);
}
private void handleMainButtonClicked() {
String mainText = _b.getMainTextArea().getText();
System.out.println("Button clicked; main text = " + mainText);
}
public class MainButtonListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
handleMainButtonClicked();
}
}
}
public class B extends JFrame {
private JPanel _contentPane;
private JTextArea _jTextArea;
private JButton _jButton;
public B() {
initComponents();
}
private void initComponents() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(400, 400);
_contentPane = new JPanel();
setContentPane(_contentPane);
_jTextArea = new JTextArea();
_contentPane.add(_jTextArea, BorderLayout.CENTER);
_jButton = new JButton("My Button");
_contentPane.add(_jButton, BorderLayout.SOUTH);
}
public JButton getMainButton() {
return _jButton;
}
public JTextComponent getMainTextArea() {
return _jTextArea;
}
}
Basically what I want to do is get a start button to initiate a method running in another class and acting on another object.
My code for the listener:
button1a.addActionListener(new ActionListener() {
public void actionPerformed (ActionEvent event) {
// Figure out how to make this work
//sim.runCastleCrash();
}
} );
My code for the other class:
public static void main(String[] args) {
CastleCrash sim;
sim = new CastleCrash();
}
and
public void runCastleCrash() {
System.out.println("Castle Crash is beginning...");
//Other method parts here to be added
}
I get the feeling this can't be too hard, but I'm missing a piece.
One way to reference things in an anonymous class is using the final keyword:
public static void main(String[] args) {
final Object thingIWantToUse = "Hello";
JButton button = new JButton("Click");
button.addActionListener(new ActionListener() {
#Override public void actionPerformed(ActionEvent e) {
System.out.println(thingIWantToUse);
}
});
JFrame frame = new JFrame();
frame.setLayout(new FlowLayout());
frame.add(button);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
Alternatively, you can access members (variables or methods) of an enclosing type:
public class ActionListenerDemo2 {
private final JFrame frame = new JFrame();
private Object thingIWantToUse = "Hello";
public ActionListenerDemo2() {
JButton button = new JButton("Click");
button.addActionListener(new ActionListener() {
#Override public void actionPerformed(ActionEvent e) {
thingIWantToUse = "Goodbye";
System.out.println(thingIWantToUse);
}
});
frame.setLayout(new FlowLayout());
frame.add(button);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
new ActionListenerDemo2().frame.setVisible(true);
}
}
I've had the same problem like you and this is how i solved it.
You can either make your object final (final CastleCrash sim = new CastleCrash();), but i didn't want to do that, or you can make something like a setter method to run the method in your other class:
My code for the listener class:
button1a.addActionListener(new ActionListener()
{
public void actionPerformed (ActionEvent event)
{
//How to make this work ?
//Like this:
runCC();
}
});
public void runCC()
{
CastleCrash sim = new CastleCrash();
sim.runCastleCrash();
}
My code for the other class:
public void runCastleCrash()
{
System.out.println("Castle Crash is beginning...");
//Other method parts here to be added
}
Hope this is helpful, good luck ! :)
McDowell already answers practically with good examples on how to access variables from event listeners (or anonymous inner classes in general). There is however a more general Sun resource on Event Listeners in Swing that is canonical and a good overview of all the caveats to take into account when writing them.
Somehow you need a reference to your CastleCrash object available to call from your actionListener.
You probably want to subclass JFrame, or whatever is containing your JButton such that it has your both your main method and a CastleCrash property that can then be referenced from your anonymous inner class Actionlistener.
BUT - be careful, you look like you are calling what will be a long running method from within the GUI event thread (where the action listener will called). This is generally a bad idea, you will case your GUI to become unresponsive.
See http://java.sun.com/products/jfc/tsc/articles/threads/threads1.html especially the bit on SwingWorker class for ideas on how to avoid that problem.