As an improvement to my encryption project I decided to make a little GUI. However, when I run the program, only the top element shows up on the screen and it appears to obscure the others, though I have no way of checking. Does anyone know why?
Below is my code in its entirety besides e() and d() because those simply encrypt a string and have nothing to do with a GUI. I would also like a way to speed it up as much as possible without editing the encryption, just to make it as great as possbile.
#SuppressWarnings("serial")
public class EncDecExample extends JFrame implements ActionListener {
final static JPanel top = new JPanel();
final static JPanel mid = new JPanel();
final static JPanel bot = new JPanel();
final static JTextField in = new JTextField(10);
final static JTextField out = new JTextField(10);
final static JButton enc = new JButton("Encrypt");
final static JButton dec = new JButton("Decrypt");
final static JFrame f = new JFrame("Encryption/decryption");
public static void main(String[] args) {
// EncDec.exampleImplement();
f.setSize(500, 500);
f.setResizable(false);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
out.setEditable(false);
out.setText("Hello");
in.setVisible(true);
out.setVisible(true);
enc.setVisible(true);
dec.setVisible(true);
top.add(in);
mid.add(enc);
mid.add(dec);
bot.add(out);
f.add(top);
f.add(mid);
f.add(bot);
f.setVisible(true);
}
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == enc && !in.getText().equalsIgnoreCase("")) {
out.setText(EncDec.e(in.getText(), 5));
}
else if(e.getSource() == dec && !in.getText().equalsIgnoreCase("")) {
out.setText(EncDec.d(in.getText()));
}
}
}
The content pane of a JFrame has a BorderLayout. If you place a component in a BL with no constraints it ends up in the CENTER. The center can only display one component.
For an immediate effect, I suggest:
f.add(top, BorderLayout.PAGE_START);
f.add(mid);
f.add(bot, BorderLayout.PAGE_END);
Other points.
Take out f.setSize(500, 500); and call pack() immediately before setVisible(true)
For a better way to end the GUI, change f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); to f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
in.setVisible(true); Except for the frame itself, take these out. A component automatically becomes visible when it is added to a top level container and that container is itself made visible.
Change public class EncDecExample extends JFrame to public class EncDecExample This code keeps a reference to a frame, and that is the right way to go.
Related
As an improvement to my encryption project I decided to make a little GUI. However, when I run the program, only the top element shows up on the screen and it appears to obscure the others, though I have no way of checking. Does anyone know why?
Below is my code in its entirety besides e() and d() because those simply encrypt a string and have nothing to do with a GUI. I would also like a way to speed it up as much as possible without editing the encryption, just to make it as great as possbile.
#SuppressWarnings("serial")
public class EncDecExample extends JFrame implements ActionListener {
final static JPanel top = new JPanel();
final static JPanel mid = new JPanel();
final static JPanel bot = new JPanel();
final static JTextField in = new JTextField(10);
final static JTextField out = new JTextField(10);
final static JButton enc = new JButton("Encrypt");
final static JButton dec = new JButton("Decrypt");
final static JFrame f = new JFrame("Encryption/decryption");
public static void main(String[] args) {
// EncDec.exampleImplement();
f.setSize(500, 500);
f.setResizable(false);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
out.setEditable(false);
out.setText("Hello");
in.setVisible(true);
out.setVisible(true);
enc.setVisible(true);
dec.setVisible(true);
top.add(in);
mid.add(enc);
mid.add(dec);
bot.add(out);
f.add(top);
f.add(mid);
f.add(bot);
f.setVisible(true);
}
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == enc && !in.getText().equalsIgnoreCase("")) {
out.setText(EncDec.e(in.getText(), 5));
}
else if(e.getSource() == dec && !in.getText().equalsIgnoreCase("")) {
out.setText(EncDec.d(in.getText()));
}
}
}
The content pane of a JFrame has a BorderLayout. If you place a component in a BL with no constraints it ends up in the CENTER. The center can only display one component.
For an immediate effect, I suggest:
f.add(top, BorderLayout.PAGE_START);
f.add(mid);
f.add(bot, BorderLayout.PAGE_END);
Other points.
Take out f.setSize(500, 500); and call pack() immediately before setVisible(true)
For a better way to end the GUI, change f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); to f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
in.setVisible(true); Except for the frame itself, take these out. A component automatically becomes visible when it is added to a top level container and that container is itself made visible.
Change public class EncDecExample extends JFrame to public class EncDecExample This code keeps a reference to a frame, and that is the right way to go.
As an improvement to my encryption project I decided to make a little GUI. However, when I run the program, only the top element shows up on the screen and it appears to obscure the others, though I have no way of checking. Does anyone know why?
Below is my code in its entirety besides e() and d() because those simply encrypt a string and have nothing to do with a GUI. I would also like a way to speed it up as much as possible without editing the encryption, just to make it as great as possbile.
#SuppressWarnings("serial")
public class EncDecExample extends JFrame implements ActionListener {
final static JPanel top = new JPanel();
final static JPanel mid = new JPanel();
final static JPanel bot = new JPanel();
final static JTextField in = new JTextField(10);
final static JTextField out = new JTextField(10);
final static JButton enc = new JButton("Encrypt");
final static JButton dec = new JButton("Decrypt");
final static JFrame f = new JFrame("Encryption/decryption");
public static void main(String[] args) {
// EncDec.exampleImplement();
f.setSize(500, 500);
f.setResizable(false);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
out.setEditable(false);
out.setText("Hello");
in.setVisible(true);
out.setVisible(true);
enc.setVisible(true);
dec.setVisible(true);
top.add(in);
mid.add(enc);
mid.add(dec);
bot.add(out);
f.add(top);
f.add(mid);
f.add(bot);
f.setVisible(true);
}
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == enc && !in.getText().equalsIgnoreCase("")) {
out.setText(EncDec.e(in.getText(), 5));
}
else if(e.getSource() == dec && !in.getText().equalsIgnoreCase("")) {
out.setText(EncDec.d(in.getText()));
}
}
}
The content pane of a JFrame has a BorderLayout. If you place a component in a BL with no constraints it ends up in the CENTER. The center can only display one component.
For an immediate effect, I suggest:
f.add(top, BorderLayout.PAGE_START);
f.add(mid);
f.add(bot, BorderLayout.PAGE_END);
Other points.
Take out f.setSize(500, 500); and call pack() immediately before setVisible(true)
For a better way to end the GUI, change f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); to f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
in.setVisible(true); Except for the frame itself, take these out. A component automatically becomes visible when it is added to a top level container and that container is itself made visible.
Change public class EncDecExample extends JFrame to public class EncDecExample This code keeps a reference to a frame, and that is the right way to go.
As an improvement to my encryption project I decided to make a little GUI. However, when I run the program, only the top element shows up on the screen and it appears to obscure the others, though I have no way of checking. Does anyone know why?
Below is my code in its entirety besides e() and d() because those simply encrypt a string and have nothing to do with a GUI. I would also like a way to speed it up as much as possible without editing the encryption, just to make it as great as possbile.
#SuppressWarnings("serial")
public class EncDecExample extends JFrame implements ActionListener {
final static JPanel top = new JPanel();
final static JPanel mid = new JPanel();
final static JPanel bot = new JPanel();
final static JTextField in = new JTextField(10);
final static JTextField out = new JTextField(10);
final static JButton enc = new JButton("Encrypt");
final static JButton dec = new JButton("Decrypt");
final static JFrame f = new JFrame("Encryption/decryption");
public static void main(String[] args) {
// EncDec.exampleImplement();
f.setSize(500, 500);
f.setResizable(false);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
out.setEditable(false);
out.setText("Hello");
in.setVisible(true);
out.setVisible(true);
enc.setVisible(true);
dec.setVisible(true);
top.add(in);
mid.add(enc);
mid.add(dec);
bot.add(out);
f.add(top);
f.add(mid);
f.add(bot);
f.setVisible(true);
}
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == enc && !in.getText().equalsIgnoreCase("")) {
out.setText(EncDec.e(in.getText(), 5));
}
else if(e.getSource() == dec && !in.getText().equalsIgnoreCase("")) {
out.setText(EncDec.d(in.getText()));
}
}
}
The content pane of a JFrame has a BorderLayout. If you place a component in a BL with no constraints it ends up in the CENTER. The center can only display one component.
For an immediate effect, I suggest:
f.add(top, BorderLayout.PAGE_START);
f.add(mid);
f.add(bot, BorderLayout.PAGE_END);
Other points.
Take out f.setSize(500, 500); and call pack() immediately before setVisible(true)
For a better way to end the GUI, change f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); to f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
in.setVisible(true); Except for the frame itself, take these out. A component automatically becomes visible when it is added to a top level container and that container is itself made visible.
Change public class EncDecExample extends JFrame to public class EncDecExample This code keeps a reference to a frame, and that is the right way to go.
public class HandleUI {
public static void setUpUI(){
JPanel jPan = new JPanel();
FlowLayout flow = new FlowLayout();
jPan.setLayout(flow);
txtFld = new JTextField();
txtFld.setSize(550,5);
jPan.add(txtFld);
jPan.setSize(10,200);
MainClass.mainFrame.add(jPan);
int gapX = MainClass.mainFrame.getX()-(txtFld.getX()/2);
}
//Instance variables.
public static JTextField txtFld;
public JButton [] buttons;
}
public class MainClass {
public static void main (String [] args){
int frameX = Constants.FRAME_WIDTH;
int frameY = Constants.FRAME_HEIGHT;
mainFrame = new JFrame();
mainFrame.setSize(frameX,frameY);
mainFrame.setResizable(false);
mainFrame.setVisible(true);
HandleUI.setUpUI();
}
//Instance variables
public static JFrame mainFrame;
}
It's supposed to show JTextField, but as you might have guessed - JFrame shows nothing. I didn't type in imports on purpose, but they are all there. I can't find the problem. Can anyone help?
1.) Simply write:
JTextField tField = new JTextField(10);
Here In the constructor you are passing the number of columns, which is sufficient for a layout like FlowLayout to set the size of the JTextField
2.) The line mainFrame.setVisible(true); must be the last line of the main method. You need to put the code at main() method, inside SwingUtilities.invokeLater(...) thingy.
3.) Instead of setting size on the JFrame use JFrame.pack(), to set the window to the preferred size.
4.) Creation of unnecessary static members is a design flaw. Try to keep yourself away from such thingies.
5.) Read a bit about Concurrency in Swing
One Example Program for help(Use the order of lines as specified in this answer):
import java.awt.*;
import javax.swing.*;
public class Example {
private void displayGUI() {
JFrame frame = new JFrame("Example Demo");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JPanel contentPane = new JPanel();
JTextField tField = new JTextField(10);
contentPane.add(tField);
frame.setContentPane(contentPane);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
Runnable runnable = new Runnable() {
#Override
public void run() {
new Example().displayGUI();
}
};
EventQueue.invokeLater(runnable);
}
}
You have to call setVisible(true) on your JFrame AFTER having initialised your UI.
Simply pulling the following line:
HandleUI.setUpUI();
... right before:
mainFrame.setVisible(true);
... will do the trick.
As a side note, I'd like to point out that setting the size of your text field won't really work like you did. You probably would use setPreferredSize(Dimension) instead. Or, even better, organise your UI only using Layouts and not manually setting any component's size.
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).