So I have a JOptionPane like this in the very beginning of my main method:
JFrame frame = new JFrame("Input");
String progName = JOptionPane.showInputDialog(frame, "Name?");
However, before I can start typing, I need to manually go click on the pop up. Is there any way to make it so that as soon as I run the program, it will automatically "select" the pop up so that when I start typing it will just be in the text box. If this can't be done with a JOptionPane, I am OK with other alternatives, I just need to get a user inputted string with the above constraint in mind.
I have created a simple example in which the logic for asking the user's name is concentrated in a single method. This method is called at the very start of the application and every time you click on a button.
This way, the user is forced to enter the data when the application starts and every time he/she wishes to change the entered value.
public class Jf53136132 extends JFrame {
private static final long serialVersionUID = -3336501835025139522L;
private JPanel contentPane;
public Jf53136132() {
setTitle("Jf53136132");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
contentPane.setLayout(new BorderLayout(0, 0));
setContentPane(contentPane);
JPanel panel = new JPanel();
contentPane.add(panel, BorderLayout.CENTER);
JButton btnInvokeJoptionpane = new JButton("set some text on label");
panel.add(btnInvokeJoptionpane);
JLabel lblx = new JLabel("-x-");
panel.add(lblx);
getNewTextForLabel(lblx);
btnInvokeJoptionpane.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
getNewTextForLabel(lblx);
}
});
}
private void getNewTextForLabel(JLabel label) {
String inputText = JOptionPane.showInputDialog("Enter the text for the label");
System.out.println("you entered <" + inputText + ">");
if (inputText != null && !inputText.trim().isEmpty()) {
label.setText(inputText);
}
}
}
Notice how the method getNewTextForLabel(...) is called as soon as the label is added to the content pane and at every click of the button.
Also, as VGR correctly pointed out, it is a good practice to not run any Swing code inside the main application thread.
You can have a look at the java tutorials for swing (here's a classic example).
The following is some example code that runs the frame on a separate thread.
public class Main {
private static void createAndShowGUI() {
Jf53136132 f = new Jf53136132();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setPreferredSize(new Dimension(640, 480));
f.setLocationRelativeTo(null);
f.setVisible(true);
}
void execute() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
public static void main(String[] args) {
new Main().execute();
}
}
Related
I have two JFrame (JFrame1 and JFrame2) with two JTextField1 and JTextField2. My question is when I write "Hello world " on JTextField2 from Jframe2 and then click on OK button, I see "Hello world " on JTextField1 on Jframe1 class.
How can I do this? I'm sorry if this is a newbie question but I'm learning..
Here is my code:
JFrame2:
private JFrame1 jf1;
private void btn2ActionPerformed(java.awt.event.ActionEvent evt) {
jf1.setjTextField1(this.jTextField2);
}
What you are doing there is actually sending the reference to the actual JTextField from one frame to the other one.
That's probably not a good idea cause both frames would be end up referencing the same visual component.
What you probably want is to keep all visual components separate, but make the text of the second text field equal to the text in the first one.
Something like this:
private void btn2ActionPerformed(java.awt.event.ActionEvent evt) {
jf1.getjTextField1().setText(this.jTextField2.getText());
}
You could use an Observer Pattern or Producer/Consumer Pattern to solve the problem.
The basic idea is, you have something that generates a value and something that either wants to be notified or consume the generated value.
One of the other prinicples you should take the time to learn is also Code to interface (not implementation). This sounds stranger then it is, but the the idea is to reduce the unnecessary exposure of your objects (to unintended/controlled modifications) and decouple your code, so you can change the underlying implementation without affecting any other code which relies on it
Given the nature of your problem, an observer pattern might be more suitable. Most of Swing's listener's are based on the same principle.
We start by defining the contract that the "generator" will use to provide notification of changes...
public interface TextGeneratorObserver {
public void textGenerated(String text);
}
Pretty simple. This means we can safely provide an instance of any object that implements this interface to the generator and know that it won't do anything to our object, because the only thing it knows about is the textGenerated method.
Next, we need something that generates the output we are waiting for...
public class GeneratorPane extends JPanel {
private TextGeneratorObserver observer;
private JTextField field;
private JButton button;
public GeneratorPane(TextGeneratorObserver observer) {
this.observer = observer;
field = new JTextField(10);
button = new JButton("OK");
ActionListener listener = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
observer.textGenerated(field.getText());
}
};
button.addActionListener(listener);
field.addActionListener(listener);
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = GridBagConstraints.REMAINDER;
gbc.insets = new Insets(2, 2, 2, 2);
add(field, gbc);
add(button, gbc);
}
}
This is just a simple JPanel, but it requires you to pass a instance of TextGeneratorObserver to it. When the button (or field) triggers the ActionListener, the ActionListener calls the textGenerated to notify the observer that the text has been generated or changed
Now, we need someone to observer it...
public class ObserverPanel extends JPanel implements TextGeneratorObserver {
private JLabel label;
public ObserverPanel() {
label = new JLabel("...");
add(label);
}
#Override
public void textGenerated(String text) {
label.setText(text);
}
}
This is a simple JPanel which implements the TextGeneratorObserver interface and updates it's JLabel with the new text
Then, we just need to plumb it together
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
ObserverPanel op = new ObserverPanel();
op.setBorder(new CompoundBorder(new LineBorder(Color.RED), new EmptyBorder(10, 10, 10, 10)));
GeneratorPane pp = new GeneratorPane(op);
pp.setBorder(new CompoundBorder(new LineBorder(Color.GREEN), new EmptyBorder(10, 10, 10, 10)));
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridLayout(2, 1));
frame.add(pp);
frame.add(op);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
This is a complete working example I just coded out:
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
class FrameRunner
{
public static void main(String[] args){
MyFrame f1 = new MyFrame("Frame 1");
MyFrame f2 = new MyFrame("Frame 2");
f1.addRef(f2);
f2.addRef(f1);
}
}
class MyFrame extends JFrame{
JTextField txt = new JTextField(8);
JButton btn = new JButton("Send");
MyFrame f = null;
public MyFrame(String title){
super(title);
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
setLayout(new FlowLayout());
setPreferredSize(new Dimension(400, 300));
setVisible(true);
add(btn);
add(txt);
pack();
setLocationRelativeTo(null);
init();
}
public void addRef(MyFrame f){
this.f = f;
}
public void init(){
btn.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
f.update(txt.getText());
}
});
}
public void update(String str){
txt.setText(str);
}
}
In order to make the code short and easier for you to understand. Many of the things I did not following the conventions and I did not modularize the codes. But this should give you a very good idea of how you can pass in the reference of another JFrame.
This code shows an example of how Frame1 has a reference on Frame2. Yet Frame2 also has a reference on Frame1.
Whatever things you type in JFrame1 can be send to JFrame2's textfield. Same for the other way round.
How can i remove lines from a JTextArea one by one instead of all together?
I have a JTextArea which gets appended with string results from a thread, now i would like to remove one line at a time while the thread is executing.
You first need to decide what should trigger the line removal.
Should it be the addition of a new line, so that total line number is constant. If so then you should write your code to call the line removal code in the same location that where a new line is added.
Or should it be at a constant rate -- and if so, then you will want to use a Swing Timer for this.
Then you need to decide which line to remove. If not the first line, then you'll need to figure out how to calculate which line. The javax.swing.text.Utilities class can help you find out the start and finish location of every line of text in your JTextArea.
Edit
You ask:
the main concern is about how to remove it from the JTextArea, i have already calculated the start and end positions of a line that has to be deleted.But what function can assist in removing just that one line?
You would first get the JTextArea's Document by calling, getDocument()
Then you could call remove(int offs, int length) on the Document as per the Document API.
Try This :
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class SwingControlDemo {
String [] m;
int i=0;
String append="";
private JFrame mainFrame;
private JLabel headerLabel;
private JLabel statusLabel;
private JPanel controlPanel;
Timer t;
public SwingControlDemo(){
prepareGUI();
}
public static void main(String[] args){
SwingControlDemo swingControlDemo = new SwingControlDemo();
swingControlDemo.showTextAreaDemo();
}
private void prepareGUI(){
mainFrame = new JFrame("Java Swing Examples");
mainFrame.setSize(400,400);
mainFrame.setLayout(new GridLayout(3, 1));
mainFrame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent windowEvent){
System.exit(0);
}
});
headerLabel = new JLabel("", JLabel.CENTER);
statusLabel = new JLabel("",JLabel.CENTER);
statusLabel.setSize(350,100);
controlPanel = new JPanel();
controlPanel.setLayout(new FlowLayout());
mainFrame.add(headerLabel);
mainFrame.add(controlPanel);
mainFrame.add(statusLabel);
mainFrame.setVisible(true);
}
private void showTextAreaDemo(){
headerLabel.setText("Control in action: JTextArea");
JLabel commentlabel= new JLabel("Comments: ", JLabel.RIGHT);
final JTextArea commentTextArea =
new JTextArea("This is a Swing tutorial "
+"\n to make GUI application in Java."+"\n to make GUI application in Java"+"\n to make GUI application in Java",5,20);
JScrollPane scrollPane = new JScrollPane(commentTextArea);
JButton showButton = new JButton("Show");
showButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String s=commentTextArea.getText();
m=s.split("\n");
t.start();
}
});
t=new Timer(1000,new ActionListener(){
public void actionPerformed(ActionEvent e)
{
i++;
append="";
if(i<=m.length)
{
for(int j=i;j<m.length;j++)
{
append=append+m[j];
}
commentTextArea.setText(append);
}
else
{
t.stop();
}
}});
controlPanel.add(commentlabel);
controlPanel.add(scrollPane);
controlPanel.add(showButton);
mainFrame.setVisible(true);
}
}
I already have a pretty basic Java Swing program but realised that I could do with a simple Username/password login screen to restrict access to it to only people with the username and password.
Is there anyway that I can insert some code to the start of the main method which will prevent execution beyond it until the username and password are entered on a screen that appears?
Here is an example of a Login Dialog. Closes entire program with close of Dialog.
Username: stackoverflow Password: stackoverflow
import java.awt.*;
import java.awt.event.*;
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 ("stackoverflow".equals(String.valueOf(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);
}
});
}
}
This is very tricky to do (as you probably realize), to ensure that someone can't sidestep your authentication.
If you don't care too much if someone can get past it, then an easy way to accomplish what you're trying would be to create a variable tracking login process and don't allow your main thread to start the GUI thread of the main application until the authentication is completed. Something like this would work:
public class MyApp {
private static boolean isAuthenticated;
public static void main( String args[] ) {
isAuthenticated = false;
while( !isAuthenicated ) {
authenticateUser();
try{ Thread.sleep( 200 ); } catch( InterruptedException ie ){ }
}
new JFrame();
// finish rest of GUI code.
}
private static void authenticateUser(){
dialog = new MyAuthenticationDialog();
dialog.show();
if( isValid( dialog.getUsername(), dialog.getPassword() )
isAuthenticated = true;
else
isAuthenticated = false;
}
}
If you care whether this can be reverse engineered however (this example would be trivial for me to RE), then you will need to have some encrypted value that uses the correct username and password as a key. Hash these together into a SHA-256 key and encrypt the value. Note that an RE could still bypass this but it will take more effort, especially if you repeatedly check that you can decrypt the value with the user provided credentials in random spots all through your code. Don't use a single function for it otherwise the RE need only patch that one function and his job is easy. At the end of the day you don't have control over the client so no solution will be perfect. These are some ideas. Also run your final code through a Java obfuscator.
You can use a DialogBox with Swing as soon as you execute your main method. Then, based on the code, you can validate. If the values entered are ok with the authentication data (incoming from db, files, etc), then you show your main UI, if not, maybe you can show a dialog with something like "Try again" or close the dialog.
http://java.about.com/od/UsingDialogBoxes/a/How-To-Make-A-Password-Dialog-Box.htm
Hope it helps, best regards.
I have created a form on which two components are present, button and progressbar (Netbeans drag and drop).Form contains the main method from where my application starts.I have created another class as well in which i have written a function.What i want is that when i press a button the application goes into the function and the progressbar runs simultaneously with it and when that function is complete with its functionality the the progress bar shows 100% complete.Now this function can take anytime for its completion so i cannot set the max value for the progressbar.So, what to do in this case?Can anyone please provide me with a good example .
JProgressBar.setIndeterminate(true)
Since what sort of a work you are doing inside that so called "Called Function", so it's tough to say, what you want in the scenario, though you can put your lines like progressBar.setValue(someProgress); at regular intervals with it's Indeterminate State to true, and at the end of the function you can simply say that progressBar.setValue(100); and the Indeterminate State will turn to false here, so that it can show that to the end user.
Have a look at this sample program :
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class ProgressExample
{
public static JProgressBar progressBar;
private void createAndDisplayGUI()
{
JFrame frame = new JFrame("Progress Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationByPlatform(true);
JPanel contentPane = new JPanel();
contentPane.setLayout(new BorderLayout(5, 5));
progressBar = new JProgressBar(0, 100);
progressBar.setValue(0);
JButton button = new JButton("START");
button.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
progressBar.setIndeterminate(true);
WorkingDialog wd = new WorkingDialog();
wd.createAndDisplayDialog();
}
});
contentPane.add(progressBar, BorderLayout.PAGE_START);
contentPane.add(button, BorderLayout.PAGE_END);
frame.setContentPane(contentPane);
frame.pack();
frame.setVisible(true);
}
public static void main(String... args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new ProgressExample().createAndDisplayGUI();
}
});
}
}
class WorkingDialog extends JDialog
{
private String message = "HelloWorld";
private int count = 0;
private JTextField tfield;
private Timer timer;
private ActionListener timerAction = new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
if (count == 10)
{
timer.stop();
ProgressExample.progressBar.setIndeterminate(false);
ProgressExample.progressBar.setValue(100);
ProgressExample.progressBar.setStringPainted(true);
dispose();
return;
}
tfield.setText(tfield.getText() + message.charAt(count));
count++;
}
};
public void createAndDisplayDialog()
{
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
setLocationByPlatform(true);
JPanel panel = new JPanel();
tfield = new JTextField(10);
panel.add(tfield);
add(panel);
pack();
setVisible(true);
timer = new Timer(1000, timerAction);
timer.start();
}
}
So , it seems like you are write
ProgressExample.progressBar.setIndeterminate(false);
ProgressExample.progressBar.setValue(100);
ProgressExample.progressBar.setStringPainted(true);
after your while loop.
You can take a look at my answer in a previous SO question, which contains a sample using a JProgressBar which gets updates from another Thread by using a SwingWorker. Whether or not to use a SwingWorker depends a bit on your use case. If the function take some time to run you better use the SwingWorker to avoid blocking the UI.
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).