So I'm revising a random number generator I made a while back and instead of making it in JOptionPane, I decided to try to create it in JFrame. The 2 problems I'm having is:
I can't figure out how to access the number of attempts in class "Easy" to use for class "PlayAgain".
How could I loop back to the beginning of the program and start at the Menu screen again if they decide to click btnPlayAgain? Creating a new instance of Menu does not work the way I want it to, as the Menu frame doesn't close after you choose a difficulty.
The code is for the 3 classes, Menu, Easy, and PlayAgain. I didn't include the code for buttons Medium or Hard as it is pretty much identical to Easy.
Menu
import java.awt.BorderLayout;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JLabel;
import javax.swing.SwingConstants;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
public class Menu extends JFrame {
private JPanel contentPane;
public static Menu frame;
public static Easy eFrame;
public static Medium mFrame;
public static Hard hFrame;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
frame = new Menu();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public Menu() {
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 149);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
JLabel lblSelectADifficulty = new JLabel("Select a difficulty");
lblSelectADifficulty.setBounds(10, 49, 424, 19);
lblSelectADifficulty.setFont(new Font("Tahoma", Font.PLAIN, 15));
lblSelectADifficulty.setHorizontalAlignment(SwingConstants.CENTER);
contentPane.add(lblSelectADifficulty);
JLabel lblRandomNumberGuessing = new JLabel("Random Number Guessing Game");
lblRandomNumberGuessing.setHorizontalAlignment(SwingConstants.CENTER);
lblRandomNumberGuessing.setFont(new Font("Tahoma", Font.PLAIN, 22));
lblRandomNumberGuessing.setBounds(10, 11, 424, 27);
contentPane.add(lblRandomNumberGuessing);
JButton btnEasy = new JButton("Easy (0-100)");
btnEasy.setBounds(10, 79, 134, 23);
contentPane.add(btnEasy);
JButton btnMedium = new JButton("Medium (0-1000)");
btnMedium.setBounds(155, 79, 134, 23);
contentPane.add(btnMedium);
JButton btnHard = new JButton("Hard (0-10000)");
btnHard.setBounds(300, 79, 134, 23);
contentPane.add(btnHard);
btnEasy.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
frame.setVisible(false);
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
eFrame = new Easy();
eFrame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
});
}
}
Easy
import java.awt.BorderLayout;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JLabel;
import javax.swing.SwingConstants;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.JTextField;
import javax.swing.JButton;
public class Easy extends JFrame {
private JPanel contentPane;
private JTextField textField;
private int rand;
public int attempts;
public Easy() {
attempts = 1;
Random rnd = new Random();
rand = rnd.nextInt(100 + 1);
setResizable(false);
setTitle("Take a guess");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 300, 135);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
final JLabel lblGuessANumber = new JLabel("Guess a number between 0 - 100");
lblGuessANumber.setBounds(10, 11, 274, 19);
lblGuessANumber.setFont(new Font("Tahoma", Font.PLAIN, 15));
lblGuessANumber.setHorizontalAlignment(SwingConstants.CENTER);
contentPane.add(lblGuessANumber);
textField = new JTextField();
textField.setBounds(20, 41, 110, 20);
contentPane.add(textField);
textField.setColumns(10);
final JButton btnGuess = new JButton("Guess");
btnGuess.setBounds(164, 41, 110, 20);
contentPane.add(btnGuess);
final JLabel label = new JLabel("");
label.setFont(new Font("Tahoma", Font.PLAIN, 12));
label.setHorizontalAlignment(SwingConstants.CENTER);
label.setBounds(10, 72, 274, 24);
contentPane.add(label);
btnGuess.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if((Integer.parseInt(textField.getText())) >= 0 && (Integer.parseInt(textField.getText())) <= 100){
if((Integer.parseInt(textField.getText())) < rand){
label.setText("You guessed too low.");
System.out.println(rand);
attempts++;
}
else if((Integer.parseInt(textField.getText())) > rand){
label.setText("You guessed too high.");
attempts++;
}
else if((Integer.parseInt(textField.getText())) == rand){
dispose();
PlayAgain pl = new PlayAgain();
pl.setVisible(true);
}
}
else
label.setText("Please enter a valid input.");
}
});
}
public int returnAttempts(){
return attempts;
}
}
PlayAgain
import java.awt.BorderLayout;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JLabel;
import javax.swing.SwingConstants;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
public class PlayAgain extends JFrame {
private JPanel contentPane;
public PlayAgain() {
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 240, 110);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
JLabel lblPlayAgain = new JLabel("Play Again?");
lblPlayAgain.setFont(new Font("Tahoma", Font.PLAIN, 15));
lblPlayAgain.setHorizontalAlignment(SwingConstants.CENTER);
lblPlayAgain.setBounds(10, 27, 214, 23);
contentPane.add(lblPlayAgain);
JButton btnYes = new JButton("Yes");
btnYes.setBounds(10, 49, 89, 23);
contentPane.add(btnYes);
JButton btnQuit = new JButton("Quit");
btnQuit.setBounds(135, 49, 89, 23);
contentPane.add(btnQuit);
//Need to return number of attempts from Easy.java in lblYouGuessedCorrectly
JLabel lblYouGuessedCorrectly = new JLabel("You guessed correctly! Attempts: ");
lblYouGuessedCorrectly.setHorizontalAlignment(SwingConstants.CENTER);
lblYouGuessedCorrectly.setBounds(10, 11, 214, 14);
contentPane.add(lblYouGuessedCorrectly);
btnYes.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//Need to start the program over again, starting with from the Menu screen
}
});
btnQuit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
}
}
Suggestions:
You're creating an event-driven Swing GUI, and so you won't "loop" back to the beginning of your program as you would in a linear console program, because that's not how event driven programs work. Rather you'd simply display the menu view when needed, usually in response to some event such as within the ActionListener of a JButton and/or JMenuItem.
So add a reset JButton or JMenuItem or both, have them share the same ResetAction AbstractAction, and inside of that Action, re-show the menu view.
Side recommendation 1 (not related to your main problem): Don't use null layouts or setBounds as that will lead to rigid hard to debug and enhance GUI's that look good on one platform only.
Side recommendation 2: Don't code towards creation of JFrames but rather JPanel views as this will increase the flexibility of your program greatly, allowing you to swap JPanel views if need be using a CardLayout, or displaying views within a JFrame or JDialog or anywhere else they're needed.
For example using a CardLayout to swap JPanel views and a JOptionPane to get user input on re-starting:
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Font;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Window;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
#SuppressWarnings("serial")
public class Main2 extends JPanel {
private MenuPanel menuPanel = new MenuPanel(this);
private GamePanel gamePanel = new GamePanel(this);
private CardLayout cardLayout = new CardLayout();
public Main2() {
setLayout(cardLayout);
add(menuPanel, MenuPanel.NAME);
add(gamePanel, GamePanel.NAME);
}
public void setDifficulty(Difficulty difficulty) {
gamePanel.setDifficulty(difficulty);
}
public void showCard(String name) {
cardLayout.show(Main2.this, name);
}
private static void createAndShowGui() {
JFrame frame = new JFrame("Main2");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new Main2());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
#SuppressWarnings("serial")
class MenuPanel extends JPanel {
public static final String NAME = "menu panel";
private static final String MAIN_TITLE = "Random Number Guessing Game";
private static final String SUB_TITLE = "Select a difficulty";
private static final int GAP = 3;
private static final float TITLE_SIZE = 20f;
private static final float SUB_TITLE_SIZE = 16;
private Main2 main2;
public MenuPanel(Main2 main2) {
this.main2 = main2;
JLabel titleLabel = new JLabel(MAIN_TITLE, SwingConstants.CENTER);
titleLabel.setFont(titleLabel.getFont().deriveFont(Font.BOLD, TITLE_SIZE));
JPanel titlePanel = new JPanel();
titlePanel.add(titleLabel);
JLabel subTitleLabel = new JLabel(SUB_TITLE, SwingConstants.CENTER);
subTitleLabel.setFont(subTitleLabel.getFont().deriveFont(Font.PLAIN, SUB_TITLE_SIZE));
JPanel subTitlePanel = new JPanel();
subTitlePanel.add(subTitleLabel);
JPanel buttonPanel = new JPanel(new GridLayout(1, 0, GAP, GAP));
for (Difficulty difficulty : Difficulty.values()) {
buttonPanel.add(new JButton(new DifficultyAction(difficulty)));
}
setBorder(BorderFactory.createEmptyBorder(GAP, GAP, GAP, GAP));
setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
add(titlePanel);
add(subTitlePanel);
add(buttonPanel);
}
private class DifficultyAction extends AbstractAction {
private Difficulty difficulty;
public DifficultyAction(Difficulty difficulty) {
this.difficulty = difficulty;
String name = String.format("%s (0-%d)", difficulty.getText(), difficulty.getMaxValue());
putValue(NAME, name);
int mnemonic = (int) name.charAt(0);
putValue(MNEMONIC_KEY, mnemonic);
}
#Override
public void actionPerformed(ActionEvent e) {
main2.setDifficulty(difficulty);
main2.showCard(GamePanel.NAME);
}
}
}
enum Difficulty {
EASY("Easy", 100), MEDIUM("Medium", 1000), HARD("Hard", 10000);
private String text;
private int maxValue;
private Difficulty(String text, int maxValue) {
this.text = text;
this.maxValue = maxValue;
}
public String getText() {
return text;
}
public int getMaxValue() {
return maxValue;
}
}
#SuppressWarnings("serial")
class GamePanel extends JPanel {
public static final String NAME = "game panel";
private String labelText = "Guess a number between 0 - ";
private JLabel label = new JLabel(labelText + Difficulty.HARD.getMaxValue(), SwingConstants.CENTER);
private Main2 main2;
GuessAction guessAction = new GuessAction("Guess");
private JTextField textField = new JTextField(10);
private JButton guessButton = new JButton(guessAction);
private boolean guessCorrect = false;
private Difficulty difficulty;
public GamePanel(Main2 main2) {
this.main2 = main2;
textField.setAction(guessAction);
JPanel guessPanel = new JPanel();
guessPanel.add(textField);
guessPanel.add(Box.createHorizontalStrut(10));
guessPanel.add(guessButton);
JPanel centerPanel = new JPanel(new GridBagLayout());
centerPanel.add(guessPanel);
setLayout(new BorderLayout());
add(label, BorderLayout.PAGE_START);
add(centerPanel, BorderLayout.CENTER);
}
public void setDifficulty(Difficulty difficulty) {
this.difficulty = difficulty;
label.setText(labelText + difficulty.getMaxValue());
}
private class GuessAction extends AbstractAction {
private int attempts = 1;
public GuessAction(String name) {
super(name);
int mnemonic = (int) name.charAt(0);
putValue(MNEMONIC_KEY, mnemonic);
}
#Override
public void actionPerformed(ActionEvent e) {
// TODO use difficulty and all to check guesses, and reply to user
// we'll just show the go back to main menu dialog
guessCorrect = true; // TODO: Delete this later
if (guessCorrect) {
String message = "Attempts: " + attempts + ". Play Again?";
String title = "You've Guessed Correctly!";
int optionType = JOptionPane.YES_NO_OPTION;
int selection = JOptionPane.showConfirmDialog(GamePanel.this, message, title, optionType);
if (selection == JOptionPane.YES_OPTION) {
textField.setText("");
main2.showCard(MenuPanel.NAME);
} else {
Window window = SwingUtilities.getWindowAncestor(GamePanel.this);
window.dispose();
}
}
}
}
}
Related
the JLabel's name is set to an int which changes as the user modifies the number, i tried label.revalidate and Label.repaint after the user changes the int value. i have seen in similar questions people suggest creating a new jlabel everytime, but im wondering if there is a simpler way? the code is very long so i will summerize when needed.
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class officia {
static JFrame Frame;
static JPanel Panel;
static JTextField healthPlace;
static String health="0";
static JButton begin;
static JLabel heart;
static int loop;
public static void main(String[] args) {
Panel = new JPanel();
Frame = new JFrame();
Frame.setSize(500,1000);
Frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Frame.add(Panel);
Panel.setLayout(null);
//adds panel and frame
healthPlace = new JTextField();
healthPlace.setBounds(170, 130, 165, 25);
Panel.add(healthPlace);
begin = new JButton("Begin");
begin.setBounds(217, 185, 70, 25);
Panel.add(begin);
while(loop==1)
loop=0;
heart = new JLabel(health);
heart.setBounds(150, -85, 500, 500);
Panel.add(heart);
Frame.setVisible(true);
//inputs gui's
ActionListener beginPressed = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
health = healthPlace.getText();
loop=1;
}
};
begin.addActionListener(beginPressed);
}
}
You're working in a event driven environment, that is, something happens and you respond to it.
This means, you're while-loop is ill-conceived and is probably the source of your issue. How can the ActionListener for the button be added when the loop is running, but you seem to using the ActionListener to exit the loop...
I modified you code slightly, so when you press the button, it will update the label.
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class officia {
static JFrame Frame;
static JPanel Panel;
static JTextField healthPlace;
static String health = "0";
static JButton begin;
static JLabel heart;
static int loop;
public static void main(String[] args) {
Panel = new JPanel();
Frame = new JFrame();
Frame.setSize(500, 1000);
Frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Frame.add(Panel);
Panel.setLayout(null);
//adds panel and frame
healthPlace = new JTextField();
healthPlace.setBounds(170, 130, 165, 25);
Panel.add(healthPlace);
begin = new JButton("Begin");
begin.setBounds(217, 185, 70, 25);
Panel.add(begin);
// This is ... interesting, but a bad idea
// while (loop == 1) {
// loop = 0;
// }
heart = new JLabel(health);
heart.setBounds(150, -85, 500, 500);
Panel.add(heart);
Frame.setVisible(true);
//inputs gui's
ActionListener beginPressed = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
health = healthPlace.getText();
loop ++;
heart.setText(Integer.toString(loop));
}
};
begin.addActionListener(beginPressed);
}
}
JLabel#setText is what's known as a stateful property, that is, it will trigger an update that will cause it to be painted, so, if it's not updating, you're doing something wrong.
Possible runnable example (of what I think you want to do)
You're working a very rich UI framework. One if it's, many, features, is the layout management framework, something you should seriously take the time to learn to understand and use.
See Laying Out Components Within a Container for more details.
Below is a relatively simple example which shows one way you might "swicth" between views based on a response to a user input
import java.awt.CardLayout;
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
frame.add(new BasePane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class BasePane extends JPanel {
private CardLayout cardLayout;
public BasePane() {
cardLayout = new CardLayout();
setLayout(cardLayout);
StartPane startPane = new StartPane(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
cardLayout.show(BasePane.this, "HeartPane");
}
});
HeartPane heartPane = new HeartPane();
add(startPane, "StartPane");
add(heartPane, "HeartPane");
}
}
public class StartPane extends JPanel {
public StartPane(ActionListener actionListener) {
setBorder(new EmptyBorder(10, 10, 10, 10));
setLayout(new GridBagLayout());
JButton start = new JButton("Begin");
add(start);
start.addActionListener(actionListener);
}
}
public class HeartPane extends JPanel {
private JTextField heartTextField;
private JLabel heartLabel;
public HeartPane() {
setBorder(new EmptyBorder(10, 10, 10, 10));
setLayout(new GridBagLayout());
heartLabel = new JLabel("Heart");
heartTextField = new JTextField(10);
add(heartLabel);
add(heartTextField);
}
}
}
I'm trying to make a traffic light program, changing the foreground colour of JLabel from red to yellow to green, everytime I press JButton (i.e once i press JButton, JLabel turns red, then when i again press JButton it turns yellow and so on). But somehow the colour changes only once to red & nothing happens on further pressing JButton. Any kind of help would be appreciated. Thanks.
import java.awt.Color;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingConstants;
import java.awt.Font;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JTextField;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class traffic {
private JFrame frame;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
traffic window = new traffic();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public traffic() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 798, 512);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);
JLabel lblTrafficLight = new JLabel("Traffic Light");
lblTrafficLight.setFont(new Font("Tahoma", Font.BOLD, 40));
lblTrafficLight.setHorizontalAlignment(SwingConstants.CENTER);
lblTrafficLight.setBounds(190, 11, 403, 61);
frame.getContentPane().add(lblTrafficLight);
JLabel lblRed = new JLabel("RED");
lblRed.setHorizontalAlignment(SwingConstants.CENTER);
lblRed.setFont(new Font("Tahoma", Font.PLAIN, 40));
lblRed.setBounds(273, 125, 249, 61);
frame.getContentPane().add(lblRed);
JButton btnButton = new JButton("Button");
btnButton.setActionCommand("B");
btnButton.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent arg0) {
if(btnButton.getActionCommand().equals("B"))
{
lblRed.setForeground(Color.RED);
}
if(btnButton.getActionCommand().equals("B"))
{
lblRed.setForeground(Color.YELLOW);
}
if(btnButton.getActionCommand().equals("B"))
{
lblRed.setForeground(Color.GREEN);
}
if(btnButton.getActionCommand().equals("B"))
{
lblRed.setForeground(Color.YELLOW);
}
if(btnButton.getActionCommand().equals("B"))
{
lblRed.setForeground(Color.RED);
}
}
});
btnButton.setBounds(353, 346, 89, 23);
frame.getContentPane().add(btnButton);
}
}
You're using the same actionCommand, B for each if block, and so all of the blocks will always run, and the last block will be the one seen.
e.g.,
int x = 1;
if (x == 1) {
// do something
}
if (x == 1) {
// do something else
}
all blocks will be done!
Either change the actionCommands used, or don't use actionCommand String but rather an incrementing int index. Also, don't use MouseListeners for JButtons but rather ActionListeners.
For example:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.util.HashMap;
import java.util.Map;
import javax.swing.*;
public class Traffic2 extends JPanel {
private static final int PREF_W = 400;
private static final int PREF_H = 300;
private static final String[] STRINGS = {"Red", "Blue", "Orange", "Yellow", "Green", "Cyan"};
private Map<String, Color> stringColorMap = new HashMap<>();
private JLabel label = new JLabel("", SwingConstants.CENTER);
private int index = 0;
public Traffic2() {
stringColorMap.put("Red", Color.red);
stringColorMap.put("Blue", Color.blue);
stringColorMap.put("Orange", Color.orange);
stringColorMap.put("Yellow", Color.YELLOW);
stringColorMap.put("Green", Color.GREEN);
stringColorMap.put("Cyan", Color.CYAN);
label.setFont(label.getFont().deriveFont(Font.BOLD, 40f));
String key = STRINGS[index];
label.setText(key);
label.setForeground(stringColorMap.get(key));
JPanel centerPanel = new JPanel(new GridBagLayout());
centerPanel.add(label);
JPanel topPanel = new JPanel();
topPanel.add(new JButton(new AbstractAction("Change Color") {
#Override
public void actionPerformed(ActionEvent e) {
index++;
index %= STRINGS.length;
String key = STRINGS[index];
label.setText(key);
label.setForeground(stringColorMap.get(key));
}
}));
setLayout(new BorderLayout());
add(topPanel, BorderLayout.PAGE_START);
add(centerPanel, BorderLayout.CENTER);
}
#Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
private static void createAndShowGui() {
Traffic2 mainPanel = new Traffic2();
JFrame frame = new JFrame("Traffic2");
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();
}
});
}
}
So what I've got is that I would love to try and make an little login applet. I'm using Java Windowsbuilder for it, to make it easyer for me. I hope the code isn't to messy, because I'm just a starter.
The problem I've got is that My JButton "login" only registers a keyevent when it's selected trought tab, or when you first click it. What I want is that I can use the button always just by pressing the "ENTER" key.
Hope you guys solve my problem :)
import java.awt.BorderLayout;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import org.eclipse.wb.swing.FocusTraversalOnArray;
import java.awt.Component;
import java.awt.event.KeyAdapter;
public class nummer1 extends JFrame{
private JPanel contentPane;
public static nummer1 theFrame;
private JTextField textFieldUsername;
private JTextField textFieldPass;
private nummer1 me;
private JLabel lblCheck;
private String password = "test", username = "test";
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
nummer1 frame = new nummer1();
nummer1.theFrame = frame;
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public void Check(){
String Pass = textFieldPass.getText();
String Username = textFieldUsername.getText();
System.out.println(Pass);
if (Pass.equals(password) && Username.equals(username)){
lblCheck.setText("Correct Login");
}else{
lblCheck.setText("Invalid username or password");
}
}
/**
* Create the frame.
*/
public nummer1() {
me = this;
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 356, 129);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
JLabel lblUsername = new JLabel("Username:");
lblUsername.setBounds(10, 11, 61, 14);
contentPane.add(lblUsername);
JLabel lblPassword = new JLabel("Password:");
lblPassword.setBounds(10, 36, 61, 14);
contentPane.add(lblPassword);
textFieldUsername = new JTextField();
textFieldUsername.setBounds(81, 8, 107, 20);
contentPane.add(textFieldUsername);
textFieldUsername.setColumns(10);
me.textFieldUsername = textFieldUsername;
textFieldPass = new JTextField();
textFieldPass.setBounds(81, 33, 107, 20);
contentPane.add(textFieldPass);
textFieldPass.setColumns(10);
me.textFieldPass = textFieldPass;
JButton btnLogin = new JButton("Login");
contentPane.requestFocusInWindow();
btnLogin.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_ENTER){
me.Check();
System.out.println("hi");
}
}
});
btnLogin.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
me.Check();
}
});
btnLogin.setBounds(198, 7, 89, 23);
contentPane.add(btnLogin);
JLabel lblCheck = new JLabel("");
lblCheck.setHorizontalAlignment(SwingConstants.TRAILING);
lblCheck.setBounds(10, 65, 264, 14);
contentPane.add(lblCheck);
me.lblCheck = lblCheck;
contentPane.setFocusTraversalPolicy(new FocusTraversalOnArray(new
Component[]{lblUsername, lblPassword, textFieldUsername, textFieldPass, btnLogin, lblCheck}));
}
}
Thanks Emil!
What I want is that I can use the button always just by pressing the "ENTER" key
Sounds like you want to make the "login" button the default button for the dialog.
See Enter Key and Button for the problem and solution.
When using panels KeyListeners won't work unless the panel is focusable. What you can do is make a KeyBinding to the ENTER key using the InputMap and ActionMap for your panel.
public class Sample extends JPanel{
//Code
Sample() {
//More code
this.getInputMap().put(KeyStroke.getKeyStroke((char)KeyEvent.VK_ENTER), "Enter" );
this.getActionMap().put("Enter", new EnterAction());
}
private class EnterAction extends AbstractAction(){
#Override
public void ActionPerformed(ActionEvent e){
//Acion
}
}
}
this is the first time I've had a look at JFrames and JPannels and I've come a little stuck.
What I am trying to do is this, I wish to have an starting screen then based on the users button choice it swaps to another screen. To start I have only 2 screens, however once I've moved on there will be multiple screens. I've looked at CardLayout and while that is good it's not the way I wish to go I want to be able to do this first. Here is what I have.
Main.java
import java.awt.BorderLayout;
public class Main extends JFrame {
private JPanel contentPane;
protected boolean someCondition = false;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Main frame = new Main();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public Main() {
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);
if( someCondition == false ){
showTest();
someCondition = test.needToReg();
}else{
showTest2();
}
}
private void showTest(){
contentPane.removeAll();
contentPane.add(new test());
setContentPane(contentPane);
revalidate();
repaint();
}
private void showTest2(){
contentPane.removeAll();
contentPane.add(new test2());
setContentPane(contentPane);
revalidate();
repaint();
}
}
test.java
import javax.swing.JPanel;
public class test extends JPanel {
private JTextField textField;
protected static boolean toReg = false;
/**
* Create the panel.
*/
public test() {
setLayout(null);
JButton btnNewButton = new JButton("New button");
btnNewButton.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
System.out.println("Mouse Clicked");
System.out.println("Before " + toReg);
toReg = true;
System.out.println("After " + toReg);
}
});
btnNewButton.setBounds(188, 166, 89, 23);
add(btnNewButton);
textField = new JTextField();
textField.setBounds(150, 135, 86, 20);
add(textField);
textField.setColumns(10);
JRadioButton rdbtnNewRadioButton = new JRadioButton("New radio button");
rdbtnNewRadioButton.setBounds(6, 166, 109, 23);
add(rdbtnNewRadioButton);
}
public static boolean needToReg(){
return toReg;
}
}
test2.java
import javax.swing.JPanel;
import javax.swing.JButton;
import javax.swing.JLabel;
public class test2 extends JPanel {
/**
* Create the panel.
*/
public test2() {
setLayout(null);
JButton btnNewButton = new JButton("New button");
btnNewButton.setBounds(56, 59, 89, 23);
add(btnNewButton);
JLabel lblNewLabel = new JLabel("New label");
lblNewLabel.setBounds(122, 165, 46, 14);
add(lblNewLabel);
}
}
Running the program with the outputs I included I get this.
Mouse Clicked
Before false
After true
Mouse Clicked
Before true
After true
Mouse Clicked
Before true
After true
Mouse Clicked
Before true
After true
Mouse Clicked
Before true
After true
I hope it's clear what I am trying to do and I hope you can lend a hand with this. Thanks
Try this out
On clicking the screenSwapper button in the main frame a new Panel is added to the main frame that can have multiple components I have added one button only
On second click this panel is removed and second panel is added to the main frame and previous one is removed.
The swapping is carried as you click the button continuously
You may use two singletons if you want to preserve once created panel in case of MyPanel1 and MyPanel2
You may add more components on each panel and test.
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Test extends JFrame {
public boolean switcher;
public JPanel currentPanel;
public JPanel panel1;
public JPanel panel2;
public Test() {
this.switcher = false;
this.currentPanel = null;
this.setSize(200, 200);
panel1 = new JPanel();
JButton screenSwapper = new JButton("Screen Swapper");
panel1.add(screenSwapper);
panel2 = new JPanel();
this.getContentPane().setLayout(new GridLayout(2, 2));
this.getContentPane().add(panel1);
this.getContentPane().add(panel2);
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
screenSwapper.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
if (switcher == false) {
currentPanel = new MyPanel1();
switcher = true;
if (panel2.getComponentCount() != 0) {
panel2.removeAll();
}
} else {
switcher = false;
currentPanel = new MyPanel2();
if (panel2.getComponentCount() != 0) {
panel2.removeAll();
}
}
panel2.add(currentPanel);
panel2.repaint();
panel2.revalidate();
}
});
}
public static void main(String[] args) {
Test t = new Test();
}
}
This is the first panel
import java.awt.BorderLayout;
import java.awt.Button;
import javax.swing.JPanel;
public class MyPanel1 extends JPanel{
public MyPanel1() {
// TODO Auto-generated constructor stub
this.setLayout(new BorderLayout());
this.add(new Button("Button1"));
}
}
This is the second Panel
import java.awt.BorderLayout;
import javax.swing.JButton;
import javax.swing.JPanel;
public class MyPanel2 extends JPanel {
public MyPanel2() {
this.setLayout(new BorderLayout());
this.add(new JButton("button2"));
}
}
package bt;
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.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class login extends javax.swing.JFrame implements ActionListener, javax.swing.RootPaneContainer {
private static final long serialVersionUID = 1L;
private JTextField TUserID=new JTextField(20);
private JPasswordField TPassword=new JPasswordField(20);
protected int role;
public JButton bLogin = new JButton("continue");
private JButton bCancel = new JButton("cancel");
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new login().createAndShowGUI();
}
});
}
public void createAndShowGUI() {
ImageIcon icon = new ImageIcon("");
JLabel l = new JLabel();
JLabel l2 = new JLabel("(2011)");
l2.setFont(new Font("Courier New", Font.BOLD, 10));
l.setIcon(icon);
JLabel LUserID=new JLabel("Your User ID: ");
JLabel LPassword=new JLabel("Your Password: ");
TUserID.addActionListener(this);
TPassword.addActionListener(this);
TUserID.setText("correct");
TPassword.setEchoChar('*');
TPassword.setText("correct");
bLogin.setOpaque(true);
bLogin.addActionListener(this);
bCancel.setOpaque(true);
bCancel.addActionListener(this);
JFrame f = new JFrame("continue");
f.setUndecorated(true);
f.setSize(460,300);
AWTUtilitiesWrapper.setWindowOpaque(f, false);
AWTUtilitiesWrapper.setWindowOpacity(f, ((float) 80) / 100.0f);
Container pane = f.getContentPane();
pane.setLayout(new BoxLayout(pane, BoxLayout.Y_AXIS) );
pane.setBackground(Color.BLACK);
Box box0 = Box.createHorizontalBox();
box0.add(Box.createHorizontalGlue());
box0.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
box0.add(l);
box0.add(Box.createRigidArea(new Dimension(100, 0)));
pane.add(box0);
Box box = Box.createHorizontalBox();
box.add(Box.createHorizontalGlue());
box.setBorder(BorderFactory.createEmptyBorder(10, 20, 20, 100));
box.add(Box.createRigidArea(new Dimension(100, 0)));
box.add(LUserID);
box.add(Box.createRigidArea(new Dimension(32, 0)));
box.add(TUserID);
LUserID.setMaximumSize( LUserID.getPreferredSize() );
TUserID.setMaximumSize( TUserID.getPreferredSize() );
pane.add(box);
Box box2 = Box.createHorizontalBox();
box2.add(Box.createHorizontalGlue());
box2.setBorder(BorderFactory.createEmptyBorder(10, 20, 20, 100));
box2.add(Box.createRigidArea(new Dimension(100, 0)));
box2.add(LPassword,LEFT_ALIGNMENT);
box2.add(Box.createRigidArea(new Dimension(15, 0)));
box2.add(TPassword,LEFT_ALIGNMENT);
LPassword.setMaximumSize( LPassword.getPreferredSize() );
TPassword.setMaximumSize( TPassword.getPreferredSize() );
pane.add(box2);
Box box3 = Box.createHorizontalBox();
box3.add(Box.createHorizontalGlue());
box3.setBorder(BorderFactory.createEmptyBorder(20, 20, 0, 100));
box3.add(bLogin);
box3.add(Box.createRigidArea(new Dimension(10, 0)));
box3.add(bCancel);
pane.add(box3);
f.setLocation(450,300);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setBackground(Color.BLACK);
f.setVisible(true);
}
#Override
public void actionPerformed(ActionEvent evt) {
String TBUsername = TUserID.getText();
Object src = evt.getSource();
char[] CHPassword1 = TPassword.getPassword();
String TBPassword = String.valueOf(CHPassword1);
login mLogin = this;
if (src==bLogin) {
if (authenticate(TBUsername,TBPassword)) {
System.out.println(this);
exitApp(this);
} else {
exitApp(this);
}
} else if (src==bCancel) {
exitApp(mLogin);
}
}
public void exitApp(JFrame mlogin) {
mlogin.setVisible(false);
}
private boolean authenticate(String uname, String pword) {
if ((uname.matches("correct")) && (pword.matches("correct"))) {
new MyJFrame().createAndShowGUI();
return true;
}
return false;
}
}
and MyJFrame.java
package bt;
import java.awt.Color;
import java.awt.Container;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class MyJFrame extends javax.swing.JFrame implements ActionListener {
private static final long serialVersionUID = 2871032446905829035L;
private JButton bExit = new JButton("Exit (For test purposes)");
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new MyJFrame().createAndShowGUI();
}
});
}
public void createAndShowGUI() {
JPanel p = new JPanel();
p.setBackground(Color.black);
ImageIcon icon = new ImageIcon("");
JLabel l = new JLabel("(2011)"); //up to here
l.setIcon(icon);
p.add(l);
p.add(bExit);
bExit.setOpaque(true);
bExit.addActionListener(this);
JFrame f = new JFrame("frame");
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setUndecorated(true);
p.setOpaque(true);
f.getContentPane().add(p);
f.pack();
f.setSize(1000,600);
Container pane=f.getContentPane();
pane.setLayout(new GridLayout(0,1) );
//p.setPreferredSize(200,200);
AWTUtilitiesWrapper.setWindowOpaque(f, false);
AWTUtilitiesWrapper.setWindowOpacity(f, ((float) 90) / 100.0f);
f.setLocation(300,300);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
#Override
public void actionPerformed(ActionEvent evt) {
Object src = evt.getSource();
if (src==bExit) {
System.exit(0);
}
}
}
I cannot get the exitApp() method to work, although it worked before I expanded on my code, I've been trying for hours to get it to work but no avail! The login button suceeds in opening the new frame but will not close the preious(login) frame. It did earlier till I added the validation method etc ....
Create only one JFrame as parent and for another Top-level Containers create only once JDialog (put there JPanel as base), and re-use that for another Action, then you only to remove all JComponents from Base JPanel and add there another JPanel
don't forget for as last lines after switch betweens JPanels inside Base JPanel
revalidate();
repaint();
you can pretty to forgot about that by implements CardLayout