How would i be able to run this function from my main() to build the gui, and then use code from elsewhere to handle the button click and retrieve input from the text field?
package main;
import javax.swing.*;
import java.awt.*;
public class Gui {
public static void mainGUI() {
UIManager.put("swing.boldMetal", Boolean.FALSE);
java.net.URL imgApp = ClassLoader.getSystemResource("res/app.png");
JFrame mainWin = new JFrame("jIRC");
mainWin.setSize(1024, 720);
mainWin.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainWin.setIconImage(new ImageIcon(imgApp).getImage());
Container panel = mainWin.getContentPane();
panel.setLayout(null);
JTextArea inputBox = new JTextArea();
inputBox.setSize(300, 100);
inputBox.setLocation(500, 250);
JButton sendButton = new JButton();
sendButton.setText("Send");
sendButton.setFont(new Font("Helvetica", Font.ITALIC, 16));
sendButton.setSize(72, 32);
sendButton.setLocation(500, 500);
panel.add(inputBox);
panel.add(sendButton);
mainWin.setVisible(true);
}
}
Here's my class with the main function:
public class Run{
public static void main(String[] args) {
main.Debug.startupDebug();
main.Gui.mainGUI();
}
}
How would I go about placing some of my code in a non-static field?
You've got everything in a static method, and that won't allow you to use any of the power of object-oriented programming. Consider creating OOP-compliant classes non-static fields and methods and with public getter and setter methods, and this way other classes can affect the behavior of this class.
Edit
You posted:
public class Run{
public static void main(String[] args) {
main.Debug.startupDebug();
main.Gui.mainGUI();
}
}
But what you need to do instead is something like:
public class Run{
public static void main(String[] args) {
GUI gui = new GUI();
Debug debug = new Debug();
debug.setGui(gui);
gui.setDebug(debug);
gui.startGui();
}
}
Or something similar. Again avoid using static anything.
Related
I'm working through the book "Head first Java" and started chapter 12.
When I tried to create the method changeButtonText() I cannot access any of the class methods from button.
Why is this? What have I done wrong in this code?
import javax.swing.*;
public class Main {
public static void main(String[] args) {
JFrame frame = new JFrame();
JButton button = new JButton("Click Me");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(button);
frame.setSize(300,300);
frame.setVisible(true);
}
public void changeButtonText(){
button.setText("I've been clicked");
}
}
The reason you cannot access the variable is because of its scope (tutorial about the scope of variables: https://www.baeldung.com/java-variable-scope).
You declare the variable JButton button in the main method, therefore it is not accessible anywhere outside of it, even in a method that main calls itself.
To make changeButtonText aware that the button variable exists, you have to pass it as parameters of this method:
import javax.swing.*;
public class Main {
public static void main(String[] args) {
JButton button = new JButton("Click Me");
changeButtonText(button);
}
public static void changeButtonText(JButton button){
button.setText("I've been clicked");
}
}
I also added the static keyword in front of the changeButtonText method, because main is also a static method. Check this link for example to have more details about the difference: https://www.geeksforgeeks.org/static-methods-vs-instance-methods-java/
Surely this is a problem of scope and it can be overcome with defining variable at global level and initialize wherever you required. something like -
public class Main {
private static JButton button;
public static void main(String[] args) {
JFrame frame = new JFrame();
button = new JButton("Click Me");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(button);
frame.setSize(300,300);
frame.setVisible(true);
Main.changeButtonText();
}
public static void changeButtonText(){
button.setText("I've been clicked");
}
}
There's a couple of things that is wrong with your code and concepts that you seem to not fully grasp. These concepts are this. and scopes.
public void changeButtonText(){
button.setText("I've been clicked");
}
First we need to talk about scopes. A scope is what's declared between { /* here */ } i.e. two curly brackets. From within a scope you can access and declare both local and global objects, variables, members etc.
So here's an example using local scope (what you did):
public void myFunction(){
JButton button = new Jbutton();
}
If I then go ahead and try to access the button outside of the scope, it wont know what button is. Since it's not declared within that local scope.
public void myFunction(){
JButton button = new Jbutton();
}
public static void main(String[] args) {
button.setText("hello"); //error
// compiler thinks: what's `button` referring to here? its not declared in this scope.
}
Global class scope:
JButton button = new JButton(); //declaring button in global class scope
public void myFunction(){
this.button.setText("hello"); // will access the globally declared variable, object, member called `button`.
//^ notice the usage of `this`.
//`this` will look outside of the local functions scope for publically declared class-members.
}
To fix your particular problem, you could either make your function static and pass in a JButton object, or you could declare your button in the global class scope like this:
public class Main {
JButton button = new JButton("Click Me"); //global class scope
public static void main(String[] args) { //local scope of main start {
Main myClass = new Main(); //instantiate class
myClass.changeButtonText(); //access class-member function
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(this.button); // this.
frame.setSize(300,300);
frame.setVisible(true);
} // local scope of main ends }
public void changeButtonText(){
this.button.setText("I've been clicked"); //access global class members using `this` keyword
}
}
test.java
import javax.swing.JFrame;
public class test {
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setVisible(true);
frame.setSize(600, 600);
}
}
My Other java File test2.java
import javax.swing.JButton;
public class test2 {
public static void main(String[] args) {
JButton Button = new JButton();
frame.add(Button);
}
}
am trying to call frame to test2.java
The reason you are getting this problem:
When you run a java application, the application's main function will be called. Therefore you should really only have one main function per application.
In your scenario you had 2 main functions. Think of this as 2 different applications. The following scenarios were happening:
When you run the Test class, your application was creating a new JFrame object. That's pretty much it, it ended there. It had no idea that the Test2 class existed.
When you run the Test2 class, your application was creating a new JButton object. Although, your Test2 class had no reference to the frame variable (that is why you were getting an error). It didn't even know there was a Test class.
In order to fix this in your situation, try this:
Test.java
public class Test
{
public static void main(String[] args)
{
JFrame frame = new JFrame();
frame.setVisible(true);
frame.setSize(600, 600);
// By passing the frame as a reference, the function
// will be able to add the button to this frame.
Test2.addButton(frame);
}
}
Test2.java
public class Test2
{
public static void addButton(JFrame frame)
{
JButton button = new JButton();
frame.add(button);
}
}
A more OOP approach:
Here, I made a Driver class that would connect the Test2 and MyFrame classes together.
Driver.java
public class Driver
{
public static void main(String[] args)
{
MyFrame frame = new MyFrame();
Test2.addButton(frame);
}
}
MyFrame.java
public class MyFrame extends JFrame
{
public MyFrame()
{
this.setSize(600, 600);
this.setVisible(true);
}
}
Test2.java
public class Test2
{
public static void addButton(JFrame frame)
{
JButton button = new JButton();
frame.add(button);
}
}
I assume you're trying to add Button to the JFrame frame you created in test To do this, you'll need to make frame visible to what is essentially the global scope, as such:
import javax.swing.JFrame;
public class test {
public static JFrame frame;
public static void main(String[] args) {
frame = new JFrame();
frame.setVisible(true);
frame.setSize(600, 600);
test2.main(args)
}
}
and then, to add the button in test2, you need to access test by name
import javax.swing.JButton;
public class test2 {
public static void main(String[] args) {
JButton Button = new JButton();
test.frame.add(Button);
}
}
I have written a Java XML Parser as an Applet. It is looking and functioning well enough in this form.
My Question, Is if I want to run this without a browser, how Would I properly wrap it to run as an executable?
GUI.java
--------------
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class GUI extends JPanel implements ActionListener
{
/**
*
*/
private static final long serialVersionUID = 1L;
private Parser xmlEditor;
private String startTimeValue;
private String endTimeValue;
public GUI(){
init();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
#Override
public void run() {
new GUI();
}
});
}
public void init() {
this.setXmlEditor(new Parser("C:\\Users\\Administrator\\workspace\\XMLParser\\src\\test.xml"));
add(new Label("Start Time"));
startTimeValue = xmlEditor.getStartTimeValue();
endTimeValue = xmlEditor.getEndTimeValue();
startTime = new TextField(startTimeValue);
add(new Label("End Time"));
endTime = new TextField(endTimeValue);
save = new Button("save");
save.addActionListener(this);
add(startTime);
add(endTime);
add(save);
}
public void actionPerformed(ActionEvent e)
{
System.out.println(endTime.getText());
xmlEditor.updateStartTimeValue(startTime.getText());
xmlEditor.updateEndTimeValue(endTime.getText());
System.out.println(e);
System.exit(0);
}
public Parser getXmlEditor() {
return xmlEditor;
}
public void setXmlEditor(Parser xmlEditor) {
this.xmlEditor = xmlEditor;
}
TextField startTime, endTime;
Button save;
}
While trying things with Swing and JFRame etc, I am not getting properly layout, or am opening multiple windows. Can anyone provide assistance? The second Panel Keeps replacing the First. Id like to really try to learn how to place multiple components inside an executable jar is the goal.
SwingPaintDemo.java
import java.awt.Label;
import java.awt.TextField;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.JFrame;
public class SwingPaintDemo {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
private static void createAndShowGUI() {
System.out.println("Created GUI on EDT? "+
SwingUtilities.isEventDispatchThread());
JFrame f = new JFrame("Test");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
Parser myParser = new Parser("C:\\Users\\Administrator\\workspace\\XMLParser\\src\\test.xml");
JPanel top = new JPanel();
top.add(new Label("Start Time"));
TextField startTimeField = new TextField(myParser.getStartTimeValue());
top.add(startTimeField);
f.getContentPane().add(top);
JPanel bottom = new JPanel();
bottom.add(new Label("End Time"));
TextField endTimeField = new TextField(myParser.getEndTimeValue());
bottom.add(endTimeField);
f.getContentPane().add(bottom);
f.pack();
}
}
JFrame uses a BorderLayout by default, where as a JPanel uses a FlowLayout
Instead of rebuilding the UI in the JFrame, simply add an instance of GUI to it, since you've already defined the functionality in a JPanel, this makes it easily reusable.
public class SwingPaintDemo {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
private static void createAndShowGUI() {
System.out.println("Created GUI on EDT? "+
SwingUtilities.isEventDispatchThread());
JFrame f = new JFrame("Test");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().add(new GUI());
f.pack();
f.setVisible(true);
}
}
FYI: You should never reference src in any path element, src won't exist once the program is built and packaged. This is also doubly concerning for applets, as applets run in a tight security model, which prevents them from accessing the file system by default.
Instead, you should be using Class#getResource or Class#getResourceAsStream, depending on your needs.
this.setXmlEditor(new Parser(getClass().getResource("/test.xml")));
for example. You may need to change your Parser to accept either a URL and/or InputStream as well
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.
I'm trying to parse String to another frame Using JAVA
i have 2 jFrames. jFrame1 have 1 text field and jFrame 2 have 1 text field. i want to parse jFrame1 text filed's text to jframe2's text field.
It's look like this : But this is not code :(
jFrame2.textfield1.setText(jFrame1.textfield1.gettext());
Anyone know how to parse String to another frame Using JAVA?
Thanks in advance!
Assuming that you have two separate GUIs on the screen at the same time because both textFields have the same reference, each JFrame will be a Object in its own right.
Therefore the only way to access another objects variables is with its methods.
Create a setter method in jFrame2 to change the textField in question.
See Working code below.
import java.awt.*;
import javax.swing.*;
import javax.swing.BoxLayout;
import java.awt.event.*;
public class JframeLink {
public static void main(String[] args)
{
new JframeOneGui();
new JframeTwoGui();
}
//JFrame one Object
public static class JframeOneGui extends JFrame implements ActionListener
{
JPanel jPanelOne = new JPanel();
JTextField textField1 = new JTextField("Message for transfer");
JButton buttonOne = new JButton("Transfer");
public JframeOneGui()
{
//setup swing components
textField1.setSize(100,10);
buttonOne.addActionListener(this);
//setup jPanelOne
jPanelOne.setLayout(new BoxLayout(jPanelOne, 1));
jPanelOne.add(textField1);
jPanelOne.add(buttonOne);
//setup JframeOneGui
this.add("Center",jPanelOne);
this.setLocation(25,25);
this.setTitle("JframeOneGui");
this.setSize(200,200);
this.setResizable(false);
this.setVisible(true);
}
public void actionPerformed(ActionEvent e)
{
if(e.getSource() == buttonOne)
{
//Here we are calling JframeTwoGui's Setter method
JframeTwoGui.setTextFieldOne(textField1.getText());
}
}
}
//JFrame two Object
public static class JframeTwoGui extends JFrame
{
JPanel jPanelOne = new JPanel();
static JTextField textField1 = new JTextField();
public JframeTwoGui()
{
jPanelOne.setLayout(new BoxLayout(jPanelOne, 1));
jPanelOne.add(textField1);
this.add("Center",jPanelOne);
this.setLocation(300,25);
this.setTitle("JframeTwoGui");
this.setSize(200,200);
this.setResizable(false);
this.setVisible(true);
}
//Setter to change TextFieldOne in this Object
public static void setTextFieldOne(String text)
{
textField1.setText(text);
}
}
}