I want to update JLabel's text when clicking on JButton.
The problem is that they are on different classes.
I minimized my code as much as I can, so this code doesn't contain every code that I actually have.
Below is the 1st Panel's code, which contains a button that will trigger the text updating method.
public class CultureCategorySelectPanel extends JPanel {
public CultureCategorySelectPanel(JFrame mf) {
setVisible(true);
setLayout(null);
setSize(1000, 600);
JButton bookCategoryBtn = new JButton("Book");
// When Clicking on JButton
bookCategoryBtn.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
mf.getContentPane().removeAll();
CultureListPanel myPanel = new CultureListPanel(mf);
mf.getContentPane().add(myPanel);
String text = “This text will be shown”;
myPanel.updateLabel(text);
mf.setVisible(true);
mf.repaint();
}
});
}
}
And the below is the 2nd Panel's code, which has a textLabel that will be updated.
private JLabel plzSelectLabel;
public CultureListPanel(JFrame mf) {
setVisible(true);
setLayout(null);
setSize(1000, 600);
JLabel plzSelectLabel = new JLabel(“This text soon be changed”);
plzSelectLabel.setHorizontalAlignment(SwingConstants.CENTER);
plzSelectLabel.setBounds(138, 89, 367, 34);
rightPanel.add(plzSelectLabel);
// 'rightPanel' is on the top of CultureListPanel, I put plzSelectLabel on the panel called 'rightPanel'
}
public void updateLabel(String text) {
plzSelectLabel.setText(text);
}
When I run, I got Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException at com.kh.mini_Project.view.CultureListPanel.updateLabel(CultureListPanel.java:169) error.
I also tried with getter/setter but it shows the same error.
EDIT
The code below is MainFrame.
import javax.swing.JFrame;
public class MainFrame extends JFrame{
public MainFrame() {
this.setTitle("--");
this.setSize(1000, 600);
this.setLocationRelativeTo(null);
this.setResizable(false);
this.getContentPane().add(new WelcomPage(this));
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
EDIT
The Driver class is here.
public class Run {
public static void main(String[] args) {
new MainFrame();
}
}
Your constructor defines a variable plzSelectLabel which has a local (constructor) scope. Therefor the class level variable (with the same name) will not be initialized hence the NPE.
Hint: read some information about variable scopes ;-)
Related
In trying to read the text that is entered into a textField, I used the actionlistener for a button right next to it. In this actionlistener class, I had an action performed method in which I created a string that was set equal to the textField.getText();. This class however has a problem recognizing textField variable from the previous class.
It is necessary for the .getText() or reading of the textField entry to be in the actionlistener class. I do not know what to try besides the code that I have listed down below.
public class MainClass {
public static void main(String args[]) {
JFrame frame = new JFrame ("Welcome");
frame.setVisible(true);
frame.setSize(500, 200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
frame.add(panel);
JLabel label = new JLabel("...");
panel.add(label);
JTextField text = new JTextField(20);
panel.add(text);
JButton SubmitButton = new JButton("Analyze");
panel.add(SubmitButton);
SubmitButton.addActionListener(new Action1());
}
static class Action1 implements ActionListener {
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
JFrame frame1 = new JFrame("Word Commonality");
frame1.setVisible(true);
frame1.setSize(500,200);
String ReceivedPath = text.getText();
System.out.println(ReceivedPath);
Error is present at second to bottom line of code. The error is "text cannot be resolved"
I expect that the text can be read and printed out in the console.
Your problem is revolved around function scoping to fix it you need a direct access to the JTextField object you can do so by instantiating a new action performed straight in the MainClass like this:
public class Main {
public static void main(String args[]) {
new MainClass();
}
}
Here I created a class only used to instantiate the window class
For the main class I suggest extending JFrame so you can inherit all of it methods.
//Imports
public class MainClass extends JFrame {
private JPanel panel;
private JLabel label;
private JTextField text;
private JButton SubmitButton;
public MainClass(){
super("Welcome");
setSize(500, 200);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
panel = new JPanel();
add(panel);
label = new JLabel("...");
panel.add(label);
text = new JTextField(20);
panel.add(text);
SubmitButton = new JButton("Analyze");
panel.add(SubmitButton);
SubmitButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String ReceivedPath = text.getText();
System.out.println(ReceivedPath);
}
});
setVisible(true);
}
}
This is how your class should look like.
Side notes:
Set visible is at the end otherwise the items will not be see able.
The MainClass is inheriting from JFrame so it can use all its methods without instatiating it look at inheritance(https://www.w3schools.com/java/java_inheritance.asp)
The action performed now can acces the text JTextField because it is a class attribute.
If the solution is correct please think of marking this answer as final. Thank you
If you place the getText() outside the ActionListener, it will be read immediately after creating the panel. That is why it is empty. You can make the ActionListener assign a value to a variable, but it will be empty until the action is performed.
Also see here: Swing GUI doesn't wait for user input
Ok so I have 2 jPanels.
one of them has a number of buttons that when pressed should add text to the the textfield that is in the second jPanel.
I am brand spanking new to swing with previously only having to write back end code and web based code so I am having difficulty seeing how you would accomplish this.
I only have buttons created in one panel and a textfield in another so i suspect code would be irrelevant.
Any articles that someone could point me to or examples are greatly appreciated.
So I had this problem ones,
So Lets say you have two JFrame JFrame1 and JFrame2
In order to communicate with each other at runtime both has to have most recent initialized object of each individual frame.
Now lets say this is your first frame where is your textbox,
public class JFrame1 extends JFrame{
JTextField jTextField= null;
public JFrame1() throws HeadlessException {
super("JFrame");
setSize(200, 200);
jTextField = new JTextField();
add(jTextField);
setVisible(true);
}
public void setValueToText(String value){
jTextField.setText(value);
}
}
Then This is second and where is your Button,
public class JFrame2 extends JFrame{
JButton jButton= null;
JFrame1 frame1=null;
public JFrame2() throws HeadlessException {
super("JFrame");
frame1=new JFrame1();
jButton = new JButton("Clieck Me");
add(jButton);
setVisible(true);
jButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
frame1.setValueToText("Hi");
}
});
setVisible(true);
}
public static void main(String[] args) {
JFrame2 jf= new JFrame2();
jf.setSize(200, 200);
}
}
Now Just run second class file and click one button which will set hi on your textbox which is in second frame.
So As you see answer lay's in Initialized second object in frame.
My execution is like,
Run JFrame2
Initialized JFrame1 in JFame2 const.
you can make the JTextField an instance variable of the enclosing JFrame and make the two panels inner classes of it. By this, the two panels will have a reference to the same field which belongs to the outer class.
So, you will end up having something similar to:
public class Outer extends JFrame{
private JTextField text = new JTextField();
...
public Outer(){
this.add(new Inner1(), BorderLayout.NORTH);
this.add(new Inner2(), BorderLayout.SOUTH);
}
class Inner1 extends JPanel{
...
public Inner1(){
this.add(text);
}
}
class Inner2 extends JPanel implements ActionListener{
private JButton button = new JButton();
public Inner2(){
button.addActionListener(this);
}
public void actionPerformed(ActionEvent e){
if (e.getSource() == button)
text.setText("Hello StackOverFlow");
}
}
}
add your code to change the text in another panel, when a button clicked in the first panel.
mybutton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
//do your logic to change the text in another panel
}
});
I am new to swing, can anyone help me out with this...
It is not showing my "label" , instead it shows me only components which are in the "panel" class.
One more question, can anyone clarify me about LayoutManagers ?
Can 2 or more LayoutManagers be used in a frame ? like for the frame i will be using FlowLayout and i have a JPanel added to the frame for which i will be using BoxLayout ... is it possible in the first place ??
import javax.swing.*;
import java.awt.event.*;
import java.awt.Graphics;
public class JForm1 extends JFrame
{
public JForm1()
{
init();
}
public static void main(String[] args)
{
JForm1 form = new JForm1();
}
public void init()
{
JFrame frame = new JFrame("My Form 1");
frame.setSize(500,500);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
getContentPane().setLayout(new BoxLayout(this,BoxLayout.PAGE_AXIS));
JLabel label = new JLabel("Enter your Name : ");
panel MyPanel = new panel();
frame.getContentPane().add(label);
frame.getContentPane().add(MyPanel);
frame.setVisible(true);
}
}
class panel extends JPanel implements ActionListener
{
JButton submitButton;
JTextField text;
panel()
{
this.setLayout(new BoxLayout(this,BoxLayout.Y_AXIS));
}
public void paintComponent(Graphics g)
{
text = new JTextField("Enter Name here");
text.setSize(100,25);
submitButton = new JButton("Submit");
submitButton.setSize(50,90);
submitButton.setBounds(200, 0, 80, 80);
submitButton.addActionListener(this);
this.add(text);
this.add(submitButton);
}
public void actionPerformed(ActionEvent event)
{
if(event.getSource()==submitButton)
{
System.out.println("The Entered Name is : "+text.getText());
}
}
}
What is this ?:
public void paintComponent(Graphics g)
{
text = new JTextField("Enter Name here");
text.setSize(100,25);
submitButton = new JButton("Submit");
submitButton.setSize(50,90);
submitButton.setBounds(200, 0, 80, 80);
submitButton.addActionListener(this);
this.add(text);
this.add(submitButton);
}
This code has nothing to do in paintComponent. paintComponent is about "painting a component", ie, paint a rectangle, draw a line, fill an oval, etc... This is absolutely not the place where to add your components. Instead, call that code in your constructor.
Additionally, if you are using LayoutManager's (which you should), calling setSize/setBounds/setLocation is useless (dimply remove those calls).
A few more things:
If you override paintComponent, make sure to invoke the super-method
Don't extends JFrame if not needed (here it is clearly not needed)
Follow Java naming conventions (class names should start with an UpperCase letter, variables and methods with a lowerCase letter)
All Swing-related code must be called on the EDT. Start your UI within a SwingUtilities.invokeLater() block.
Try by changing layout to FlowLayout for mypanel.
mypanel.setLayout(new FlowLayout());
I have this piece of code and read that validate can refer to laying out a container's subcomponents. "Layout-related changes, such as setting the bounds of a component, or adding a component to the container, invalidate the container automatically." (source: javadoc).
However, I see no difference whatsoever between keeping validate() or removing it from this little piece of code.
Can you show me a convincing example where you can see distinct behaviour in two cases (with or without validate) to prove a point? Any other comments/advice appreciated.
public class Sw1
extends JApplet
{
JLabel lbl;
public void init()
{
lbl = new JLabel ("a label");
JPanel pan = (JPanel) getContentPane ();
pan.add(lbl);
validate();
}
}
Here is the program after I intended the push of a button to add a label. It renders an exception when I push the button:
import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
public class Sw_test
extends JApplet
implements ActionListener
{
JLabel lbl;
JButton bt ;
JPanel pan ;
JLabel l;
public void init()
{
lbl = new JLabel ("label 1");
bt = new JButton ("go ahead, press me");
bt.addActionListener(this);
JPanel pan = (JPanel) getContentPane ();
pan.setLayout(new FlowLayout());
pan.add(lbl);
pan.add(bt);
validate();
}
public void actionPerformed(ActionEvent ev)
{
l = new JLabel("new label");
pan.add(l);
}
}
You would need to call it if you add a component to a panel after it has been initialized and made visible.
Try adding a button to your applet, and on the click of the button, add a new label to the applet.
i will quote the API:
The validate method is used to cause a container to lay out its subcomponents again. It should be invoked when this container's subcomponents are modified (added to or removed from the container, or layout-related information changed) after the container has been displayed.
so as you see, it is important if you modify your layout, AFTER it has been initialized.
That is the reason why you don´t see any difference
btw: here is your example :
public class TestFrame extends JFrame{
private JButton b = new JButton();
public TestFrame() {
this.setLayout(new GridLayout(5,5));
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.add(b);
b.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
TestFrame.this.add(new JLabel("whatever"));
//try it with and without
//validate();
}
});
this.setSize(300, 300);
this.setVisible(true);
}
public static void main(String[] args) {
new TestFrame();
}
}
I am new to Java and was trying to develop a basic swing application. I wanted to set the location of the button on the JFrame. I tried to do this but was unable to do this this is my code. I am using eclipse for development
public class MyUI extends JFrame {
JButton button1 = new JButton("Click");
JTextField tb1 = new JTextField(5);
JPanel panel1 = new JPanel();
public MyUI() {
super("Test");
setVisible(true);
this.setLayout(null);
panel1.setLayout(null);
panel1.setVisible(true);
button1.setVisible(true);
panel1.add(button1);
add(panel1);
panel1.setLocation(10, 10);
button1.setLocation(10, 10);
setDefaultCloseOperation(EXIT_ON_CLOSE);
button1.addActionListener(this);
}
public static void main(String[] args) {
MyUI gui = new MyUI();
gui.setSize(400, 300);
}
}
1.why you put two JComponents to the same Bounds
panel1.setLocation(10, 10);
button1.setLocation(10, 10);
2.have look at Initials Thread
3.public class MyUI extends JFrame {
should be
public class MyUI extends JFrame implements ActionListener{
4.don't extend JFrame, create a local variable
5.setVisible(true); should be (in this form) only last code line into MyUI() constructor
6.setVisible(true); is important issue, you visibled JFrame and then to add JComponent(s)
7.don't use NullLayout, use proper LayoutManager, in the case that you remove this.setLayout(null); and panel1.setLayout(null); added JComponents could be visible
8.use pack() before setVisible(true) as last two code lines in constructor
EDIT (by using built_in LayoutManagers, BorderLayout for JFrame and FlowLayout for JPanel)
import java.awt.event.*;
import javax.swing.*;
public class MyUI extends JFrame implements ActionListener {
private static final long serialVersionUID = 1L;
private JButton button1 = new JButton("Click");
private JTextField tb1 = new JTextField(5);
private JPanel panel1 = new JPanel();
public MyUI() {
super("Test");
panel1.add(tb1);
panel1.add(button1);
add(panel1);
setDefaultCloseOperation(EXIT_ON_CLOSE);
button1.addActionListener(this);
pack();
setVisible(true);
}
public void actionPerformed(ActionEvent e) {
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
MyUI testing = new MyUI();
}
});
}
}
Your panel and button are not seen because they have zero size. Add something like:
panel1.setSize(100, 100);
button1.setSize(80, 30);
or use the setBounds method which is more convenient to set location and size simultaneously:
panel1.setBounds(10, 10, 100, 100);
button1.setBounds(10, 10, 80, 30);
Would like to suggest something, though its not the direct immediate answer to your question, but still its important from my point of view....
You can use Group Layout which was developed by NetBeans team back in 2005, its awesome to work with.... Try using the Windows Builder Pro which is provided by Google for free now... You can get your application up and running in no time......