How to get string from JTextField and save it in variable? - java

I am making a simple kid game that will ask the user to enter his/her name in a JTextField and that name will shown in other class after ending the game.
I made new object and used it to call the method getName but when I call the method it return null
I want it to return the name that the user entered.
This is the code:
package learn_englishTest;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JLabel;
import javax.swing.JButton;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Icon;
import javax.swing.ImageIcon;
public class Home extends JFrame{
JTextArea welcome_txt,userName_txt;
JTextField user_name;
JLabel Background_lbl;
JButton exit_btn,start_btn;
JPanel panel;
Icon Background_icon;
String name;
Font userName_font,welcome_font;
public Home(){
super("Easy Fun Learning");
Container c =getContentPane();
c.setLayout(new BorderLayout());
panel =new JPanel(null);
panel.setPreferredSize(new Dimension(650,470));
welcome_txt=new JTextArea("Welcom to Easy Fun Learning ");
welcome_txt.setEditable(false);
welcome_font = new Font("Verdana", Font.BOLD, 30);
welcome_txt.setFont(welcome_font);
welcome_txt.setForeground(Color.pink);
welcome_txt.setBounds(80, 60, 500, 50);
userName_font=new Font("Verdana",Font.BOLD,20);
userName_txt=new JTextArea("Enter Your Name");
userName_txt.setEditable(false);
userName_txt.setFont(userName_font);
userName_txt.setForeground(Color.BLUE);
userName_txt.setBounds(350, 200, 200, 40);
user_name=new JTextField(10);
user_name.setBounds(400, 240, 100, 30);
start_btn=new JButton("Start");
start_btn.setBounds(480, 360, 100, 20);
exit_btn=new JButton("Exit");
exit_btn.setBounds(480, 390, 100, 20);
Background_icon=new ImageIcon(getClass().getResource("art.png"));
Background_lbl=new JLabel(Background_icon);
Background_lbl.setBounds(0, 80, 450, 450);
panel.add(welcome_txt);
panel.add(userName_txt);
panel.add(user_name);
panel.add(exit_btn);
panel.add(start_btn);
panel.add(Background_lbl);
panel.setBackground(Color.WHITE);
c.add(panel,BorderLayout.BEFORE_FIRST_LINE);
ButtonHandler handler=new ButtonHandler();
exit_btn.addActionListener(handler);
start_btn.addActionListener(handler);
}
private class ButtonHandler implements ActionListener{
#Override
public void actionPerformed(ActionEvent e) {
if(e.getSource()==exit_btn)
System.exit(0);
if(e.getSource()==start_btn){
name=user_name.getText();
List list=new List();
list.setSize(700, 700);
list.setVisible(true);
list.setDefaultCloseOperation(EXIT_ON_CLOSE);
Home.this.setVisible(false);
}
}
}
#Override
public String getName(){
return name;
}
}

You forgot to add an ActionListener.
user_name.addActionListener(handler);
I strongly suggest you to follow the Java naming conventions as well.
So user_name should be userName.

To get a string from a JTextField, you simply need the following:
String var = jTextFieldName.getText();
This will save whatever is in the JTextField into the var variable.
The getText() is simply a method belonging to the JTextField class and returns whatever text is in it.

try something like:
JTextArea userName_txt = new JTextArea("Enter Your Name");
userName_txt.getDocument().addDocumentListener(new DocumentListener() {
#Override
public void removeUpdate(final DocumentEvent paramDocumentEvent) {
name = userName_txt.getText();
}
#Override
public void insertUpdate(final DocumentEvent paramDocumentEvent) {
name = userName_txt.getText();
}
#Override
public void changedUpdate(final DocumentEvent paramDocumentEvent) {
name = userName_txt.getText();
}
});
or rewrite getName() to something like:
public String getName() {
return userName_txt.getText();
}
But you basically overwrote Component.getName() in your code which makes no sense at all, better rename your method to getUsername().

Related

How do I update JList and store into an array using a function?

I am under the impression that most of my code work, however, I think I am confident that I am only missing one line under the function updatedJList() Please help, thank you.
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.SwingConstants;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.JList;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Ex1 extends JFrame {
private JTextField txtName;
private JList nameList;
private String[] nameArr;
private int arrCounter = 0;
private JLabel lblDisplayName;
public Ex1(){
this.setTitle("Exercise01");
this.setSize(300, 266);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
getContentPane().setLayout(null);
this.nameArr = new String[10];
JLabel lblName = new JLabel("Name:");
lblName.setBounds(10, 11, 264, 14);
getContentPane().add(lblName);
this.txtName = new JTextField();
this.txtName.setBounds(10, 25, 264, 20);
getContentPane().add(this.txtName);
this.txtName.setColumns(10);
JButton btnAddName = new JButton("Add Name to List");
btnAddName.setBounds(10, 49, 264, 23);
getContentPane().add(btnAddName);
btnAddName.addActionListener(new AddNameListener());
//Create ScrollPane
JScrollPane scrollPane = new JScrollPane();
scrollPane.setBounds(10, 75, 264, 126);
getContentPane().add(scrollPane);
//Create and Add JList
this.nameList = new JList();
nameList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
this.updateJList();
this.nameList.addListSelectionListener(new DisplayListener());
this.lblDisplayName = new JLabel("(Name will be shown here)");
this.lblDisplayName.setHorizontalAlignment(SwingConstants.CENTER);
this.lblDisplayName.setBounds(10, 203, 264, 14);
getContentPane().add(this.lblDisplayName);
this.setVisible(true);
}
private class AddNameListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
updateJList();
}
}
private void updateJList(){
//I think I am missing something on this line.. HELP
String name = this.txtName.getText();
this.txtName.setText(name);
this.arrCounter++;
this.txtName.setText("");
DefaultListModel model = new DefaultListModel();
for(int i =0;i<this.nameArr.length;i++)
{
model.addElement(name);
}
this.nameList.setModel(model);
}
private class DisplayListener implements ListSelectionListener {
#Override
public void valueChanged(ListSelectionEvent arg0) {
displayName();
}
}
private void displayName()
{
int index = this.nameList.getSelectedIndex();
String name = this.nameArr[index];
this.lblDisplayName.setText(name);
}
public static void main(String[] args) {
Ex1 gui = new Ex1();
}
}
I am very very very lost at this point, I cant seem to figure out what's wrong, I've been learning Java for about 8 weeks now, and I've also been working on this question for 4 hours. I really think I am missing a line, but if you think otherwise, please feel free to comment. Thank you, wonderful people!
Edit:
After some discussion the issue that the OP is stating is the following:
Whenever I run the code, it will work, however, when I key in the name in the text box to store it in the array and display it, it will not show up in the text box, therefore I cannot display the name.
Compare the below code with that in your question. The changes are described after the code.
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.SwingConstants;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.JList;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Ex1 extends JFrame {
private JTextField txtName;
private JList<Object> nameList;
private String[] nameArr;
private int arrCounter = 0;
private JLabel lblDisplayName;
public Ex1() {
this.setTitle("Exercise01");
this.setSize(300, 266);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
getContentPane().setLayout(null);
this.nameArr = new String[10];
JLabel lblName = new JLabel("Name:");
lblName.setBounds(10, 11, 264, 14);
getContentPane().add(lblName);
this.txtName = new JTextField();
this.txtName.setBounds(10, 25, 264, 20);
getContentPane().add(this.txtName);
this.txtName.setColumns(10);
JButton btnAddName = new JButton("Add Name to List");
btnAddName.setBounds(10, 49, 264, 23);
getContentPane().add(btnAddName);
btnAddName.addActionListener(new AddNameListener());
// Create and Add JList
DefaultListModel<Object> model = new DefaultListModel<>();
this.nameList = new JList<>(model);
nameList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
// Create ScrollPane
JScrollPane scrollPane = new JScrollPane(nameList);
scrollPane.setBounds(10, 75, 264, 126);
getContentPane().add(scrollPane);
this.nameList.addListSelectionListener(new DisplayListener());
this.lblDisplayName = new JLabel("(Name will be shown here)");
this.lblDisplayName.setHorizontalAlignment(SwingConstants.CENTER);
this.lblDisplayName.setBounds(10, 203, 264, 14);
getContentPane().add(this.lblDisplayName);
this.setVisible(true);
}
private class AddNameListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
updateJList();
}
}
private void updateJList() {
// I think I am missing something on this line.. HELP
String name = this.txtName.getText();
this.txtName.setText(name);
this.arrCounter++;
this.txtName.setText("");
DefaultListModel<Object> model = (DefaultListModel<Object>) nameList.getModel();
model.addElement(name);
}
private class DisplayListener implements ListSelectionListener {
#Override
public void valueChanged(ListSelectionEvent arg0) {
displayName();
}
}
private void displayName() {
int index = this.nameList.getSelectedIndex();
if (index >= 0) {
ListModel<Object> model = nameList.getModel();
Object obj = model.getElementAt(index);
String name = obj == null ? "" : obj.toString();
this.lblDisplayName.setText(name);
}
}
public static void main(String[] args) {
Ex1 gui = new Ex1();
}
}
Create a model for the JList first and pass it to the JList constructor.
DefaultListModel<Object> model = new DefaultListModel<>();
this.nameList = new JList<>(model);
You are adding an empty JScrollPane. You need to pass the JList to the JScrollPane constructor.
JScrollPane scrollPane = new JScrollPane(nameList);
In method updateJList(), you don't need a new model, you just need to update the existing model by adding an element to it.
DefaultListModel<Object> model = (DefaultListModel<Object>) nameList.getModel();
model.addElement(name);
EDIT
Excuse me, I didn't pay attention to that part of your code that displays the selected value from nameList.
I changed method displayName() in the above code to the following:
private void displayName() {
int index = this.nameList.getSelectedIndex();
if (index >= 0) {
ListModel<Object> model = nameList.getModel();
Object obj = model.getElementAt(index);
String name = obj == null ? "" : obj.toString();
this.lblDisplayName.setText(name);
}
}
You don't need nameArr and you don't need arrCounter.
There is no need for an Array.
When you use Swing components, the data is store in a "model", in this case the DefaultListModel. So the data is added to the model and if you every want to access the data in the JList you get the data from the model.
DefaultListModel model = new DefaultListModel();
That code is wrong. You don't want to keep creating a new model every time you click on the button. You want to add items to the existing model so all the items can be displayed.
Read the section from the Swing tutorial on How to Use Lists. The ListDemo code will show you how to better structure your class so you can dynamically add and remove items in the model. So download the code and modify it for your requirements.

Java cannot instantiate type ActionListener

im trying to add an ActionListener to my buttons for my calculator Im making. The problem is that Im being presented an error when I try to make an ActionListener. I tried in one class then I created a listener class just to see if that would help. Here is my code:
package main;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.event.ActionListener;
import java.io.IOException;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
public abstract class Main extends JFrame implements Listener{
public static void main(String[] args) throws IOException{
//Main variables
String dis = "0";
double ans = Double.parseDouble(dis);
//Making frames
JFrame frame = new JFrame("Calculator");
JPanel panel = new JPanel();
//Buttons
JButton enter = new JButton("Enter");
JButton sub = new JButton("-");
JButton add = new JButton("+");
JButton div = new JButton("รท");
JButton mult = new JButton("*");
JTextField text = new JTextField(dis);
//Font
Font bigFont = text.getFont().deriveFont(Font.PLAIN, 30f);
Font butf = text.getFont().deriveFont(Font.PLAIN, 20f);
//Methods
panel.setLayout(new FlowLayout());
panel.add(text);
panel.setSize(590, 100);
text.setColumns(22);
text.setFont(bigFont);
text.setHorizontalAlignment(JTextField.RIGHT);
text.setEditable(false);
enter.setForeground(Color.RED);
sub.setForeground(Color.RED);
div.setForeground(Color.RED);
mult.setForeground(Color.RED);
add.setForeground(Color.RED);
//Buttons Methods
enter.setBounds(470, 450, 100, 150);
sub.setBounds(470, 350, 100, 90);
div.setBounds(470, 250, 100, 90);
mult.setBounds(470, 150, 100, 90);
add.setBounds(470, 50, 100, 90);
enter.setFont(butf);
sub.setFont(butf);
div.setFont(butf);
mult.setFont(butf);
add.setFont(butf);
//Frame
frame.add(div);
frame.add(mult);
frame.add(sub);
frame.add(enter);
frame.add(add);
frame.add(panel);
frame.setSize(600, 650);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
//extra
text.setSize(1000, 100);
//Actions
}
}
package main;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
public interface Listener extends ActionListener {
//Throwing error here 'Cant instantiate the type ActionListener'
ActionListener al = new ActionListener();
public default void actionPerformed(ActionEvent e){
}
}
Anyone know how to fix this error?
To declare an ActionListener use
public class Listener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
//dostuff
}
}
ActionListener is a interface, it can't be instantiated, without provide a concrete implementation of it's contract
interfaces can't contain instance fields
Simply speaking, it should look more like...
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public interface Listener extends ActionListener {
public default void actionPerformed(ActionEvent e) {
}
}
You may also like to have a closer look at
How to Write an Action Listeners
What Is an Interface?
The Interfaces trail
In Swing, you should make sure that your UI is only created and manipulated from within the context of the Event Dispatching Thread. Have a look at Initial Threads for more details
You're also going to be very disappointed with the results of your layout, have a look at Laying Out Components Within a Container for better solutions

How can we put value on text field on output screen?

I want to put value in txtf1 at output screen and get it. How can we put value on text field on output screen?
import java.awt.Color;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
public class demog extends JPanel implements ActionListener{
private TextField textf, txtf1;
public void jhand(){
textf = new TextField();
textf.setSize(40, 40);
textf.setText("20");
textf.setEditable(false);
textf.setBackground(Color.WHITE);
textf.setForeground(Color.BLACK);
//textf.setHorizontalAlignment(SwingConstants.CENTER);
textf.setLocation(15, 15);
//textf.addActionListener(this);
txtf1 = new TextField();
txtf1.setSize(40, 40);
txtf1.getText();
txtf1.setEditable(false);
txtf1.setBackground(Color.WHITE);
txtf1.setForeground(Color.BLACK);
//txtf1.setHorizontalAlignment(SwingConstants.CENTER);
txtf1.setLocation(50, 50);
JFrame frame = new JFrame("demo");
JPanel p = new JPanel();
p.setOpaque(true);
p.setBackground(Color.WHITE);
p.setLayout(null);
frame.setContentPane(p);
frame.setSize(500,500);
frame.setVisible(true);
p.add(textf);
p.add(txtf1);
}
public void actionPerformed(ActionEvent evt) {
String text = textf.getText();
System.out.println(text);
}
public static void main(String... args){
demog g = new demog();
g.jhand();
}
}
You have to change some of your code in order to work. You had some problem in your code which I resolved them for you in the following code. See the comments to learn some in swing ;-)
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.WindowConstants;
// Use upper Case in the start of you class names:
public class Demog extends JPanel implements ActionListener {
private JTextField textf, txtf1;
public Demog() {
jhand();
}
public void jhand() {
setLayout(new FlowLayout()); // Always set the layout before you add components
// you can use null layout, but you have to use setBounds() method
// for placing the components. For an advanced layout see the
// tutorials for GridBagLayout and mixing layouts with each other.
textf = new JTextField(); // Do not mix AWT component with
// Swing (J components. See the packages)
//textf.setSize(40, 40); // Use setPreferredSize instead
textf.setPreferredSize(new Dimension(40, 40));
textf.setText("20");
textf.setEditable(false); // Text fields are for getting data from user
// If you need to show something to user
// use JLabel instead.
textf.setBackground(Color.WHITE);
textf.setForeground(Color.BLACK);
add(textf);
txtf1 = new JTextField();
//txtf1.setSize(40, 40); Use setPreferredSize instead
txtf1.setPreferredSize(new Dimension(40, 40));
txtf1.getText();
txtf1.setEditable(false);
txtf1.setBackground(Color.WHITE);
txtf1.setForeground(Color.BLACK);
add(txtf1);
JButton b = new JButton("Click ME!");
b.addActionListener(this);
add(b);
}
public void actionPerformed(ActionEvent evt) {
String text = textf.getText();
JOptionPane.showMessageDialog(Demog.this, "\"textf\" text is: "+text);
}
public static void main(String[] args) {
JFrame frame = new JFrame("demo");
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
Demog p = new Demog();
p.setBackground(Color.WHITE);
frame.setContentPane(p);
frame.setSize(500, 500);
frame.setVisible(true);
}
}
Good Luck.

Prevent the code from returning value before user input

I have the following code to get 2 input from user through JCombo box, then I return the value s of the obtained input to the calling function but the problem is that this code displays the frame to obtain user input but before user can press the 'Ok' button it returns the null value to the calling function.I am looking to halt the code in this method till user presses 'Ok' button.
Please suggest something.
package io;
import java.io.*;
import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.Insets;
import java.io.FileNotFoundException;
public class SrcAndTargLangInput implements ActionListener {
public static JFrame frame;
public static JComboBox sourcLang;
public static JComboBox targLang;
public static JLabel setSrcLang;
public static JLabel setTargLang;
public static JButton ok;
static String[] lang=new String[2];
public SrcAndTargLangInput(){
ok = new JButton("Ok");
ok.setBounds(150,150,100,50);
frame = new JFrame();
frame.getContentPane().setLayout(null);
frame.getContentPane().add(ok);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
Insets ins = frame.getInsets();
frame.setSize(400+ins.left+ins.right, 200+ins.bottom+ins.top);
setSrcLang=new JLabel("Source Language");
frame.getContentPane().add(setSrcLang);
setSrcLang.setBounds(50, 50, 100, 40);
setTargLang=new JLabel("Target Language");
frame.getContentPane().add(setTargLang);
setTargLang.setBounds(50, 100, 100, 40);
String[] srcLangList={"English","Spanish","French"};
sourcLang = new JComboBox(srcLangList);
frame.getContentPane().add(sourcLang);
sourcLang.setBounds(250,50,100,40);
String[] targLangList={"English","Spanish","French"};
targLang = new JComboBox(targLangList);
frame.getContentPane().add(targLang);
targLang.setBounds(250,100,100,40);
frame.setVisible(true);
ok.addActionListener(this);
}
public static String[] langInfo(){
SrcAndTargLangInput ob = new SrcAndTargLangInput();
return lang;
}
public void actionPerformed(ActionEvent e){
lang[0]=(sourcLang.getSelectedItem().toString());
lang[1]=(targLang.getSelectedItem().toString());
frame.setVisible(false);
}
}
The calling function is :
String[] lg = new String[2];
lg = io.SrcAndTargLangInput.langInfo();
System.out.println(lg[0]);
System.out.println(lg[1]);
In your code you can add a boolean variable with a default value as false.
In the actionPerformed method set that value to true. Update your logInfo method to make the thread sleep till no action is performed. Look at the code below.
import java.io.*;
import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.Insets;
import java.io.FileNotFoundException;
public class SrcAndTargLangInput implements ActionListener {
public static JFrame frame;
public static JComboBox sourcLang;
public static JComboBox targLang;
public static JLabel setSrcLang;
public static JLabel setTargLang;
public static JButton ok;
static String[] lang=new String[2];
boolean actionPerformed = false;
public SrcAndTargLangInput(){
ok = new JButton("Ok");
ok.setBounds(150,150,100,50);
frame = new JFrame();
frame.getContentPane().setLayout(null);
frame.getContentPane().add(ok);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
Insets ins = frame.getInsets();
frame.setSize(400+ins.left+ins.right, 200+ins.bottom+ins.top);
setSrcLang=new JLabel("Source Language");
frame.getContentPane().add(setSrcLang);
setSrcLang.setBounds(50, 50, 100, 40);
setTargLang=new JLabel("Target Language");
frame.getContentPane().add(setTargLang);
setTargLang.setBounds(50, 100, 100, 40);
String[] srcLangList={"English","Spanish","French"};
sourcLang = new JComboBox(srcLangList);
frame.getContentPane().add(sourcLang);
sourcLang.setBounds(250,50,100,40);
String[] targLangList={"English","Spanish","French"};
targLang = new JComboBox(targLangList);
frame.getContentPane().add(targLang);
targLang.setBounds(250,100,100,40);
frame.setVisible(true);
ok.addActionListener(this);
}
public static String[] langInfo() throws InterruptedException{
SrcAndTargLangInput ob = new SrcAndTargLangInput();
while(!ob.actionPerformed) {
Thread.sleep(1000);
}
return lang;
}
public void actionPerformed(ActionEvent e){
lang[0]=(sourcLang.getSelectedItem().toString());
lang[1]=(targLang.getSelectedItem().toString());
actionPerformed = true;
frame.setVisible(false);
Thread.currentThread().interrupt();
}
}
Based on these lines:
String[] lg = new String[2];
lg = io.SrcAndTargLangInput.langInfo();
The problem is your SrcAndTargLangInput class uses a JFrame to ask the user for the input. Having said this, JFrame is not modal and thus it doesn't block the current thread waiting for an input as you wish. You have to use a modal JDialog or JOptionPane(which displays a modal dialog) instead in order to wait until users confirm their input.
Take a look to these topics:
The Use of Multiple JFrames, Good/Bad Practice?
How to Use Modality in Dialogs
How to Make Dialogs
Off-topic
As many developers have already said, Swing is designed to be used with Layout Managers and you should avoid methods such as setBounds(), setLocation() or setSize(). You may want to take a look to these topics too:
Should I avoid the use of set(Preferred|Maximum|Minimum)Size methods in Java Swing?
Nested Layout Example
Providing white space in a Swing GUI
Example (using JOptionPane)
Note the text field's text doesn't change until you confirm your input.
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class Demo {
private void createAndShowGui() {
final JTextField textField = new JTextField(10);
textField.setEditable(false);
JButton button = new JButton("Show dialog");
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JComboBox languagesComboBox = new JComboBox(new Object[]{"English","Spanish","French"});
JPanel dialogPanel = new JPanel();
dialogPanel.add(new JLabel("Please select an option:"));
dialogPanel.add(languagesComboBox);
int option = JOptionPane.showConfirmDialog(null, dialogPanel, "Select an input"
, JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
if(option == JOptionPane.OK_OPTION) {
String selectedInput = (String)languagesComboBox.getSelectedItem();
textField.setText(selectedInput);
}
}
});
JPanel content = new JPanel();
content.add(new JLabel("User input:"));
content.add(textField);
content.add(button);
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.add(content);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Demo().createAndShowGui();
}
});
}
}

Switching between JPanels in different classes

I've stumbled upon this complications and have spent more than 4 hours debugging and googling but to no avail..
Basically what I have here is 1 JFrame, 2 JPanels.
I had my JFrame setContentPane to 1 of the JPanel, and when I run the Application, the JFrame will appear with the JPanel inside.
Now this JPanel have 1 JButton inside it, when I click it I want it to switch to another JPanel. As you can see from the code, when I click the JButton(Add Product), I want the OnlineShopAdPane to switch to AddProduct. I tried using CardLayout but it only has NSEW formatting.
package OnlineShop.ui;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import java.awt.CardLayout;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class OnlineShopMainFrame extends JFrame {
/**
* Launch the application.
*/
AddProduct Add;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
OnlineShopMainFrame MainFrame = new OnlineShopMainFrame();
MainFrame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public OnlineShopMainFrame() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
OnlineShopAdPane AdPanel = new OnlineShopAdPane();
setContentPane(AdPanel);
}
}
package OnlineShop.ui;
import javax.swing.JPanel;
import java.awt.CardLayout;
import javax.swing.JLabel;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.BorderLayout;
public class OnlineShopAdPane extends JPanel {
/**
* Create the panel.
*/
public OnlineShopAdPane() {
JLabel lblWhatDoYou = new JLabel("What do you want to do?");
lblWhatDoYou.setBounds(28, 26, 160, 26);
add(lblWhatDoYou);
JButton btnAddProduct = new JButton("Add Product");
btnAddProduct.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
OnlineShopMainFrame MainFrame = new OnlineShopMainFrame();
MainFrame.removeAll();
MainFrame.add(new AddProduct());
MainFrame.revalidate();
MainFrame.repaint();
}
});
btnAddProduct.setBounds(46, 75, 115, 23);
add(btnAddProduct);
}
}
package OnlineShop.ui;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.JTextArea;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class AddProduct extends JPanel {
private JTextField textField;
/**
* Create the panel.
*/
public AddProduct() {
JLabel lblProductName = new JLabel("Product Name:");
lblProductName.setBounds(35, 26, 77, 24);
add(lblProductName);
JLabel lblProductDescription = new JLabel("Product Description:");
lblProductDescription.setBounds(10, 50, 106, 24);
add(lblProductDescription);
textField = new JTextField();
textField.setBounds(116, 28, 141, 20);
add(textField);
textField.setColumns(10);
JTextArea textArea = new JTextArea();
textArea.setBounds(116, 66, 141, 112);
add(textArea);
JButton btnClose = new JButton("Close");
btnClose.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
}
});
btnClose.setBounds(223, 244, 89, 23);
add(btnClose);
}
}
I tried using CardLayout but it only has NSEW formatting.
What does that mean? A CardLayout simply contains two or more panels. Only one panel is visible at a time. Each panel can use whatever layout it wants to layout the components on the panel.
when I click it I want it to switch to another JPanel.
That is exactly what CardLayout does. See the Swing tutorial on How to Use Card Layout for a working example and explanation.
Whenever I see code like remove/add/revalidate/repaint it should almost always be replaced with a CardLayout
I think that with CardLayout you can resolve it, but another way is using for example a Handler to switch your panels.
private JComponent container; // this could be your Frame
private JComponent loadedComponent;
public void loadContent(JComponent component, Object object ) {
if (loadedComponent != null) {
loadedComponent.setVisible(false);
container.remove(loadedComponent);
loadedComponent = null;
}
//TODO may check layout
container.add(component,object);
component.setVisible(true);
loadedComponent = component;
container.validate();
}
The problem is pobably located at the following lines in class OnlineShopAdPane.java
OnlineShopMainFrame MainFrame = new OnlineShopMainFrame();
MainFrame.removeAll();
MainFrame.add(new AddProduct());
MainFrame.revalidate();
MainFrame.repaint();
your not referring to the frame where your JPanel is nested. instead your creating a new OnlineShopMainFrame

Categories