I am new to Java events, listeners and handlers. I can write code to create a button click event and a working result. However, I cannot get a simple enter event within a TextField to work.
Notice I do declare and call action listeners, input handlers, and define a resulting method execution. (I import java.awt and javax.swing libraries not shown below.)
public convertStringToCapitalLetters() {
setTitle("Convert String to All Capital Letters");
Container c = getContentPane();
c.setLayout(new GridLayout(2, 2));
inputLabel = new JLabel("Enter String: ", SwingConstants.LEFT);
stringTextField = new JTextField(50);
outputLabel = new JLabel("Capitalized String: ", SwingConstants.LEFT);
newStringLabel = new JLabel("", SwingConstants.RIGHT);
c.add(inputLabel);
c.add(stringTextField);
c.add(outputLabel);
c.add(newStringLabel);
inputHandler = new InputHandler();
stringTextField.addActionListener(inputHandler);
setSize(WIDTH, HEIGHT);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
}
private class InputHandler implements ActionListener {
public void actionPerformed(ActionEvent e) {
String str, newStr;
str = stringTextField.getText();
newStr = str.toUpperCase();
newStringLabel.setText(String.format("", newStr));
}
}
public static void main(String[] args) {
convertStringToCapitalLetters capitalConv = new convertStringToCapitalLetters();
}
I think you just made a very small mistake which is to forget to specify the placeholder %s in String.format()
Try this:
newStringLabel.setText(String.format("%s", newStr));
You don't need the String.format("", newStr) call when setting the label's text, you can simply use
newStringLabel.setText(newStr);
Related
I have a class that has 4 private attributes, and through a JComboBox selection, I want to modify them through calling a procedure. However, it seems like even though the JComboBox appears with the selection, the attributes that are shown don't change.
public class PanneauVehicule extends JPanel {
private String[] vehicules;
private int majCarburant;
private int majPassager;
public class PanneauVehicule extends JPanel {
//Main constructor
public PanneauVehicule(){
//Creates a JPanel
super();
//Sets layout as BorderLayout
setLayout(new BorderLayout());
initListeVehicule();
initLabels();
}
public void initListeVehicule(){
vehicules = new String[] {Constantes.CS100 , Constantes.CS300 ,
Constantes.GREYHOUND102D3 , Constantes.GREYHOUNDG4500 ,
Constantes.TGVATLANTIQUE , Constantes.TGVDUPLEX};
final JComboBox<String> vehiculesList = new JComboBox<>(vehicules);
//Keep in mind the comboBox does appear with the right selections
add(vehiculesList,BorderLayout.NORTH);
//Here's where it doesnt work.
vehiculesList.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e){
majInfo(2,4);
}
});
}
public void majInfo(int test1, int test2){
this.majCarburant = test2;
this.majPassager = test1;
}
public void initLabels(){
JPanel panneauBas = new JPanel();
panneauBas.setLayout(new GridLayout(2,1,5,5));
JLabel labelCarburant = new JLabel();
labelCarburant.setText("Type de caburant: " + this.majCarburant);
JLabel labelPassagers = new JLabel();
labelPassagers.setText("Nb de passagers: " + this.majPassager);
panneauBas.add(labelPassagers);
panneauBas.add(labelCarburant);
add(panneauBas, BorderLayout.SOUTH);
panneauBas.setBackground(Color.WHITE);
}
After that, I use another procedure that will make majCarburant and majPassager appear on screen. However their values are shown as default (0). I can make their values change manually without using an ActionListener, but the task at hand requires me to use one.
I've been trying ways to just simply change the values through actionListener directly,
You don't invoke an ActionListener directly. Once an ActionListener has been added to the combo box, you can invoke:
setSelectedItem(...) or
setSelectedIndex(...)
on the combo box and the combo box will invoke the ActionListener.
I found the solution after a few more hours of meddling. I just integrated the procedure that creates labels into initListeVehicule, and from there the ActionListener can access the labels to modify their texts.
public void initListeVehiculeInfos(){
vehicules = new String[] {Constantes.CS100 , Constantes.CS300 ,
Constantes.GREYHOUND102D3 , Constantes.GREYHOUNDG4500 ,
Constantes.TGVATLANTIQUE , Constantes.TGVDUPLEX};
final JComboBox<String> vehiculesList = new JComboBox<>(vehicules);
add(vehiculesList,BorderLayout.NORTH);
JPanel panneauBas = panelGenerator();
//these setTexts serve as default values before doing your first selection
final JLabel carb = labelGenerator();
carb.setText("Carburant: Kérosène");
final JLabel passager = labelGenerator();
passager.setText("Nb Passager: 110");
vehiculesList.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e){
InterfaceVehicules info = FabriqueVehicule.obtenirVehicule(vehiculesList.getSelectedIndex());
carb.setText("Carburant: " + info.tabNomTypeCarburant[info.getTypeCarburant()] );
passager.setText("Nb Passagers: " + info.getNbPassagersMax());
}
});
panneauBas.add(carb);
panneauBas.add(passager);
add(panneauBas, BorderLayout.SOUTH);
}
I've got a very simple Java program designed to convert Fahrenheit to Celsius and vice versa. However right now I only have it set up to convert from Fahrenheit to Celsius and i'm having trouble figuring out how to go about making it work both ways.
In the end i'd like the user to be able to type into either text field and have the program know which formula to use based on whatever textfield was altered last. I'd like to use the KeyListener function from Java for this, but after reading the documentation on it i'm fairly confused on how to go about this. I know i'm supposed to add them to the textFields, but it's constructor is a throwing me off.
Here's my code so far, if someone could explain how to incorporate this into my main class i'd be really appreciative!
import java.awt.*;
import javax.swing.*;
public class Convert extends JFrame
{
private JTextField jtfFahr = new JTextField(10);
private JTextField jtfCels = new JTextField(10);
private JButton jbConvert = new JButton("Convert");
public static void main(String[] args)
{
new Convert();
}
public Convert()
{
setTitle("Convert");
setSize(400, 125);
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
JPanel jpNorth = new JPanel(new GridLayout(0, 2));
jpNorth.add(new JLabel("Fahrenheit", JLabel.RIGHT));
jpNorth.add(jtfFahr);
jpNorth.add(new JLabel("Celcius", JLabel.RIGHT));
jpNorth.add(jtfCels);
add(jpNorth, BorderLayout.NORTH);
JPanel jpSouth = new JPanel();
jpSouth.add(jbConvert);
add(jpSouth, BorderLayout.SOUTH);
Converter cvt = new Converter(jtfFahr, jtfCels);
jbConvert.addActionListener(cvt);
setVisible(true);
}
}
Here's the class that actually implements the actions as well:
import javax.swing.*;
import java.awt.event.*;
public class Converter implements ActionListener
{
private JTextField jtfDegF;
private JTextField jtfDegC;
public Converter(JTextField _jtfDegF, JTextField _jtfDegC)
{
jtfDegF = _jtfDegF;
jtfDegC = _jtfDegC;
}
public void actionPerformed(ActionEvent ae)
{
if()
{
double degF = Double.parseDouble(jtfDegF.getText());
double degC = (degF - 32) * 5.0 / 9.0;
jtfDegC.setText(String.format("%.2f", degC));
}
else
{
double degC = Double.parseDouble(jtfDegC.getText());
double degF = (degC * 9.0 / 5.0) + 32;
jtfDegF.setText(String.format("%.2f", degF));
}
}
}
As you can see it isn't complete yet due to not knowing how to pose the 'if' element.
Any simple explanation on how to implement addKeyListener to this would be great!
Never add a KeyListener to a JTextField as these are very low-level listeners and use of them can undermine the text component's normal functioning.
Usually we would recommend listening to the JTextField's Document, but in your situation a much simpler solution presents itself:
Why not simply add ActionListeners to both. When the user presses enter on either field, its own ActionListener will be called and you can then decide which conversion to do.
For example, a simple example that doubles or halves a number entered
import javax.swing.*;
#SuppressWarnings("serial")
public class TextFieldListener extends JPanel {
private JTextField field1 = new JTextField(15);
private JTextField field2 = new JTextField(15);
public TextFieldListener() {
field1.addActionListener(e -> {
String text1 = field1.getText();
try {
int value1 = Integer.parseInt(text1);
String text2 = String.valueOf(2 * value1);
field2.setText(text2);
} catch (NumberFormatException e1) {
String title = "Number Format Error";
String message = "Text must be numeric";
JOptionPane.showMessageDialog(field1, message, title, JOptionPane.ERROR_MESSAGE);
field1.setText("");
}
});
field2.addActionListener(e -> {
String text2 = field2.getText();
try {
int value2 = Integer.parseInt(text2);
String text1 = String.valueOf(value2 / 2);
field1.setText(text1);
} catch (NumberFormatException e1) {
String title = "Number Format Error";
String message = "Text must be numeric";
JOptionPane.showMessageDialog(field1, message, title, JOptionPane.ERROR_MESSAGE);
field2.setText("");
}
});
add(field1);
add(field2);
}
private static void createAndShowGui() {
JFrame frame = new JFrame("Field Listener");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new TextFieldListener());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
I'm trying to use the JButton count to count the number of characters entered into the JTextField t. I'm new to Java and GUIs but here's my code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class GUI1 extends Frame implements ActionListener{
TextField t;
Button count;
int a;
Choice choice;
public GUI1(){
this.t = new TextField("", 30);
this.count = new Button("count");
this.count.addActionListener(this);
JTextField x = new JTextField();
x.setEditable(false);
this.setTitle("Character count");
this.setLayout(new FlowLayout());
this.add(x);
this.add(t);
this.add(count);
this.pack();
this.setVisible(true);
}
public void actionPerformed(ActionEvent e) {
if(e.getSource()== this.count)
t.setText(choice.getSelectedItem()+ " " +a);
}
I'm also trying to enter the value in another uneditable JTextField x. Any help is appreciated.
Add this to your code
count.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
a = t.getText().length();
}
});
OR
You can use lambda expression like this
count.addActionListener(e -> a = t.getText().length());
For More
http://docs.oracle.com/javase/7/docs/api/java/awt/event/ActionListener.html
You need to add a listener
TextField t = new TextField();
Button b = new Button("Count");
b.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
int count = t.getText().length();
}
});
You can read more about here
http://www.tutorialspoint.com/awt/awt_button.htm
First of all, I recommend you not to use AWT elements, since it brings tons of problems and it has little to no support, instead you can try using Swing components which are a replacement/fix for AWT. You can read more about here. You might also want to read AWT vs Swing (Pros and Cons).
Now going into your problem:
You should avoid extending from JFrame, I might recommend you to create a new JFrame object instead. Here's the reason to why. That being said, you can also remove all your this.t and other calls with this.
I'm glad you're using a Layout Manager!
And now to count the number of characters on your JTextField and set text to your other JTextField you should use this code:
count.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
int count = t.getText().length();
System.out.println(count);
x.setText(t.getText());
}
});
Also I fixed your code, I changed AWT elements to Swing ones and added number of cols to your second JTextField so it would appear.
So, here's a running example that I made from your code (And removed Choice choice line since you didn't posted that code):
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class GUI1 {
JTextField t;
JButton count;
int a;
JFrame frame;
public GUI1(){
frame = new JFrame();
t = new JTextField("", 15);
count = new JButton("count");
JTextField x = new JTextField("", 15);
x.setEditable(false);
count.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
int count = t.getText().length();
System.out.println(count);
x.setText(t.getText());
}
});
frame.setTitle("Character count");
frame.setLayout(new FlowLayout());
frame.add(x);
frame.add(t);
frame.add(count);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
public static void main (String args[]) {
new GUI1();
}
}
When you click on a button you should
String str = t.getText(); // get string from jtextfield
To save the text from the texfield. Then you can use something like:
a = str..length(); // get length of string
x.setText(str + " " + a); //set it to the field
To set it to the JTextField.
I am trying to make the input from a JTextField get split into an array of words when I press a button. When I press the button the program gives me a huge list of errors. The line of code that splits the sentence and where I call the class in the action listener is where eclipse says the error is coming from. I do not know why I am getting this error and I don't know how to fix. I have tried a lot of different things but they don't work. If you could explain why this isn't working or how to fix that would be great. Here is my code. Thank you for your help.
Main Class:
public class Control {
public static void main(String[] args) {
OpenWindow ow = new OpenWindow();
ow.window();
}
}
Second Class:
public class OpenWindow extends JFrame{
//Making variables
String input;
String firstWord2;
JButton jb = new JButton("Button");
JLabel jl = new JLabel();
JTextField jtf = new JTextField(40);
JPanel jp1 = new JPanel(new GridLayout(3,1));
SentenceSplitter ss = new SentenceSplitter();
public void window() {
//Make window pop up
setTitle("Project");
setSize(600, 300);
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
//Action Listener
jb.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
input = jtf.getText();
//Error from line below
ss.split();
firstWord2 = ss.getFirstWord();
jl.setText(firstWord2);
}
});
//Add JFrames
jp1.add(jtf);
jp1.add(jb);
jp1.add(jl);
add(jp1);
}
//Make input accesible from other classes
String getInput() {
return input;
}
}
Third Class:
public class SentenceSplitter {
String firstWord;
public void split() {
OpenWindow ow2 = new OpenWindow();
//Get input
String sentence = ow2.getInput();
//Error from line below
String[] splitSentence = sentence.split(" ");
firstWord = splitSentence[0];
}
String getFirstWord() {
return firstWord;
}
}
In your code you
creating OpenWindow
In The OpenWindow object you are creating a SentenceSplitter and listening for a click
On the click you are calling the split method on the previously created SentenceSplitter
In split you are creating a new OpenWindow
What you maybe should do is pass the String as an input parameter to the split method
How can I get chosen line from JTA ?
I suppose you can use getLineStartOffset(int line), and getLineEndOffset(int line) to substring out a particular line from the string returned from getText()
If you mean that you want to know what the user has selected (using the mouse/keyboard):
getSelectedText() should give you that.
Why not break the lines up into tokens. then if you know the line number you want, you can just access it via an array of Strings
public class JTALineNum extends JFrame{
JTextArea jta = null;
JButton button = null;
public JTALineNum(){
jta = new JTextArea();
button = new JButton("Hit Me");
button.addActionListener(new ButtonListener());
add(jta, BorderLayout.CENTER);
add(button, BorderLayout.SOUTH);
setSize(200,200);
setVisible(true);
}
private class ButtonListener implements ActionListener{
public void actionPerformed(ActionEvent e) {
String text = jta.getText();
String[] tokens = text.split("\n");
for(String i : tokens){
System.out.println("Token:: " + i);
}
}
}
public static void main(String args[]){
JTALineNum app = new JTALineNum();
app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}