0

I am having trouble implementing JLabel with JFrame. The program needs to show either "Hello" or "World" in the center of the screen when the button "study" is pressed. Also with this being a flashcard program, when study is pressed a word is placed on the middle of the screen and the program is suppose to read from the text field for the user input and print whether it is right or wrong. The problem is that the program is reading the text field after study is pressed so it is printing false before the user can input a answer.

Can someone briefly explain why this is not working and what I can do to fix this issue?

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 javax.swing.JButton;

public class NoteCardGUI implements ActionListener {

public static JFrame frame;
public static JPanel panel;
public static JLabel label;
private NoteCard ex;
private JButton study;

public static Box box1 = new Box(), box2 = new Box(), box3 = new Box();

public NoteCardGUI() {
    ex = new NoteCard("Hello", "World");

    frame = new JFrame("Flash Card");
    panel = new JPanel();

    study = new JButton("Study");


    study.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            String resp = NoteCard.getResponse(ex);
            String chal = NoteCard.getChallenge(ex);
            String a = text.getText();

            label = new JLabel(chal, label.CENTER);
            label.setAlignmentX(0);
            label.setAlignmentY(0);
            frame.add(label, BorderLayout.SOUTH);
            frame.revalidate();

            if(resp.compareTo(a) == 0)
            {
                label = new JLabel("Correct!");
            }
            label = new JLabel("Incorrect");
        }
    });

    panel.add(study);

    frame.add(panel);
    frame.setSize(500, 500);
    frame.setResizable(false);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);

}

public static void main(String[] args) {

    new NoteCardGUI();
}

@Override
public void actionPerformed(ActionEvent e) {
    // TODO Auto-generated method stub

}

}
Ryan Hardin
  • 81
  • 2
  • 3
  • 12

2 Answers2

3

You are adding the label to your frame, but you already have added a JPanel on top of the frame. The solution is to add the label to the panel instead of the frame.

So change: frame.add(label); to panel.add(label);

Shahzad
  • 2,033
  • 1
  • 16
  • 23
  • Actually, it doesn't matter that the panel was added to the frame. It's BorderLayout, so the Label should just "replace" the panel. I think the main problem is that the didn't call `revalidate()`. But I agree that adding the label to a panel rather than to the frame (= to the `BorderLayout`'s center and therefore replacing the panel) is a good idea. – Lukas Rotter Oct 17 '15 at 17:56
  • 1
    @LuxxMiner, `it doesn't matter that the panel was added to the frame.` - Yes is does. The previous component is not replaced. When you use revalidate(), the label will be given a size/location so now two components will be painted. Swing will paint the last component added first, so the label will be painted and the panel will be painted on top of the label. Since a panel is opaque it will cover the label. Check out my answer here: http://stackoverflow.com/questions/30361149/why-does-the-first-panel-added-to-a-frame-disappear/30362786#30362786 for a more complete explanation. – camickr Oct 17 '15 at 19:02
2

By default, a JFrame (or rather, its content pane) has BorderLayout. This means that if you add components to it without specifying a constraint, they will be added at the CENTER. But you can't add more than one element at any of the BorderLayout's regions.

So in order for this to work, you need to add the label somewhere else other than the center, or have the panel added with some other, explicit region.

So if you change the add, for example, to:

frame.add(label, BorderLayout.NORTH);

It will work - but you must not forget to also add:

frame.revalidate();

Whenever you add components to your GUI, you should call this when you've added them all, in order for it to rebuild the hierarchy of components as needed.

Another option would be to change the layout manager of the Frame, or to add to the panel.

RealSkeptic
  • 33,993
  • 7
  • 53
  • 79