I have not yet created a GUI in Java, thus I'm wondering how I can create and use multiple Windows. I want to work with the following Windows:
Splash Screen
Login Window (Create and Load Game)
Main Window
The Main Window contains three buttons:
If Button1 is clicked, then show Window1.
If Button2 is clicked, then show Window2.
If Button3 is clicked, then show Window3.
How can I do this? Thanks for your help.
Just to get you started, here is an example:
private void run() {
JFrame main = createMain();
populateMain(main.getContentPane());
main.setVisible(true);
}
private JFrame createMain() {
JFrame result = new JFrame();
result.setTitle("Main");
result.setSize(400, 300);
result.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
return result;
}
private void populateMain(Container contentPane) {
contentPane.setLayout(new GridLayout(1, 3));
contentPane.add(button1());
contentPane.add(button2());
contentPane.add(button3());
}
private JButton button1() {
JButton result = new JButton("button1");
result.addActionListener(e -> displayWindow1());
return result;
}
private void displayWindow1() {
JFrame frame = new JFrame();
frame.setTitle("Window 1");
frame.setSize(400, 300);
frame.setVisible(true);
}
private JButton button2() {
JButton result = new JButton("button2");
result.addActionListener(e -> displayWindow2());
return result;
}
private void displayWindow2() {
JFrame frame = new JFrame();
frame.setTitle("Window 2");
frame.setSize(400, 300);
frame.setVisible(true);
}
private JButton button3() {
JButton result = new JButton("button3");
result.addActionListener(e -> displayWindow3());
return result;
}
private void displayWindow3() {
JFrame frame = new JFrame();
frame.setTitle("Window 3");
frame.setSize(400, 300);
frame.setVisible(true);
}
When you execute the run() method, this will display the main window. The main window contains three buttons, added by the method populateMain(). When you click any of the three buttons, a new window is created and displayed. You can also click each button multiple times. When you close the main window, the application is terminated. This is because of the following line:
result.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
I hope this helps you to get started. However this is just a simple example using Java's GUI framework called Swing. If you want to create a game you might want to use another GUI framework.
Related
I have first frame containing a button. On pressing the button I invoke actionPerformed() method of different class.
JButton compress = new JButton("Submit");
compress.addActionListener(new Action1(inp,out,frame1)); // inp,out are textboxes and frame1 is 1st frame containing textboxes and JButton
In actionPerformed() of class Action1. I have created another frame there as follows
static class Action1 implements ActionListener {
JTextField input_path,out_path;
JFrame prev;
public Action1(JTextField inp,JTextField out,JFrame jf)
{
input_path = inp;
out_path = out;
prev = jf;
}
public void actionPerformed (ActionEvent e) {
prev.dispose();
try{
drawFrame();
// launch the compression job
launchJob(input_path.getText(),out_path.getText());
}
catch(IOException io){
io.printStackTrace();
}
}
public void drawFrame()
{
JFrame frame2 = new JFrame("New Frame");
JPanel panel = new JPanel();
frame2.setSize(400,300);
frame2.setLocation(500, 300);
JLabel label = new JLabel(" in Progress...");
panel.add(label);
frame2.add(panel);
frame2.setVisible(true);
}
}
But in actionPerformed(), the contents of the frame2 are getting visible after method launchJob() is executed. I want to display(make visible) content of frame2 before my function launchJob() starts executing. Can you plz suggest where im going wrong or some alternative. Thank you.
I have just verified that your frame is being set visible before your method launchJob() is called.
Consider adding some print statements to debug, for example, at the end of the drawFrame() method , add the following code:
frame2.setVisible(true);
System.out.println("frame visible");
Do the same at the start of the launch job method:
System.out.println("doing launch job");
You will see that the output is:
frame visible
doing launch job
This verifies that the JFrame is in fact being made visible before your launch job method.
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).
I am new to java and am getting to the advanced level of it, i have a problem in the GUI Controls, i made a button that when clicked opens up a new window like this:
JButton b = new JButton("Open New Window");
b.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Window w = new Window();
w.setVisible(true);
}
});
this window contains other objects but i have been thinking of making the button in such a way that instead of opening a new JFrame, it opens everything in that same window without opening a new window, honestly i dont know how to do so please could i get some professional help
I think you want a card layout for this situation. Here is some code which should point you in the right direction.
class MyFrame extends JFrame {
public MyFrame() {
JComponent allMyStuff = new JComponent();
JComponent allMyOtherStuff = new JComponent();
this.getContentPane().setLayout(new CardLayout());
this.getContentPane().add(allMyStuff, "1");
this.getContentPane().add(allMyOtherStuff, "2");
CardLayout cl = (CardLayout) (this.getContentPane().getLayout());
cl.show(this.getContentPane(), "1");
JButton b = new JButton("Open New Window"); //add somewhere to first compoonent
b.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
CardLayout cl = (CardLayout) (this.getContentPane().getLayout());
cl.show(this.getContentPane(), "2");
}
});
}
}
I doubt the code runs but generally it holds the idea. You have stuff in one panel, and stuff in another panel, and you just want to switch between the two. The button of course needs to be added in the first panel (allMyStuff) somewhere.
I"m not clear on what it is exactly that you want to show in the GUI when the button is pressed, but perhaps you should consider creating different JPanel "views" and swap these views in the GUI using a CardLayout.
For example, check out these StackOverflow questions and answers:
Java CardLayout Main Menu Problem
Change size of JPanel using CardLayout
Java CardLayout JPanel moves up, when second JPanel added
Java swing; How to toggle panel's visibility?
Clear components of JFrame and add new componets on the same JFrame
gui multiple frames switch
JLabel displaying countdown, java
Within the action listener that you have introduced, you have the possibility to access to instance variables. Therefore you can add further elements to your GUI if you want. I've done a small demo, maybe this is kind of, what you want to do. In order to make your GUI better, you should consider of using layout managers.
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
public class GUI {
JFrame frame;
JButton btn;
JButton compToAdd;
public GUI() {
frame = new JFrame("Testwindow");
frame.setSize(500, 500);
frame.setLayout(null);
btn = new JButton("test btn");
btn.setBounds(20, 20, 200, 200);
btn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
compToAdd = new JButton("new Button");
compToAdd.setBounds(20, 220, 200, 200);
frame.add(compToAdd);
frame.repaint();
}
});
frame.add(btn);
frame.setVisible(true);
}
public static void main(String[] args) {
GUI gui = new GUI();
}
}
I'm following through a book called "The JFC Swing Tutorial (Second Edition)" and I'm pretty much at the start I have followed this code and it should be displaying the button and the label in the content pane, but All im getting is a blank screen. any ideas?
Thanks.
import java.awt.GridLayout;
import javax.swing.*;
public class m extends JFrame
{
void UserFrame()
{
//JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame = new JFrame("Hellow You");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel jp = new JPanel(new GridLayout(0,1));
//makes label
JLabel label = new JLabel("Sup ");
//adds to the frames content pane a label
frame.getContentPane().add(label);
JButton button = new JButton("Hai");
frame.getContentPane().add(button);
jp.add(button);
jp.add(label);
jp.setBorder(BorderFactory.createEmptyBorder(30,30,10,30));
//pack set the window to what it needs AKA to display all components
frame.pack();
//frame.setSize(250, 250);
//shows window
frame.setVisible(true);
}
public static void main(String[] args)
{
final m window = new m();
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
window.UserFrame();
}
});
}
}
Simply add
frame.add(jp);
just before
frame.pack();
What's happening here? You correctly add all your widgets to a JPane, but you basically threw that JPane away and didn't use it anywhere.
This will be sufficient just to get it to work properly.
If you want to do it correctly, you should also remove frame.getContentPane().add(label); and frame.getContentPane().add(button); (Thank you #dic19 for noting that!). These will not work the way you used it.
So im making a game, and i want a jbutton to pop up in the window and when you click it you can log in. the problem is that when i start the game, it doesnt always pop up, which is kind of annoying. the only think would be the problem is the order im doing things. here is the code:
public static void createWindow() {
ImagePanel panel = new ImagePanel(
new ImageIcon(backgroundFile).getImage()); //used for the background
JButton login = new JButton(new AbstractAction("Login") {
public void actionPerformed(ActionEvent e) {
Login.createWindow();
}
});
login.setBounds(300, 300, 100, 100);
frame.getContentPane().add(panel); //sets the background to a pic
frame.setJMenuBar(MenuBar.menuBarCreator()); creates the menu bar
frame.pack();
frame.setResizable(false);
frame.setTitle("*Game Title* Beta 0.0.1 ADMINISTRATOR VERSION");
frame.setSize(ImagePanel.img.getWidth(null),
ImagePanel.img.getHeight(null));
frame.setLocation(Monitor.setLocationHeight(),
Monitor.setLocationWidth());
frame.setVisible(true);
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
StreamingLineSound.start(soundFile); //starts a music file
frame.add(login);
}
any help would be fantastic. so basically all i want is an idea why it doesnt pop up all the time. thanks
Code line frame.setVisible(true); must be last line in the public static void createWindow() {, because you display JFrame and thenafter add frame.add(login);