When I run this code which should take the text from a JLabel, use a getter method to move it to the button action class, modifiy it and then use a setter method to set it in the original class, it updates the JLabel variable but does not update the GUI.
I have tried repaint(), revalidate(), doLayout() on the label, the frame and the panel that holds the label.
The class that initializes the label:
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import java.awt.event.ActionListener;
import javax.swing.JLabel;
import javax.swing.SwingConstants;
import javax.swing.JButton;
public class Testing4 {
private JFrame frame;
private JLabel lblNewLabel;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Testing4 window = new Testing4();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public Testing4() {
initialize();
}
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);
lblNewLabel = new JLabel("label");
lblNewLabel.setBounds(52, 101, 277, 53);
frame.getContentPane().add(lblNewLabel);
lblNewLabel.setHorizontalAlignment(SwingConstants.CENTER);
JButton btnNewButton = new JButton("New button");
btnNewButton.setBounds(114, 28, 156, 53);
frame.getContentPane().add(btnNewButton);
btnNewButton.addActionListener(new ButtonAction());
}
public String getLabelText()
{
return this.lblNewLabel.getText();
}
public void setLabelText(String text)
{
System.out.println(text);
this.lblNewLabel.setText(text);
System.out.println(lblNewLabel.getText());
}
}
If you look at the setLabelText(String) method, it sets the text to the label called lblNewLabel and then it prints out the text to the console in the next line of code. That .getText() shows that the label has been modified, however the GUI does not show that it has been modified.
Here is the code for the button:
public class ButtonAction implements ActionListener
{
Testing4 test;
public void actionPerformed(ActionEvent e)
{
test = new Testing4();
String x = test.getLabelText();
System.out.println(x);
x = x + " hello";
System.out.println(x);
test.setLabelText(x);
}
}
For all intents and purposes, this should update the GUI with the new text, I've done this before and not had an issue but something this time is causing an issue.
Related
I was making a GUI to reverse an input string, I am taking input from the first textfield, then reversing the string using my function strRev() then trying to produce the result on the second textfield. But am not getting any output on 2nd textfield.
package com.awt;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.Spring;
import javax.swing.SpringLayout;
import javax.swing.plaf.basic.BasicOptionPaneUI.ButtonActionListener;
import java.awt.FlowLayout;
import java.awt.GridBagLayout;
import java.awt.GridBagConstraints;
import java.awt.Insets;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JTextField;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.InputMethodListener;
import java.awt.event.InputMethodEvent;
public class Buttons{
private JFrame frame;
private JTextField textField;
private JTextField textField_1;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Buttons window = new Buttons();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public Buttons() {
initialize();
}
public String strRev(String s) {
char a;
String ans="";
for(int i=0;i<s.length();i++) {
a=s.charAt(i);
ans=a+ans;
}
return ans;
}
private void initialize() {
frame = new JFrame("Label Demo");
frame.setBounds(150, 200, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));
textField = new JTextField();
frame.getContentPane().add(textField);
textField.setColumns(10);
JButton okButton = new JButton("Reverse");
frame.getContentPane().add(okButton);
textField_1 = new JTextField();
frame.getContentPane().add(textField_1);
textField_1.setColumns(10);
String str=textField.getText();
final String ans=strRev(str);
okButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
textField_1.setText(ans);
}
});
}
}
The GUI looks like this:-
Please let me know my mistake, Thanks
You need to read the contents of textField only when the user clicks on the Reverse button. At the moment, you read the contents when the GUI loads at which time there is nothing in the textField. So calling a reverse on empty string is going to give you an empty string and that is what you see in your textField_1. Move the code where you read the textField into your addActionListener.
private void initialize() {
frame = new JFrame("Label Demo");
frame.setBounds(150, 200, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));
textField = new JTextField();
frame.getContentPane().add(textField);
textField.setColumns(10);
JButton okButton = new JButton("Reverse");
frame.getContentPane().add(okButton);
textField_1 = new JTextField();
frame.getContentPane().add(textField_1);
textField_1.setColumns(10);
okButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// THIS BLOCK IS RUN EVERYTIME THE BUTTON IS CLICKED!
// Read the contents of textField
String str=textField.getText();
// Reverse the string you just read
final String ans=strRev(str);
// Set the answer on the other textField.
textField_1.setText(ans);
}
});
}
I want to change the text of a JLabel outside of the method I created it in.
I've looked through the other pages on the same topic but I still cannot get it to work. Perhaps I am lacking knowledge of Java to solve this by myself.
Would you please help me?
package autumn;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class Main {
private JFrame frame;
JLabel TestLabel;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Main window = new Main();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public Main() {
initialize();
setText();
}
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);
JLabel TestLabel = new JLabel("");
TestLabel.setBounds(0, 0, 46, 14);
frame.getContentPane().add(TestLabel);
}
void setText() {
TestLabel.setText("Works!");
}
}
You have a class field JLabel TestLabel.
But in the initializemethod you shadow this field by using a local variable with the same name:
JLabel TestLabel = new JLabel("");
so the class field is not initialized and the later call to setText fails.
Therefore simply write:
TestLabel = new JLabel(""); // assigns to Main.TestLabel
I am creating a JTextField everytime a label is clicked. My problem is to get the text inside those created textfields.
This is my code:
public void mouseClicked(MouseEvent arg0) {
List<JTextField> mine = new ArrayList<JTextField>();
box = new JTextField();
name = new JTextField();
pnlPanel.add(box);
pnlpanel.add(name);
lay++;
if (lay > 0) {
box.setBounds(283, 145, 182, 27);
name.setBounds(81, 145, 182, 27);
mine.add(box);
}
GetData mydata = new GetData();
mydata.doGetData();
frame.repaint();
}
This is my code for getting the data inputted by the user, but it doesnt work:
public class GetData {
public void doGetData(List<JTextField> myFields) {
for (JTextField txt: myFields) {
}
}
}
How does I get the user input?
You will have to store the fields in some kind of way. I prefer to use an ArrayList, but (as mentioned by Klemens Morbe) there are many ways to that.
Here is a basic example, the output will appear in the console.
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Collection;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
public class MoreAndMoreTextfields extends JFrame {
// the panel, that we will add the visible fields to
private JPanel panel = new JPanel();
// a collection of all fields, so that we can access them afterwards
private Collection<JTextField> textFields = new ArrayList<JTextField>();
public MoreAndMoreTextfields() {
// basic window layout stuff
setSize(400, 300);
setLayout(new FlowLayout());
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
setContentPane(panel);
// add label, that will create new input fields
JLabel addInputLabel = new JLabel("click for more fields");
addInputLabel.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
JTextField textField = new JTextField();
panel.add(textField);
textField.setPreferredSize(new Dimension(100,20));
textFields.add(textField);
revalidate();
}
});
panel.add(addInputLabel);
// add new label, that will print out contents
JLabel outputLabel = new JLabel("click for contents");
outputLabel.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
System.out.println("Contents of fields:");
for (JTextField textField : textFields) {
System.out.println(" input:"+textField.getText());
}
}
});
panel.add(outputLabel);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new MoreAndMoreTextfields().setVisible(true);
}
});
}
}
For getting the text of the JTextField use textfield.getText().
You could save the JTextFields to a list List<JTextField>
or iterate through the panels componentspanel.getComponents().
Aslo you could give every JTextField an id like this textfield.setName("id");.
I am trying to implement a swing frame. In this, I want to display a processing status in a textPanel using a different thread while performing the needed task. I tried the following code. Of course there is something wrong with the logic. Please provide me with the proper approach
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class SampleSwing {
private JFrame frame;
public static JTextField textField;
public static boolean processing=false;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
SampleSwing window = new SampleSwing();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public SampleSwing() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);
textField = new JTextField();
textField.setBounds(0, 31, 434, 20);
frame.getContentPane().add(textField);
textField.setColumns(10);
JButton btnNewButton = new JButton("New button");
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
processing=true;
Processingstatus ps=new Processingstatus();
ps.start();
/*perform the actual task*/
processing=false;
}
});
btnNewButton.setBounds(174, 74, 89, 23);
frame.getContentPane().add(btnNewButton);
}
}
class Processingstatus extends Thread{
public void run() {
try {
while(SampleSwing.processing) {
SampleSwing.textField.setText("Processing");
Thread.sleep(1000);
SampleSwing.textField.setText("Processing..");
Thread.sleep(1000);
SampleSwing.textField.setText("Processing...");
Thread.sleep(1000);
}
}
catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
First I thought, "you should be using a SwingWorker, as it has methods to handle progress and EDT updates..."
But when I looked closer, you don't actually really care about the process itself, you just want some where to show that a process is running...They are two separate entities, that are only related because one (the UI updates) will run so long as the other is running.
So, instead, I used a javax.swing.Timer. This allows me to schedule an event to occur every n milliseconds and have that triggered in the EDT, nice and clean...
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.SwingWorker;
import javax.swing.Timer;
public class SampleSwing {
private JFrame frame;
public static JTextField textField;
public static boolean processing = false;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
SampleSwing window = new SampleSwing();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public SampleSwing() {
initialize();
}
private Timer processTimer;
private void initialize() {
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
textField = new JTextField(25);
frame.add(textField, gbc);
processTimer = new Timer(500, new ActionListener() {
private StringBuilder dots = new StringBuilder(3);
#Override
public void actionPerformed(ActionEvent e) {
dots.append(".");
if (dots.length() > 3) {
dots.delete(0, dots.length());
}
textField.setText("Processing" + dots.toString());
}
});
JButton btnNewButton = new JButton("New button");
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
if (!processing) {
processing = true;
processTimer.start();
} else {
processTimer.stop();
processing = false;
textField.setText(null);
}
}
});
frame.add(btnNewButton, gbc);
frame.pack();
frame.setLocationRelativeTo(null);
}
}
ps For the reason why your original code didn't work, see my comment in the above comments section ;)
Ok so I'm trying to get familier with Java, and I've made a simple thing where if you click a button then some text appears. How can I make it so the button and label are created in one class file, and put the code for when the button is clicked in another? Sorry if it sounds like a silly question.
Pastebin code:
package com.nate.derp;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JButton;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class Derp {
private JFrame frmHello;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Derp window = new Derp();
window.frmHello.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public Derp() {
initialize();
}
public void initialize() {
frmHello = new JFrame();
frmHello.setTitle("Hello");
frmHello.setBounds(100, 100, 225, 160);
frmHello.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frmHello.getContentPane().setLayout(null);
final JLabel helloLabel = new JLabel("Hello World!");
helloLabel.setVisible(false);
helloLabel.setBounds(40, 89, 145, 16);
frmHello.getContentPane().add(helloLabel);
final JButton btnClickMe = new JButton("Click Me!");
btnClickMe.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
helloLabel.setVisible(true);
}
});
btnClickMe.setBounds(54, 29, 117, 29);
frmHello.getContentPane().add(btnClickMe);
}
}
You can do this by creating a JButton and adding an ActionListener, which can be implemented by another class.
So you first create the JButton:
Jbutton button = new JButton("hello");
Then add the Actionlistener:
button.addActionListener(new MyListener());
Where MyListener is your implementation class
class MyListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
...
}
}