Java- How to add more textfields by clicking a button? - java

I have created a frame in Java which has some textfields and buttons in it. Assuming that user wants more textfields (for example to add more data), I want to put a button and when a user clicks the button, then a new textfield should appear. then user can fill data in it and again by clicking that button another textfield should appear.
How can I do this ? What code I need to write for the button to show more and more text fields by clicking button?
Thank you !

It would be wise that instead of adding components to your JFrame directly, you add them to a JPanel. Though related to your problem, have a look at this small example, hopefully might be able to give you some hint, else ask me what is out of bounds.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class JFrameExample
{
private JFrame frame;
private JButton button;
private JTextField tfield;
private String nameTField;
private int count;
public JFrameExample()
{
nameTField = "tField";
count = 0;
}
private void displayGUI()
{
frame = new JFrame("JFrame Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridLayout(0, 1, 2, 2));
button = new JButton("Add JTextField");
button.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent ae)
{
tfield = new JTextField();
tfield.setName(nameTField + count);
count++;
frame.add(tfield);
frame.revalidate(); // For JDK 1.7 or above.
//frame.getContentPane().revalidate(); // For JDK 1.6 or below.
frame.repaint();
}
});
frame.add(button);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String... args)
{
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
new JFrameExample().displayGUI();
}
});
}
}

Supposing that you have a main container called panel and a button variable button which is already added to panel, you can do:
// handle the button action event
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// create the new text field
JTextField newTextField = new JTextField();
// add it to the container
panel.add(newTextField);
panel.validate();
panel.repaint();
}
});
When adding the new text field, you may need to mention some layout related characteristics, depending on the layout manager you are using (for instance if you use GridBagLayout, you will need to specify the constraints).

Related

label.setText - change with another textarea?

Having an issue with some bits of my code.
label1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
label1.setText(-Here i want the button to open up a new "update window, and it will update the label to the text i'll provide in a seperate window);
}
});
Is there any way to do it without without an additional form? Just wanted to add that i have several labels, and i'm not sure on how to start with it.
One approach is to return a result from your update dialog which you can then use to update the text in label1. Here's an example which updates the label text based on the result return from a JOptionPane
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Test {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
frame.setMinimumSize(new Dimension(200, 85));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new FlowLayout());
JLabel label = new JLabel("Original Text");
frame.add(label);
JButton button = new JButton("Click Me");
frame.add(button);
// to demonstrate, a JOptionPane will be used, but this could be replaced with a custom dialog or other control
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
int result = JOptionPane.showConfirmDialog(frame, "Should I update the label?", "Test", JOptionPane.OK_CANCEL_OPTION );
// if the user selected 'Ok' then updated the label text
if(result == JOptionPane.OK_OPTION) {
label.setText("Updated text");
}
}
});
frame.setVisible(true);
}
});
}
}
Another approach would be to use an Observer and Observable which would listen for updates and change the label text accordingly. For more on the Observer, take a look at this question: When should we use Observer and Observable

Automatic Resize of jPanel as text is added

I have a text game which has buttons. When a button is clicked, text appears. My text appears inside a jPanel, which is inside a jScrollPane. I would like my jPanel to automatically make more vertical space for my lines of text to be added. I have been doing it by hand but it is a lot more time consuming. Is there anyway to do this, or maybe pack a jPanel somehow. I am pretty new to this so if any extra information is needed for you to help me out feel free to ask. Thanks.
I would use a component that can do this automatically -- a JTextArea. It will automatically enlarge as more text is added.
If you need more specific help or a code example, please post your own small compilable and runnable test example program, and I can try to modify it.
You state:
I don't want to use a JTextArea because I don't want the user to be able to highlight or delete any of the text that was there in the first place.
No problem. Just make the JTextArea non-focusable and non-editable.
I have been using jLabels which are equal to "" and when a button is pressed, that jLabel is given a new value.
Try something like this:
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.*;
#SuppressWarnings("serial")
public class AddNewLines extends JPanel {
private JTextArea textArea = new JTextArea(10, 15);
private JButton addLineBtn = new JButton(new AddLineAction("Add Line", KeyEvent.VK_A));
public AddNewLines() {
textArea.setEditable(false);
textArea.setFocusable(false);
textArea.setWrapStyleWord(true);
textArea.setLineWrap(true);
textArea.setOpaque(false);
JScrollPane scrollPane = new JScrollPane(textArea);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
add(scrollPane);
add(addLineBtn);
}
class AddLineAction extends AbstractAction {
private int count = 0;
public AddLineAction(String name, int mnemonic) {
super(name);
putValue(MNEMONIC_KEY, mnemonic);
}
#Override
public void actionPerformed(ActionEvent e) {
if (count != 0) {
textArea.append("\n");
}
textArea.append("Line of Text: " + count);
count++;
}
}
private static void createAndShowGui() {
AddNewLines mainPanel = new AddNewLines();
JFrame frame = new JFrame("Add New Lines");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}

hide/show label and button produce noise in jdialog in java?

i create a dialog box in java desktop application . But when i hide/show label and button by applying condition on checkbox .its produce graphical noise by showing some part of background application part(like red box on both label and buttons also checkbox layout causes problem). i write this condition on checkbox.
checkbox.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
if (checkbox.isSelected()) {
baisvalue.setVisible(true); //label
plusbais.setVisible(true); //button
minisbais.setVisible(true); //button
}
if (!checkbox.isSelected()) {
minisbais.setVisible(false); //label
plusbais.setVisible(false); //button
baisvalue.setVisible(false); //button
}
}
});
note:
i also call repaint(); & validate(); but same problem occurs.
I wasn't able to recreate your problem - I see no graphical noise. I've attached a sscce of what I tried - Can you reproduce your problem with this example? If so, can you provide us with more information about your java version/platform? If not, can you modify this example to recreate your problem (and edit your question with the code)?
import java.awt.event.*;
import javax.swing.*;
public class MainPanel extends Box{
JCheckBox checkbox = new JCheckBox("Select Me");
JLabel baisvalue = new JLabel("baisvalue");
JButton plusbais = new JButton("plusbais");
JButton minisbais = new JButton("minisbais");
public MainPanel(){
super(BoxLayout.Y_AXIS);
ActionListener l = new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
if (checkbox.isSelected()) {
baisvalue.setVisible(true); //label
plusbais.setVisible(true); //button
minisbais.setVisible(true); //button
}
if (!checkbox.isSelected()) {
minisbais.setVisible(false); //label
plusbais.setVisible(false); //button
baisvalue.setVisible(false); //button
}
}
};
checkbox.addActionListener(l);
add(checkbox);
add(baisvalue);
add(plusbais);
add(minisbais);
//Performs the action on initialization
l.actionPerformed(new ActionEvent(checkbox, ActionEvent.ACTION_PERFORMED, ""));
}
public static void main(String[] args){
final JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new MainPanel());
frame.pack();
frame.setSize(400, 300);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
Try to use this.setOpaque(false); in constructor.

Detect removal of component

I create a Popup using the PopupFactory.getPopup method. According to the documentation, I am required to call the hide() method on the popup when it is no longer needed.
In my application, the popup is the child of a JLabel which may be removed from the current frame in a number of different situations. (Either the JLabel itself or one of its parent containers is removed.) Rather that calling hide() in every single place (and making the Popup object available in all these places) I would prefer to be able to detect the removal of the JLabel or one of its parent containers.
How can I detect the removal? I naively assumed that the removal of a component meant the removal/hiding of its children, but as the code below shows, the popup survives the removal of the JLabel.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Xyzzy extends JFrame {
static Xyzzy frame;
static JPanel panel;
static JLabel text1;
static JLabel text2;
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
frame = new Xyzzy();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(new BoxLayout(frame.getContentPane(), BoxLayout.PAGE_AXIS));
panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.LINE_AXIS));
frame.add(panel);
text1 = new JLabel("text1");
text2 = new JLabel("text2");
panel.add(text1);
frame.add(new JButton(new AbstractAction("Add popup") {
public void actionPerformed(ActionEvent e) {
PopupFactory factory = PopupFactory.getSharedInstance();
Popup popup = factory.getPopup(text1, new JLabel("POPUP"),frame.getX()+300,frame.getY()+300);
popup.show();
}
}));
frame.add(new JButton(new AbstractAction("New label") {
public void actionPerformed(ActionEvent e) {
panel.remove(text1);
panel.add(text2);
panel.revalidate();
}
}));
frame.setSize(600, 600);
frame.setVisible(true);
}
});
}
}
This code creates a JFrame displaying the text "text1" and two buttons. If you press the button labeled "Add popup", a Popup with the text "POPUP" appears in the window. This Popup is a child of text1. Press the "New label" button and "text1" is removed from the display, but the Popup survives.
I need to be able to detect when text1 or the containing panel is removed so that I can hide the popup. I want to avoid adding code where the actual remove() method is called.
You can use HierarchyListener:
public void actionPerformed(ActionEvent e) {
PopupFactory factory = PopupFactory.getSharedInstance();
final Popup popup = factory.getPopup(text1, new JLabel("POPUP"),frame.getX()+300,frame.getY()+300);
text1.addHierarchyListener(new HierarchyListener() {
public void hierarchyChanged(HierarchyEvent e) {
if (e.getID() == HierarchyEvent.HIERARCHY_CHANGED
&& (e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0) {
popup.hide();
}
}
});
popup.show();
}

Java Swing: How can I implement a login screen before showing a JFrame?

I'm trying to make a little game that will first show the player a simple login screen where they can enter their name (I will need it later to store their game state info), let them pick a difficulty level etc, and will only show the main game screen once the player has clicked the play button. I'd also like to allow the player to navigate to a (hopefully for them rather large) trophy collection, likewise in what will appear to them to be a new screen.
So far I have a main game window with a grid layout and a game in it that works (Yay for me!). Now I want to add the above functionality.
How do I go about doing this? I don't think I want to go the multiple JFrame route as I only want one icon visible in the taskbar at a time (or would setting their visibility to false effect the icon too?) Do I instead make and destroy layouts or panels or something like that?
What are my options? How can I control what content is being displayed? Especially given my newbie skills?
A simple modal dialog such as a JDialog should work well here. The main GUI which will likely be a JFrame can be invisible when the dialog is called, and then set to visible (assuming that the log-on was successful) once the dialog completes. If the dialog is modal, you'll know exactly when the user has closed the dialog as the code will continue right after the line where you call setVisible(true) on the dialog. Note that the GUI held by a JDialog can be every bit as complex and rich as that held by a JFrame.
Another option is to use one GUI/JFrame but swap views (JPanels) in the main GUI via a CardLayout. This could work quite well and is easy to implement. Check out the CardLayout tutorial for more.
Oh, and welcome to stackoverflow.com!
Here is an example of a Login Dialog as #HovercraftFullOfEels suggested.
Username: stackoverflow Password: stackoverflow
import java.awt.*;
import java.awt.event.*;
import java.util.Arrays;
import javax.swing.*;
public class TestFrame extends JFrame {
private PassWordDialog passDialog;
public TestFrame() {
passDialog = new PassWordDialog(this, true);
passDialog.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new TestFrame();
frame.getContentPane().setBackground(Color.BLACK);
frame.setTitle("Logged In");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
}
});
}
}
class PassWordDialog extends JDialog {
private final JLabel jlblUsername = new JLabel("Username");
private final JLabel jlblPassword = new JLabel("Password");
private final JTextField jtfUsername = new JTextField(15);
private final JPasswordField jpfPassword = new JPasswordField();
private final JButton jbtOk = new JButton("Login");
private final JButton jbtCancel = new JButton("Cancel");
private final JLabel jlblStatus = new JLabel(" ");
public PassWordDialog() {
this(null, true);
}
public PassWordDialog(final JFrame parent, boolean modal) {
super(parent, modal);
JPanel p3 = new JPanel(new GridLayout(2, 1));
p3.add(jlblUsername);
p3.add(jlblPassword);
JPanel p4 = new JPanel(new GridLayout(2, 1));
p4.add(jtfUsername);
p4.add(jpfPassword);
JPanel p1 = new JPanel();
p1.add(p3);
p1.add(p4);
JPanel p2 = new JPanel();
p2.add(jbtOk);
p2.add(jbtCancel);
JPanel p5 = new JPanel(new BorderLayout());
p5.add(p2, BorderLayout.CENTER);
p5.add(jlblStatus, BorderLayout.NORTH);
jlblStatus.setForeground(Color.RED);
jlblStatus.setHorizontalAlignment(SwingConstants.CENTER);
setLayout(new BorderLayout());
add(p1, BorderLayout.CENTER);
add(p5, BorderLayout.SOUTH);
pack();
setLocationRelativeTo(null);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
addWindowListener(new WindowAdapter() {
#Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
jbtOk.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (Arrays.equals("stackoverflow".toCharArray(), jpfPassword.getPassword())
&& "stackoverflow".equals(jtfUsername.getText())) {
parent.setVisible(true);
setVisible(false);
} else {
jlblStatus.setText("Invalid username or password");
}
}
});
jbtCancel.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
setVisible(false);
parent.dispose();
System.exit(0);
}
});
}
}
I suggest you insert the following code:
JFrame f = new JFrame();
JTextField text = new JTextField(15); //the 15 sets the size of the text field
JPanel p = new JPanel();
JButton b = new JButton("Login");
f.add(p); //so you can add more stuff to the JFrame
f.setSize(250,150);
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Insert that when you want to add the stuff in. Next we will add all the stuff to the JPanel:
p.add(text);
p.add(b);
Now we add the ActionListeners to make the JButtons to work:
b.addActionListener(this);
public void actionPerforemed(ActionEvent e)
{
//Get the text of the JTextField
String TEXT = text.getText();
}
Don't forget to import the following if you haven't already:
import java.awt.event*;
import java.awt.*; //Just in case we need it
import java.x.swing.*;
I hope everything i said makes sense, because sometimes i don't (especially when I'm talking coding/Java) All the importing (if you didn't know) goes at the top of your code.
Instead of adding the game directly to JFrame, you can add your content to JPanel (let's call it GamePanel) and add this panel to the frame. Do the same thing for login screen: add all content to JPanel (LoginPanel) and add it to frame. When your game will start, you should do the following:
Add LoginPanel to frame
Get user input and load it's details
Add GamePanel and destroy LoginPanel (since it will be quite fast to re-create new one, so you don't need to keep it memory).

Categories

Resources