I create an Team application in java. I add a logo which is the combination of Rectangle and Circle in JFrame but after add logo in application JTextArea not shown... Also adding new player not shown...
Here is my code.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Rectangle;
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.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextArea;
public class MainGUI extends JFrame
{
private JLabel teamName;
private JLabel playerCount;
private JLabel maxPlayer;
private JButton createTeam;
private JButton addOnePlayer;
private JButton addRemining;
private JButton exit;
private Team team;
private boolean teamCreated;
private JTextArea text;
Logo logo;
public static void main(String[] args)
{
new MainGUI();
}
public MainGUI()
{
super.setTitle("Team manager");
super.setSize(500,400);
super.setLocation(150,150);
super.setLayout(new BorderLayout());
add(addTopPanel(), BorderLayout.NORTH);
add(textArea(), BorderLayout.CENTER);
add(buttonPanel(), BorderLayout.SOUTH);
Logo logo = new Logo();
logo.setBounds(100, 100, 150,150);
getContentPane().add(logo);
// logo.addSquare(10, 10, 100, 100);
super.setVisible(true);
super.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
private JPanel buttonPanel()
{
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new GridLayout(2,2));
createTeam = new JButton("Create Team");
addOnePlayer = new JButton("Add one player");
addRemining = new JButton("Add remaining players");
exit = new JButton("Exit");
buttonPanel.add(createTeam);
buttonPanel.add(addOnePlayer);
buttonPanel.add(addRemining);
buttonPanel.add(exit);
createTeam.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
if(!teamCreated)
{
teamCreated = true;
team = new Team();
teamName.setText("Team name: "+team.getName());
playerCount.setText("Players count: "+team.getCount());
maxPlayer.setText("Max team size: "+team.getSize());
}
else
{
JOptionPane.showMessageDialog(null,"The team has been already created, and no further Team instances are instantiated");
}
}
});
addOnePlayer.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
if(team != null)
{
Player pl = Team.createPlayer();
team.addPlayer(pl);
playerCount.setText("Players count: "+team.getCount());
text.setText(team.toString());
}
else
{
JOptionPane.showMessageDialog(null,"Create a team first ");
}
}
});
addRemining.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
if(team != null)
{
team.addPlayers();
playerCount.setText("Players count: "+team.getCount());
text.setText(team.toString());
}
else
{
JOptionPane.showMessageDialog(null,"Create a team first ");
}
}
});
exit.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
System.exit(1);
}
});
return buttonPanel;
}
private JTextArea textArea()
{
text = new JTextArea();
return text;
}
private JPanel addTopPanel()
{
JPanel top = new JPanel();
top.setLayout(new GridLayout(1,3));
teamName = new JLabel("Team name: ");
playerCount = new JLabel("Players count: ");
maxPlayer = new JLabel("Max team size: ");
top.add(teamName);
top.add(playerCount);
top.add(maxPlayer);
return top;
}
class Logo extends JPanel {
/**
*
*/
private static final long serialVersionUID = 1L;
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.orange);
g.drawRect(350,80,70,70);
g.setColor(Color.blue);
g.drawRoundRect(360, 30, 50, 50, 50, 50);;
}
}
}
after add logo in application JTextArea not shown
Reason is this Line:
logo.setBounds(100, 100, 150,150);
getContentPane().add(logo);
setBounds wont work with the layouts of Swing components. So when you are adding the logo in container of JFrame it is adding it to the center , hiding out the JTextArea added in center.
Related
Everything looks ok to me but for some reason, nothing is showing up properly, maybe I missed something but I'm not sure why it's not working, can someone help me out?
** task **
Improve your program by adding two
combo boxes in the frame. Through the combo boxes, the user should be able to
select their preferred fonts and font sizes. The displayed text will then be updated
accordingly (see the figure below).
Here is what its suppose to look like
import javax.swing.*;
import java.awt.BorderLayout;
import java.awt.Dimension;
import javax.swing.JTextField;
import java.awt.*;
import java.awt.event.*;
public class ComboGUI extends JFrame implements ActionListener {
public JButton update;
public JTextField textField;
public JLabel textLabel;
public JComboBox<String> fontBox;
public JComboBox sizeBox;
public String font;
public String size;
public ComboGUI()
{
components();
panels();
actionListener();
}
public void components()
{
this.update = new JButton("update");
this.textField=new JTextField(20);
this.textField.setText("hello");
this.textLabel= new JLabel("GUI");
this.font="Arial";
this.size="20";
this.textLabel.setFont(new Font(this.font, Font.PLAIN, Integer.parseInt(this.size)));
this.fontBox=new JComboBox();
this.fontBox.addItem("Times New Roman");
this.fontBox.addItem("Calibri");
this.sizeBox= new JComboBox();
this.sizeBox.addItem("20");
this.sizeBox.addItem("30");
this.sizeBox.addItem("40");
this.setSize(400, 400);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLocationRelativeTo(null);
}
public void panels(){
JPanel northPanel =new JPanel();
JLabel fontLabel =new JLabel("Font: ");
JLabel sizeLabel =new JLabel("size: ");
northPanel.add(fontLabel);
//center
BGPanel centerPanel =new BGPanel();
centerPanel.add(this.textLabel);
this.add(centerPanel,BorderLayout.CENTER);
//south
BGPanel southPanel =new BGPanel();
southPanel.add(this.textLabel);
this.add(southPanel,BorderLayout.CENTER);
}
public void actionListener(){
this.update.addActionListener(this);
this.fontBox.addActionListener(this);
this.sizeBox.addActionListener(this);
}
#Override
public void actionPerformed(ActionEvent e){
if(e.getSource()==this.update){
this.textLabel.setText(this.textField.getText());
}
if(e.getSource()==this.fontBox || e.getSource()==this.sizeBox){
this.font=this.fontBox.getSelectedItem().toString();
this.size=this.sizeBox.getSelectedItem().toString();
this.textLabel.setFont(new Font(this.font,Font.PLAIN,Integer.parseInt(this.size)));
}
this.repaint();
}
public static void main(String[] args) {
ComboGUI comb =new ComboGUI();
combo.setVisible(true);
}
}
this is what im getting instead
It looks like you are missing this.setVisible(true); at the end of your constructor.
Your code should look like this:
public ComboGUI()
{
components();
panels();
actionListener();
this.setVisible(true);
}
incase anyone is trying to do something similar, this is the complete solution
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import java.awt.BorderLayout;
import javax.swing.JButton;
import javax.swing.JComboBox;
public class ComboGUI extends JFrame implements ActionListener{
public void updateLabelText(){
size = fSize.getItemAt(fSize.getSelectedIndex());
font = fStyles.getItemAt(fStyles.getSelectedIndex());
updateLabel.setFont(new Font(font,Font.PLAIN,size));
}
public static BGPanel centrePanel;
public JComboBox<String> fStyles;
public JComboBox<Integer> fSize;
public JButton updateButton;
public JLabel updateLabel;
public JLabel fontLabel;
public JLabel sizeLabel;
public JTextField textField;
public JPanel BottomPanel;
public JPanel topPanel;
private String font;
private int size;
public ComboGUI() {
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(400,400);
this.setLocation(0, 0);
//Top
topPanel = new JPanel();
fontLabel = new JLabel("Font:");
sizeLabel = new JLabel("Font Size:");
fStyles = new JComboBox<String>();
fStyles.addItem("Arial");
fStyles.addItem("TimesRoman");
fStyles.addItem("Serif");
fStyles.addItem("Monospaced");
fStyles.addActionListener(this);
fSize = new JComboBox<Integer>();
fSize.addItem(10);
fSize.addItem(20);
fSize.addItem(30);
fSize.addItem(40);
fSize.addActionListener(this);
topPanel.add(fontLabel);
topPanel.add(fStyles);
topPanel.add(sizeLabel);
topPanel.add(fSize);
//CentrePanel setup
centrePanel = new BGPanel();
updateLabel = new JLabel("I love PDC :)");
centrePanel.add(updateLabel);
//Bottom
BottomPanel = new JPanel();
updateButton = new JButton("Update");
textField = new JTextField(20);
textField.setText("I love PDC :)");
updateButton.addActionListener(this);
BottomPanel.add(textField);
BottomPanel.add(updateButton);
this.add(centrePanel,BorderLayout.CENTER);
this.add(BottomPanel,BorderLayout.SOUTH);
this.add(topPanel,BorderLayout.NORTH);
updateLabelText();
}
public static void main(String[] args) {
ComboGUI combo = new ComboGUI();
combo.setVisible(true);
}
#Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == updateButton){
updateLabel.setText(textField.getText().trim());
}
if(e.getSource() == fStyles){
updateLabelText();
}
if (e.getSource() == fSize){
updateLabelText();
}
}
}
I have class Home that extends JFrame, it holds a static variable panel_event. I have another class called EventLabel, which created a label and it's functions and adds it to the panel using refresh() method, code runs with no error, but my panel_event content does not get updated "show"
I have already added revalidate(), and repaint() methods
public EventLabel(String name2, String date2, int priority2, String note2) {
super();
this.name = name2;
this.date = date2;
this.priority = priority2;
this.note = note2;
}
public void buildLabel() {
label = new JLabel(this.getName());
label.setBounds(10, 11, 403, 34);
label.setForeground(Color.WHITE);
label.setFont(new Font("Yu Gothic UI Light", Font.PLAIN, 20));
String n = this.getNote();
String d = this.getDate();
int p = this.getPriority();
String na = this.getName();
setFont(new Font("Yu Gothic UI Light", Font.PLAIN, 20));
label.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
EventDetailFrame detailFrame = new EventDetailFrame();
detailFrame.NewWindow();
detailFrame.textAreaNoteD.setText(n);
detailFrame.textFieldNameD.setText(na);
detailFrame.textFieldDateD.setText(d);
detailFrame.textFieldPriorityD.setText("Priority");
}
});
}
public void refresh(){
panel_event.add(label);
panel_event.revalidate();
panel_event.repaint();
}
This is the frame with button that is suppose to change content of panel_event
btnSaveAndClose.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String name = txtEventName.getText();
String date = txtEventDate.getText();
String note = txtEventNote.getText();
int priority = getPriorityNumber(txtEventPriority.getText());
Event event = new Event(name, date, note, priority);
EventLabel event_label = new EventLabel(event.getName(),event.getDate(),event.getPriority(),event.getNote());
event_label.buildLabel();
event_label.refresh();
dispose();
}
});
After clicking btnSaveAndClose, I expected the panel_event to show my new JLabel
I created a working example on how to show new label. You can call validate() and repaint().
import java.awt.Color;
import java.awt.Font;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.StringJoiner;
import javax.swing.BorderFactory;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
public class EventLabel extends JLabel
{
private static final long serialVersionUID = -3122247523298894551L;
public EventLabel(String name, String date, String priority, String note)
{
super(name);
setBorder(BorderFactory.createLineBorder(Color.WHITE, 3, false));
setFont(new Font("Yu Gothic UI Light", Font.PLAIN, 20));
this.setOpaque(true);
setBackground(Color.WHITE);
addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e)
{
StringJoiner text = new StringJoiner("\n");
text.add("name: " + name);
text.add("date: " + date);
text.add("priority: " + priority);
text.add("note: " + note);
JOptionPane.showMessageDialog(null, text, "Event", JOptionPane.INFORMATION_MESSAGE);
}
});
}
}
AND
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class Main
{
private static JButton button;
private static JPanel labelPanel;
private static JTextField nameField;
private static JTextField dateField;
private static JTextField priorityField;
private static JTextField noteField;
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run()
{
JFrame window = new JFrame();
window.setResizable(false);
window.setTitle("Label Test");
window.getContentPane().add(getContent());
initController();
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setSize(680, 700);
window.setLocationRelativeTo(null);
window.setVisible(true);
}
});
}
protected static void initController()
{
button.addActionListener(event -> {
labelPanel.add(new EventLabel(nameField.getText(), dateField.getText(), priorityField.getText(),
noteField.getText()));
nameField.setText("");
dateField.setText("");
priorityField.setText("");
noteField.setText("");
labelPanel.validate();
labelPanel.repaint();
});
}
private static Component getContent()
{
JPanel panel = new JPanel(new BorderLayout());
panel.add(getNorthPanel(), BorderLayout.NORTH);
labelPanel = new JPanel(new FlowLayout());
labelPanel.setBorder(BorderFactory.createTitledBorder("Events"));
panel.add(labelPanel, BorderLayout.CENTER);
return panel;
}
private static Component getNorthPanel()
{
JPanel panel = new JPanel(new FlowLayout());
JPanel inputPanel = new JPanel(new GridLayout(0, 2));
inputPanel.setPreferredSize(new Dimension(400, 100));
nameField = new JTextField();
dateField = new JTextField();
priorityField = new JTextField();
noteField = new JTextField();
inputPanel.add(new JLabel("name"));
inputPanel.add(nameField);
inputPanel.add(new JLabel("date"));
inputPanel.add(dateField);
inputPanel.add(new JLabel("priority"));
inputPanel.add(priorityField);
inputPanel.add(new JLabel("note"));
inputPanel.add(noteField);
panel.add(inputPanel);
button = new JButton("add event");
panel.add(button);
return panel;
}
}
I have two frames with contents . The first one has a jlabel and jbutton which when it is clicked it will open a new frame. I need to repaint the first frame or the panel that has the label by adding another jlabel to it when the second frame is closed.
//Edited
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class FirstFrame extends JPanel implements KeyListener{
private static String command[];
private static JButton ok;
private static int count = 1;
private static JTextField text;
private static JLabel labels[];
private static JPanel p ;
private static JFrame frame;
public int getCount(){
return count;
}
public static void createWindow(){
JFrame createFrame = new JFrame();
JPanel panel = new JPanel(new GridLayout(2,1));
text = new JTextField (30);
ok = new JButton ("Add");
ok.requestFocusInWindow();
ok.setFocusable(true);
panel.add(text);
panel.add(ok);
text.setFocusable(true);
text.addKeyListener(new FirstFrame());
createFrame.add(panel);
createFrame.setVisible(true);
createFrame.setSize(600,300);
createFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
createFrame.setLocationRelativeTo(null);
createFrame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent windowEvent) {
System.out.println(command[count]);
if(command[count] != null){
p.add(new JLabel("NEW LABEL"));
p.revalidate();
p.repaint();
count++;
System.out.println(count);
}
}
});
if(count >= command.length)
count = 1;
ok.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
if(command[count] == null)
command[count] = text.getText();
else
command[count] = command[count]+", "+text.getText();
text.setText("");
}
});
}
public FirstFrame(){
p = new JPanel();
JButton create = new JButton ("CREATE");
command = new String[2];
labels = new JLabel[2];
addKeyListener(this);
create.setPreferredSize(new Dimension(200,100));
//setLayout(new BorderLayout());
p.add(new JLabel("dsafsaf"));
p.add(create);
add(p);
//JPanel mainPanel = new JPanel();
/*mainPanel.setFocusable(false);
mainPanel.add(create);
*/
create.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
createWindow();
}
});
//add(mainPanel, BorderLayout.SOUTH);
}
public static void main(String[] args) {
frame = new JFrame();
frame.add(new FirstFrame());
frame.setVisible(true);
frame.pack();
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
}
#Override
public void keyReleased(KeyEvent e) {
}
#Override
public void keyTyped(KeyEvent e) {
}
#Override
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_ENTER)
if(ok.isDisplayable()){
ok.doClick();
return;}
}
}
}
});
}
}
As per my first comment, you're better off using a dialog of some type, and likely something as simple as a JOptionPane. For instance in the code below, I create a new JLabel with the text in a JTextField that's held by a JOptionPane, and then add it to the original GUI:
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import javax.swing.*;
#SuppressWarnings("serial")
public class FirstPanel2 extends JPanel {
private static final int PREF_W = 600;
private static final int PREF_H = 300;
private JTextField textField = new JTextField("Hovercraft rules!", 30);
private int count = 0;
public FirstPanel2() {
AddAction addAction = new AddAction();
textField.setAction(addAction);
add(textField);
add(new JButton(addAction));
}
#Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
private class AddAction extends AbstractAction {
public AddAction() {
super("Add");
}
#Override
public void actionPerformed(ActionEvent e) {
String text = textField.getText();
final JTextField someField = new JTextField(text, 10);
JPanel panel = new JPanel();
panel.add(someField);
int result = JOptionPane.showConfirmDialog(FirstPanel2.this, panel, "Add Label",
JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
if (result == JOptionPane.OK_OPTION) {
JLabel label = new JLabel(someField.getText());
FirstPanel2.this.add(label);
FirstPanel2.this.revalidate();
FirstPanel2.this.repaint();
}
}
}
private static void createAndShowGui() {
FirstPanel2 mainPanel = new FirstPanel2();
JFrame frame = new JFrame("My Gui");
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();
}
});
}
}
Also, don't add KeyListeners to text components as that is a dangerous and unnecessary thing to do. Here you're much better off adding an ActionListener, or as in my code above, an Action, so that it will perform an action when the enter key is pressed.
Edit
You ask:
Just realized it is because of the KeyListener. Can you explain please the addAction ?
This is functionally similar to adding an ActionListener to a JTextField, so that when you press enter the actionPerformed(...) method will be called, exactly the same as if you pressed a JButton and activated its ActionListener or Action. An Action is like an "ActionListener" on steroids. It not only behaves as an ActionListener, but it can also give the button its text, its icon and other properties.
I have 2 windows at the moment. After a user clicks on the Submit button, the Main window appears but it appears as such:
The codes are:
LoginForm.java
package interfaceGUI;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.JButton;
import java.awt.Button;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class LoginForm extends JFrame{
private JLabel loginEmail;
private JLabel loginPass;
private JTextField loginTextField;
private JPasswordField loginPassField;
private JButton submit;
private JPanel loginArea;
private JPanel buttonArea;
public LoginForm()
{
super("Party Supplies Rental");
setLayout(new FlowLayout());
loginEmail = new JLabel("Enter Your Email Address: ");
loginTextField = new JTextField(20);
loginPass = new JLabel("Enter Your Password: ");
loginPassField = new JPasswordField(20);
loginArea = new JPanel();
loginArea.setLayout(new GridLayout(2,2));
loginArea.add(loginEmail); //add to the JPanel
loginArea.add(loginTextField);
loginArea.add(loginPass);
loginArea.add(loginPassField);
add(loginArea); //add JPanel to the frame
submit = new JButton("Submit");
buttonArea = new JPanel();
buttonArea.setLayout(new GridLayout(1,2));
buttonArea.add(submit);
add(buttonArea);
ButtonHandler handler= new ButtonHandler();
submit.addActionListener(handler);
}
public class ButtonHandler implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
if(event.getSource() == submit)
{
dispose();
new Main().setVisible(true);
}
}
}
}
And Main.java:
package interfaceGUI;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.JButton;
import java.awt.Button;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Main extends JFrame{
private JLabel label;
private JPanel forLabel;
private JButton birthdayCategory;
private JButton summerCategory;
private JButton halloweenCategory;
private JPanel forCategory;
public Main()
{
super("Home");
setLayout(new FlowLayout());
label = new JLabel("Choose the Party Category");
forLabel = new JPanel();
forLabel.setLayout(new GridLayout(1,3));
forLabel.add(label);
add(forLabel);
birthdayCategory = new JButton("Birthday Party");
summerCategory = new JButton("Summer/Festive Party");
halloweenCategory = new JButton("Halloween Party");
forCategory = new JPanel();
forCategory.setLayout(new GridLayout(1,3));
forCategory.add(birthdayCategory);
forCategory.add(summerCategory);
forCategory.add(halloweenCategory);
add(forCategory);
}
}
The testMain.java:
package interfaceGUI;
import javax.swing.JFrame;
public class testMain {
public static void main(String[] args) {
Main myFrame = new Main();
myFrame.setSize(300,200); //not working
myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
myFrame.setVisible(true);
}
}
Can anybody suggest me what's wrong? Thanks.
I wouldn't call setSize() but rather would let my components and the layout managers set their own sizes by calling pack(). Occasionally you might want to override a component's getPreferredSize() but if you do so, do it with extreme care.
Calling pack() does seem to work for me with your code:
import java.awt.FlowLayout;
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.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class TestMain {
private static void createAndShowGui() {
LoginForm loginForm = new LoginForm();
loginForm.pack();
loginForm.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
class LoginForm extends JFrame {
private JLabel loginEmail;
private JLabel loginPass;
private JTextField loginTextField;
private JPasswordField loginPassField;
private JButton submit;
private JPanel loginArea;
private JPanel buttonArea;
public LoginForm() {
super("Party Supplies Rental");
setLayout(new FlowLayout());
loginEmail = new JLabel("Enter Your Email Address: ");
loginTextField = new JTextField(20);
loginPass = new JLabel("Enter Your Password: ");
loginPassField = new JPasswordField(20);
loginArea = new JPanel();
loginArea.setLayout(new GridLayout(2, 2));
loginArea.add(loginEmail); // add to the JPanel
loginArea.add(loginTextField);
loginArea.add(loginPass);
loginArea.add(loginPassField);
add(loginArea); // add JPanel to the frame
submit = new JButton("Submit");
buttonArea = new JPanel();
buttonArea.setLayout(new GridLayout(1, 2));
buttonArea.add(submit);
add(buttonArea);
ButtonHandler handler = new ButtonHandler();
submit.addActionListener(handler);
}
public class ButtonHandler implements ActionListener {
public void actionPerformed(ActionEvent event) {
if (event.getSource() == submit) {
dispose();
Main main = new Main();
main.pack();
main.setVisible(true);
}
}
}
}
class Main extends JFrame {
private JLabel label;
private JPanel forLabel;
private JButton birthdayCategory;
private JButton summerCategory;
private JButton halloweenCategory;
private JPanel forCategory;
public Main() {
super("Home");
setLayout(new FlowLayout());
label = new JLabel("Choose the Party Category");
forLabel = new JPanel();
forLabel.setLayout(new GridLayout(1, 3));
forLabel.add(label);
add(forLabel);
birthdayCategory = new JButton("Birthday Party");
summerCategory = new JButton("Summer/Festive Party");
halloweenCategory = new JButton("Halloween Party");
forCategory = new JPanel();
forCategory.setLayout(new GridLayout(1, 3));
forCategory.add(birthdayCategory);
forCategory.add(summerCategory);
forCategory.add(halloweenCategory);
add(forCategory);
}
}
Note that if this were my project, I'd change it to use a CardLayout to swap views, something like:
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.*;
#SuppressWarnings("serial")
public class TestMain2 extends JPanel {
private static final String GUI_NAME = "My GUI";
private CardLayout cardLayout = new CardLayout();
private LoginPanel loginPanel = new LoginPanel();
private HomePanel homePanel = new HomePanel();
public TestMain2() {
setLayout(cardLayout);
add(loginPanel, LoginPanel.NAME);
add(homePanel, HomePanel.NAME);
for (PartyCategory partyCategory : PartyCategory.values()) {
PartyPanel partyPanel = new PartyPanel(partyCategory.getName());
partyPanel.addPropertyChangeListener(PartyPanel.RETURN, new PartyPanelListener());
add(partyPanel, partyCategory.getName());
}
loginPanel.addPropertyChangeListener(LoginPanel.NAME, new LoginPanelListener());
homePanel.addPropertyChangeListener(HomePanel.PARTY_CATEGORY, new HomeListener());
}
private class LoginPanelListener implements PropertyChangeListener {
#Override
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getNewValue() == Boolean.TRUE) {
System.out.println("Submit Pressed");
System.out.println("Login: " + loginPanel.getLogin());
// TODO: Dangerous code!!! Delete this!!!
System.out.println("Password: " + new String(loginPanel.getPassword()));
cardLayout.show(TestMain2.this, HomePanel.NAME);
} else {
System.out.println("Cancel Pressed");
}
}
}
private class HomeListener implements PropertyChangeListener {
#Override
public void propertyChange(PropertyChangeEvent evt) {
PartyCategory partyCategory = (PartyCategory) evt.getNewValue();
cardLayout.show(TestMain2.this, partyCategory.getName());
}
}
private class PartyPanelListener implements PropertyChangeListener {
#Override
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getNewValue() == Boolean.TRUE) {
cardLayout.show(TestMain2.this, HomePanel.NAME);
}
}
}
private static void createAndShowGui() {
TestMain2 mainPanel = new TestMain2();
JFrame frame = new JFrame(GUI_NAME);
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();
}
});
}
}
#SuppressWarnings({"serial", "hiding"})
class LoginPanel extends JPanel {
public static final String NAME = "Login";
private static final int COLS = 10;
private static final String EMAIL_PROMPT = "Enter Your Email Address:";
private static final String PASSWORD_PROMPT = "Enter Your Password:";
private boolean submitPressed = false;
private JTextField textField = new JTextField(COLS);
private JPasswordField passField = new JPasswordField(COLS);
public LoginPanel() {
JPanel buttonPanel = new JPanel(new GridLayout(1, 0, 5, 5));
buttonPanel.add(new JButton(new ButtonAction("Submit", KeyEvent.VK_S, true)));
buttonPanel.add(new JButton(new ButtonAction("Cancel", KeyEvent.VK_C, false)));
buttonPanel.add(new JButton(new ExitAction()));
JPanel innerPanel = new JPanel(new GridBagLayout());
innerPanel.setBorder(BorderFactory.createTitledBorder(NAME));
innerPanel.add(new JLabel(EMAIL_PROMPT, JLabel.LEADING), getGbc(0, 0));
innerPanel.add(textField, getGbc(1, 0));
innerPanel.add(new JLabel(PASSWORD_PROMPT, JLabel.LEADING), getGbc(0, 1));
innerPanel.add(passField, getGbc(1, 1));
innerPanel.add(buttonPanel, getGbc(0, 2, 2, 1));
add(innerPanel);
}
public boolean isLoginValid() {
return submitPressed;
}
public void setSubmitPressed(boolean submitPressed) {
this.submitPressed = submitPressed;
firePropertyChange(NAME, null, submitPressed);
}
public String getLogin() {
return textField.getText();
}
public char[] getPassword() {
return passField.getPassword();
}
private class ButtonAction extends AbstractAction {
private boolean submitPressed;
public ButtonAction(String name, int mnemonic, boolean submitPressed) {
super(name);
putValue(MNEMONIC_KEY, mnemonic);
this.submitPressed = submitPressed;
}
#Override
public void actionPerformed(ActionEvent e) {
setSubmitPressed(submitPressed);
}
}
private static GridBagConstraints getGbc(int x, int y, int width, int height) {
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = x;
gbc.gridy = y;
gbc.gridwidth = width;
gbc.gridheight = height;
gbc.weightx = 1.0;
gbc.weighty = 1.0;
if (x == 1) {
gbc.insets = new Insets(5, 15, 5, 5);
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.anchor = GridBagConstraints.EAST;
} else {
gbc.insets = new Insets(5, 5, 5, 5);
gbc.fill = GridBagConstraints.BOTH;
gbc.anchor = GridBagConstraints.WEST;
}
return gbc;
}
private static GridBagConstraints getGbc(int x, int y) {
return getGbc(x, y, 1, 1);
}
}
#SuppressWarnings({"serial", "hiding"})
class HomePanel extends JPanel {
public static final String NAME = "Home";
public static final String PARTY_CATEGORY = "Party Category";
private static final String PROMPT = "Choose Party Category:";
private PartyCategory partyCategory = null;
public HomePanel() {
JPanel buttonPanel = new JPanel(new GridLayout(1, 0, 5, 5));
for (PartyCategory partyCategory : PartyCategory.values()) {
buttonPanel.add(new JButton(new ButtonListener(partyCategory)));
}
add(new JLabel(PROMPT));
add(buttonPanel);
}
public PartyCategory getPartyCategory() {
return partyCategory;
}
public void setPartyCategory(PartyCategory partyCategory) {
this.partyCategory = partyCategory;
firePropertyChange(PARTY_CATEGORY, null, partyCategory);
}
private class ButtonListener extends AbstractAction {
private PartyCategory partyCategory;
public ButtonListener(PartyCategory partyCategory) {
super(partyCategory.getName());
this.partyCategory = partyCategory;
int mnemonic = partyCategory.getName().charAt(0);
putValue(MNEMONIC_KEY, mnemonic);
}
#Override
public void actionPerformed(ActionEvent e) {
setPartyCategory(partyCategory);
}
}
}
enum PartyCategory {
BIRTHDAY_PARTY("Birthday Party"),
SUMMER_FESTIVE_PARTY("Summer/Festive Party"),
HALLOWEEN_PARTY("Halloween Party");
private String name;
private PartyCategory(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
#SuppressWarnings("serial")
class PartyPanel extends JPanel {
public static final String RETURN = "return";
private static final int PREF_W = 400;
private static final int PREF_H = PREF_W;
public PartyPanel(String name) {
JLabel label = new JLabel(name, SwingConstants.CENTER);
label.setFont(label.getFont().deriveFont(Font.BOLD, 48f));
JPanel returnButtonPanel = new JPanel();
returnButtonPanel.add(new JButton(new ReturnAction()));
returnButtonPanel.add(new JButton(new ExitAction()));
setLayout(new BorderLayout());
add(label);
add(returnButtonPanel, BorderLayout.PAGE_END);
}
#Override
public Dimension getPreferredSize() {
Dimension superSize = super.getPreferredSize();
if (isPreferredSizeSet()) {
return superSize;
}
int prefW = Math.max(superSize.width, PREF_W);
int prefH = Math.max(superSize.height, PREF_H);
return new Dimension(prefW, prefH);
}
private class ReturnAction extends AbstractAction {
public ReturnAction() {
super("Return Home");
putValue(MNEMONIC_KEY, KeyEvent.VK_R);
}
#Override
public void actionPerformed(ActionEvent e) {
PartyPanel.this.firePropertyChange(RETURN, null, true);
}
}
}
#SuppressWarnings("serial")
class ExitAction extends AbstractAction {
public ExitAction() {
super("Exit");
putValue(MNEMONIC_KEY, KeyEvent.VK_X);
}
#Override
public void actionPerformed(ActionEvent e) {
// this will not work for JMenuItem which would require a test to see if coming
// from a pop up first.
Component source = (Component) e.getSource();
Window win = SwingUtilities.getWindowAncestor(source);
win.dispose();
}
}
My program will allow the user to log in first and if he is logged in,
he will click on labelone first and labeltwo next.
the program will print ("last two cards detected. starting new game..") and allow the user to click on the two labels again.
the problem I am facing is after my panel has been repainted. I cannot click on the labels
anymore.
I know that my codes provided it too lengthy but I have already attempted to tried to cut down my codes from my actual program.
I think the main focus is this block of codes in my controller class.
labelPanel.removeAll();
Dealer dealer = new Dealer();
labelPanel.add(new LabelPanel(dealer));
labelPanel.revalidate();
labelPanel.repaint();
new Controller(labelPanel,dealer);
I am not sure what happened to my mouselistener. please help
This is are the class. feel free to run it if you guys couldn't understand.
login as username-> john password -> abc
click on label one first, after that click on label two. the console will display
"last 2 cards detected, starting new game.."
after that try clicking the labels again(by right it should be clickable but it's not)
LoginPanel.java
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import javax.swing.border.EtchedBorder;
import javax.swing.border.TitledBorder;
#SuppressWarnings("serial")
public class LoginPanel extends JPanel {
private JPanel northPanel = new JPanel(new BorderLayout());
private JPanel southPanel = new JPanel(new BorderLayout());
private JPanel subSouthPanel = new JPanel(new GridBagLayout());
private JPanel subSouthPanelTwo = new JPanel(new FlowLayout());
private GridBagConstraints gbc2 = new GridBagConstraints();
private JTextField playerUsernameTF = new JTextField(15);
private JPasswordField playerPasswordTF = new JPasswordField(15);
private JButton playerLoginBtn = new JButton("Login");
public LoginPanel() {
setLayout(new BorderLayout());
gbc2.gridx = 0;
gbc2.gridy = 0;
subSouthPanel.add(new JLabel("Username"),gbc2);
gbc2.gridx = 1;
gbc2.gridy = 0;
subSouthPanel.add(playerUsernameTF,gbc2);
gbc2.gridx = 0;
gbc2.gridy = 1;
subSouthPanel.add(new JLabel("Password"),gbc2);
gbc2.gridx = 1;
gbc2.gridy = 1;
subSouthPanel.add(playerPasswordTF,gbc2);
southPanel.add(subSouthPanel,BorderLayout.CENTER);
subSouthPanelTwo.add(playerLoginBtn);
southPanel.add(subSouthPanelTwo,BorderLayout.SOUTH);
add(northPanel,BorderLayout.NORTH);
add(southPanel,BorderLayout.SOUTH);
}
public JTextField getPlayerUsernameTF() {
return playerUsernameTF;
}
public JPasswordField getPlayerPasswordTF() {
return playerPasswordTF;
}
void addListenerForPlayerLoginBtn(ActionListener actionListener) {
playerLoginBtn.addActionListener(actionListener);
}
}
LabelPanel.java
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.MouseListener;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
#SuppressWarnings("serial")
public class LabelPanel extends JPanel {
private JPanel panel = new JPanel(new FlowLayout());
private JLabel labelOne;
private JLabel labelTwo;
public LabelPanel(Dealer dealer) {
setLayout(new BorderLayout());
labelOne = new JLabel(new ImageIcon(dealer.hideCard()));
labelTwo = new JLabel(new ImageIcon(dealer.hideCard()));
panel.add(labelOne);
panel.add(labelTwo);
add(panel);
}
public JLabel getJLabelOne() {
return labelOne;
}
public JLabel getJLabelTwo() {
return labelTwo;
}
void listenerForJLabelOne(MouseListener listenForMouseClick) {
labelOne.addMouseListener(listenForMouseClick);
}
void listenerForJLabelTwo(MouseListener listenForMouseClick) {
labelTwo.addMouseListener(listenForMouseClick);
}
}
Dealer.java
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
public class Dealer {
public Dealer() {
}
public Image hideCard() {
BufferedImage img = null;
try {
img = ImageIO.read(new File("resources/images/blank.png"));
} catch (Exception e) {
}
return img;
}
public Image displayFirsCard() {
BufferedImage img = null;
try {
img = ImageIO.read(new File("resources/images/ClubsAce.png"));
} catch (Exception e) {
}
return img;
}
public Image displaySecondCard() {
BufferedImage img = null;
try {
img = ImageIO.read(new File("resources/images/ClubsAce.png"));
} catch (Exception e) {
}
return img;
}
}
Controller.java
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.Timer;
public class Controller {
private LabelPanel labelPanel;
private Dealer dealer;
private int countdown = 1;
private Timer timer = new Timer(1000,null);
private MouseHandler mouseHandler = new MouseHandler();
private int clicked = 0;
public Controller(LabelPanel labelPanel,Dealer dealer) {
clicked = 0;
this.labelPanel = labelPanel;
this.dealer = dealer;
this.labelPanel.listenerForJLabelOne(mouseHandler);
this.labelPanel.listenerForJLabelTwo(mouseHandler);
this.labelPanel.getJLabelOne().setText("Ace");
this.labelPanel.getJLabelTwo().setText("Ace");
}
private class MouseHandler extends MouseAdapter {
public void mousePressed(MouseEvent e) {
JLabel label = (JLabel) e.getSource();
clicked++;
if(clicked == 1) {
labelPanel.getJLabelOne().setIcon((new ImageIcon(dealer.displayFirsCard())));
}
if(clicked == 2) {
labelPanel.getJLabelTwo().setIcon((new ImageIcon(dealer.displaySecondCard())));;
if(label.getText().equals(label.getText())) {
System.out.println("last 2 cards detected, starting new game..");
timer = new Timer(1000,new newGameTimer());
timer.start();
}
}
}
}
private class newGameTimer implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
if(countdown == 0) {
timer.stop();
clicked = 0;
labelPanel.removeAll();
Dealer dealer = new Dealer();
labelPanel.add(new LabelPanel(dealer));
labelPanel.revalidate();
labelPanel.repaint();
new Controller(labelPanel,dealer);
}
else {
countdown--;
}
}
}
}
MainFrame.java
import java.awt.CardLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class MainFrame {
private CardLayout cardLayout = new CardLayout();
private Dealer dealer = new Dealer();
private JPanel cardLayoutPanel = new JPanel();
private LoginPanel loginPanel = new LoginPanel();
private JFrame frame = new JFrame("Mouse CLick Test");
private JPanel dialogPanel = new JPanel();
private LabelPanel labelPanel = new LabelPanel(dealer);
public MainFrame() {
cardLayoutPanel.setLayout(cardLayout);
cardLayoutPanel.add(loginPanel,"1");
cardLayout.show(cardLayoutPanel,"1");
cardLayoutPanel.add(labelPanel,"2");
frame.add(cardLayoutPanel);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.pack();
frame.setSize(1024,768);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
frame.setResizable(false);
loginPanel.addListenerForPlayerLoginBtn(new PlayerLoginBtnActionPerformed());
}
public class PlayerLoginBtnActionPerformed implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
String playerUsername = loginPanel.getPlayerUsernameTF().getText();
String playerPassword = new String(loginPanel.getPlayerPasswordTF().getPassword());
if(playerUsername.equals("john") && playerPassword.equals("abc")) {
JOptionPane.showMessageDialog(dialogPanel,
"Login Successfully!"
,"Player Login",JOptionPane.PLAIN_MESSAGE);
cardLayout.show(cardLayoutPanel,"2");
new Controller(labelPanel,dealer);
}
else {
JOptionPane.showMessageDialog(dialogPanel,
"Wrong Password or Username!"
,"Error",JOptionPane.ERROR_MESSAGE);
}
}
}
public static void main(String[]args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new MainFrame();
}
});
}
}
The problem is, you are adding a LabelPanel to a LabelPanel
labelPanel.add(new LabelPanel(dealer));
But you are passing the outer panel to the controller
new Controller(labelPanel, dealer);
The outer panel no longer actually contains any labels, but only contains the new LabelPanel...
A better solution would be to provide the LabelPanel with a "reset" option of some kind instead...