The first popup would only send one action, the second would send two, third will be three so and so forth. I was able to narrow it down to it being the button sending action multiple time.
At first, I was using jframe for all my window, so I tried using jdialog, the problem persists. tried making it so that when the user clicks on the button the window is disposed, still don't fix it.
public class BoothDetails extends JDialog implements ActionListener{
FloorPlanGUI floorPlan = new FloorPlanGUI();
static JLabel bname = new JLabel();
JTextArea details = new JTextArea();
static JButton addsche = new JButton("ADD TO SCHEDULE");
JPanel northPanel = new JPanel();
public BoothDetails(String name, String detail) {
setVisible(true);
setSize(300, 200);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
bname.setText(name);
details.setText(detail);
setLayout(new BorderLayout());
northPanel.setLayout(new FlowLayout(0, 10, 10));
northPanel.add(bname);
northPanel.add(addsche);
addsche.addActionListener(floorPlan);
addsche.addActionListener(this);
add(northPanel, BorderLayout.NORTH);
add(details, BorderLayout.CENTER);
}
public void actionPerformed(ActionEvent a) {
dispose();
}
}
static JLabel bname = new JLabel();
JTextArea details = new JTextArea();
static JButton addsche = new JButton("ADD TO SCHEDULE");
Don't use the static keyword. This means the variable is shared by all instances of the class.
So every time you create a new instance of the class you execute the following code:
addsche.addActionListener(floorPlan);
which adds another ActionListener to the button.
The static keyword is should generally only be used when you create constant variables in your class, it should NOT be used for components which need to be unique for each class.
Related
In trying to read the text that is entered into a textField, I used the actionlistener for a button right next to it. In this actionlistener class, I had an action performed method in which I created a string that was set equal to the textField.getText();. This class however has a problem recognizing textField variable from the previous class.
It is necessary for the .getText() or reading of the textField entry to be in the actionlistener class. I do not know what to try besides the code that I have listed down below.
public class MainClass {
public static void main(String args[]) {
JFrame frame = new JFrame ("Welcome");
frame.setVisible(true);
frame.setSize(500, 200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
frame.add(panel);
JLabel label = new JLabel("...");
panel.add(label);
JTextField text = new JTextField(20);
panel.add(text);
JButton SubmitButton = new JButton("Analyze");
panel.add(SubmitButton);
SubmitButton.addActionListener(new Action1());
}
static class Action1 implements ActionListener {
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
JFrame frame1 = new JFrame("Word Commonality");
frame1.setVisible(true);
frame1.setSize(500,200);
String ReceivedPath = text.getText();
System.out.println(ReceivedPath);
Error is present at second to bottom line of code. The error is "text cannot be resolved"
I expect that the text can be read and printed out in the console.
Your problem is revolved around function scoping to fix it you need a direct access to the JTextField object you can do so by instantiating a new action performed straight in the MainClass like this:
public class Main {
public static void main(String args[]) {
new MainClass();
}
}
Here I created a class only used to instantiate the window class
For the main class I suggest extending JFrame so you can inherit all of it methods.
//Imports
public class MainClass extends JFrame {
private JPanel panel;
private JLabel label;
private JTextField text;
private JButton SubmitButton;
public MainClass(){
super("Welcome");
setSize(500, 200);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
panel = new JPanel();
add(panel);
label = new JLabel("...");
panel.add(label);
text = new JTextField(20);
panel.add(text);
SubmitButton = new JButton("Analyze");
panel.add(SubmitButton);
SubmitButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String ReceivedPath = text.getText();
System.out.println(ReceivedPath);
}
});
setVisible(true);
}
}
This is how your class should look like.
Side notes:
Set visible is at the end otherwise the items will not be see able.
The MainClass is inheriting from JFrame so it can use all its methods without instatiating it look at inheritance(https://www.w3schools.com/java/java_inheritance.asp)
The action performed now can acces the text JTextField because it is a class attribute.
If the solution is correct please think of marking this answer as final. Thank you
If you place the getText() outside the ActionListener, it will be read immediately after creating the panel. That is why it is empty. You can make the ActionListener assign a value to a variable, but it will be empty until the action is performed.
Also see here: Swing GUI doesn't wait for user input
I'm trying to make a little game that will first show the player a simple login screen where they can enter their name (I will need it later to store their game state info), let them pick a difficulty level etc, and will only show the main game screen once the player has clicked the play button. I'd also like to allow the player to navigate to a (hopefully for them rather large) trophy collection, likewise in what will appear to them to be a new screen.
So far I have a main game window with a grid layout and a game in it that works (Yay for me!). Now I want to add the above functionality.
How do I go about doing this? I don't think I want to go the multiple JFrame route as I only want one icon visible in the taskbar at a time (or would setting their visibility to false effect the icon too?) Do I instead make and destroy layouts or panels or something like that?
What are my options? How can I control what content is being displayed? Especially given my newbie skills?
A simple modal dialog such as a JDialog should work well here. The main GUI which will likely be a JFrame can be invisible when the dialog is called, and then set to visible (assuming that the log-on was successful) once the dialog completes. If the dialog is modal, you'll know exactly when the user has closed the dialog as the code will continue right after the line where you call setVisible(true) on the dialog. Note that the GUI held by a JDialog can be every bit as complex and rich as that held by a JFrame.
Another option is to use one GUI/JFrame but swap views (JPanels) in the main GUI via a CardLayout. This could work quite well and is easy to implement. Check out the CardLayout tutorial for more.
Oh, and welcome to stackoverflow.com!
Here is an example of a Login Dialog as #HovercraftFullOfEels suggested.
Username: stackoverflow Password: stackoverflow
import java.awt.*;
import java.awt.event.*;
import java.util.Arrays;
import javax.swing.*;
public class TestFrame extends JFrame {
private PassWordDialog passDialog;
public TestFrame() {
passDialog = new PassWordDialog(this, true);
passDialog.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new TestFrame();
frame.getContentPane().setBackground(Color.BLACK);
frame.setTitle("Logged In");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
}
});
}
}
class PassWordDialog extends JDialog {
private final JLabel jlblUsername = new JLabel("Username");
private final JLabel jlblPassword = new JLabel("Password");
private final JTextField jtfUsername = new JTextField(15);
private final JPasswordField jpfPassword = new JPasswordField();
private final JButton jbtOk = new JButton("Login");
private final JButton jbtCancel = new JButton("Cancel");
private final JLabel jlblStatus = new JLabel(" ");
public PassWordDialog() {
this(null, true);
}
public PassWordDialog(final JFrame parent, boolean modal) {
super(parent, modal);
JPanel p3 = new JPanel(new GridLayout(2, 1));
p3.add(jlblUsername);
p3.add(jlblPassword);
JPanel p4 = new JPanel(new GridLayout(2, 1));
p4.add(jtfUsername);
p4.add(jpfPassword);
JPanel p1 = new JPanel();
p1.add(p3);
p1.add(p4);
JPanel p2 = new JPanel();
p2.add(jbtOk);
p2.add(jbtCancel);
JPanel p5 = new JPanel(new BorderLayout());
p5.add(p2, BorderLayout.CENTER);
p5.add(jlblStatus, BorderLayout.NORTH);
jlblStatus.setForeground(Color.RED);
jlblStatus.setHorizontalAlignment(SwingConstants.CENTER);
setLayout(new BorderLayout());
add(p1, BorderLayout.CENTER);
add(p5, BorderLayout.SOUTH);
pack();
setLocationRelativeTo(null);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
addWindowListener(new WindowAdapter() {
#Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
jbtOk.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (Arrays.equals("stackoverflow".toCharArray(), jpfPassword.getPassword())
&& "stackoverflow".equals(jtfUsername.getText())) {
parent.setVisible(true);
setVisible(false);
} else {
jlblStatus.setText("Invalid username or password");
}
}
});
jbtCancel.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
setVisible(false);
parent.dispose();
System.exit(0);
}
});
}
}
I suggest you insert the following code:
JFrame f = new JFrame();
JTextField text = new JTextField(15); //the 15 sets the size of the text field
JPanel p = new JPanel();
JButton b = new JButton("Login");
f.add(p); //so you can add more stuff to the JFrame
f.setSize(250,150);
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Insert that when you want to add the stuff in. Next we will add all the stuff to the JPanel:
p.add(text);
p.add(b);
Now we add the ActionListeners to make the JButtons to work:
b.addActionListener(this);
public void actionPerforemed(ActionEvent e)
{
//Get the text of the JTextField
String TEXT = text.getText();
}
Don't forget to import the following if you haven't already:
import java.awt.event*;
import java.awt.*; //Just in case we need it
import java.x.swing.*;
I hope everything i said makes sense, because sometimes i don't (especially when I'm talking coding/Java) All the importing (if you didn't know) goes at the top of your code.
Instead of adding the game directly to JFrame, you can add your content to JPanel (let's call it GamePanel) and add this panel to the frame. Do the same thing for login screen: add all content to JPanel (LoginPanel) and add it to frame. When your game will start, you should do the following:
Add LoginPanel to frame
Get user input and load it's details
Add GamePanel and destroy LoginPanel (since it will be quite fast to re-create new one, so you don't need to keep it memory).
I'm trying to make a simple menu for my game. I have 4 buttons in the center and I want to make them a little bit bigger and center them.
The last part worked but I can't seem to call any of my JButtons and do a .setSize / .setPreferedSize(new Dimension()) on it.
public class mainMenu extends JFrame {
private JButton start, highscore, help, stoppen;
public mainMenu() {
super("Master Mind");
maakComponenten();
maakLayout();
toonFrame();
}
private void maakComponenten() {
start = new JButton("Start");
start.setBackground(Color.gray);
highscore = new JButton("Higscores");
help = new JButton("Help");
stoppen = new JButton("Stoppen");
}
private void maakLayout() {
JPanel hoofdmenu = new JPanel();
hoofdmenu.setLayout(new BoxLayout(hoofdmenu, BoxLayout.Y_AXIS ));
hoofdmenu.add(start);
start.setAlignmentX(CENTER_ALIGNMENT);
hoofdmenu.add(highscore);
highscore.setAlignmentX(CENTER_ALIGNMENT);
hoofdmenu.add(help);
help.setAlignmentX(CENTER_ALIGNMENT);
hoofdmenu.add(stoppen);
stoppen.setAlignmentX(CENTER_ALIGNMENT);
super.add(hoofdmenu);
}
private void toonFrame() {
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setVisible(true);
setSize(500,500);
}
public static void main(String[] args) {
new mainMenu();
}
}
As an example, to change the size of the "Start" button,
change :
start1 = new JButton("Start");
to
start1 = new JButton("Start") {
{
setSize(150, 75);
setMaximumSize(getSize());
}
};
The problem is that JFrames use BorderLayout by default, which means that your JPanel will naturally fill the space.
Before adding your JPanel, call the following code to change the JFrame's layout to null and use the JPanel's settings instead.
this.setLayout(null);
JPanel hoofdmenu = new JPanel();
hoofdmenu.setBounds(0,0, 400, 100);
Alternatively, you could set the maximum size of the JButtons
Dimension maxSize = new Dimension(100, 100);
start.setMaximumSize(maxSize);
highscore.setMaximumSize(maxSize);
help.setMaximumSize(maxSize);
stoppen.setMaximumSize(maxSize);
Here's another example following behind the previous two - I'm making a soundboard program, and this is actually a sample from it - The JPanel actually is needed, agreeing to the second post.
JFrame frame = new JFrame();
JPanel menuPanel = new JPanel();
JButton Button1 = new JButton("<BUTTON NAME 1>");
Button1.setSize(80, 30);
Button1.setLocation(4, 4);
JButton Button2 = new JButton("<BUTTON NAME 2>");
Button2.setSize(80, 30);
Button2.setLocation(90, 4);
Ah, and another thing - You created the buttons in a different block from the second piece of code. Doing that causes the other blocks to not see it. You need to declare them outside the block so all the blocks can see them.
I am new to Java and was trying to develop a basic swing application. I wanted to set the location of the button on the JFrame. I tried to do this but was unable to do this this is my code. I am using eclipse for development
public class MyUI extends JFrame {
JButton button1 = new JButton("Click");
JTextField tb1 = new JTextField(5);
JPanel panel1 = new JPanel();
public MyUI() {
super("Test");
setVisible(true);
this.setLayout(null);
panel1.setLayout(null);
panel1.setVisible(true);
button1.setVisible(true);
panel1.add(button1);
add(panel1);
panel1.setLocation(10, 10);
button1.setLocation(10, 10);
setDefaultCloseOperation(EXIT_ON_CLOSE);
button1.addActionListener(this);
}
public static void main(String[] args) {
MyUI gui = new MyUI();
gui.setSize(400, 300);
}
}
1.why you put two JComponents to the same Bounds
panel1.setLocation(10, 10);
button1.setLocation(10, 10);
2.have look at Initials Thread
3.public class MyUI extends JFrame {
should be
public class MyUI extends JFrame implements ActionListener{
4.don't extend JFrame, create a local variable
5.setVisible(true); should be (in this form) only last code line into MyUI() constructor
6.setVisible(true); is important issue, you visibled JFrame and then to add JComponent(s)
7.don't use NullLayout, use proper LayoutManager, in the case that you remove this.setLayout(null); and panel1.setLayout(null); added JComponents could be visible
8.use pack() before setVisible(true) as last two code lines in constructor
EDIT (by using built_in LayoutManagers, BorderLayout for JFrame and FlowLayout for JPanel)
import java.awt.event.*;
import javax.swing.*;
public class MyUI extends JFrame implements ActionListener {
private static final long serialVersionUID = 1L;
private JButton button1 = new JButton("Click");
private JTextField tb1 = new JTextField(5);
private JPanel panel1 = new JPanel();
public MyUI() {
super("Test");
panel1.add(tb1);
panel1.add(button1);
add(panel1);
setDefaultCloseOperation(EXIT_ON_CLOSE);
button1.addActionListener(this);
pack();
setVisible(true);
}
public void actionPerformed(ActionEvent e) {
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
MyUI testing = new MyUI();
}
});
}
}
Your panel and button are not seen because they have zero size. Add something like:
panel1.setSize(100, 100);
button1.setSize(80, 30);
or use the setBounds method which is more convenient to set location and size simultaneously:
panel1.setBounds(10, 10, 100, 100);
button1.setBounds(10, 10, 80, 30);
Would like to suggest something, though its not the direct immediate answer to your question, but still its important from my point of view....
You can use Group Layout which was developed by NetBeans team back in 2005, its awesome to work with.... Try using the Windows Builder Pro which is provided by Google for free now... You can get your application up and running in no time......
I'm writing a Java programm, according to MVC model.
So the problem is that the Frame doesn't react to button click.
(The text, that I write isn't added to the TextArea after click)
At first I call constructors for View and Controller
MessageFrame mf = new MessageFrame(con);
MessageFrameListener mfl = new MessageFrameListener(mf);
Here is the part of MessageFrameListener class (controller)
public class MessageFrameListener{
private MessageFrame mf;
public MessageFrameListener(MessageFrame m_f){
mf = m_f;
m_f.addButtonListener(new SButtonListener());
}
//#Override
public class SButtonListener implements ActionListener{
public void actionPerformed(ActionEvent e) {
String insert = mf.getInput();
mf.addLine(insert);
mf.refreshInput();
}
}
}
Here is the part from MessageFrame class (View)
public class MessageFrame{
public JTextField messField;
public JTextArea dialogArea;
public JButton sendButton;
public JFrame frame;
public Contact con;
public MessageFrame (Contact con_get) {
con = con_get;
frame = new JFrame();
frame.setSize(538, 299);
JPanel panel_1 = new JPanel();
frame.getContentPane().add(panel_1, BorderLayout.NORTH);
JPanel panel_2 = new JPanel();
frame.getContentPane().add(panel_2, BorderLayout.SOUTH);
panel_2.setLayout(new BoxLayout(panel_2, BoxLayout.X_AXIS));
messField = new JTextField();
panel_2.add(messField);
messField.setColumns(10);
JButton sendButton = new JButton("Send");
panel_2.add(sendButton);
JPanel panel_3 = new JPanel();
frame.getContentPane().add(panel_3, BorderLayout.EAST);
JPanel panel_4 = new JPanel();
frame.getContentPane().add(panel_4, BorderLayout.CENTER);
panel_4.setLayout(new BorderLayout(0, 0));
JTextArea dialogArea = new JTextArea();
panel_4.add(dialogArea);
frame.setVisible(true);
}
public String getInput(){
return messField.getText();
}
public void refreshInput(){
messField.setText("");
}
public void addLine(String line){
dialogArea.append(line);
}
public void addButtonListener(ActionListener bal){
sendButton.addActionListener(bal);
}
}
You will definately find the answer if you check the output of your program or debug it.
Exception in thread "main" java.lang.NullPointerException
at test3.MessageFrame.addButtonListener(Main.java:93)
at test3.MessageFrameListener.<init>(Main.java:28)
at test3.Main.main(Main.java:18)
Your are hiding the reference to the JButton sendButton by declaring it again in the constructor so the field is never initialised.
JButton sendButton = new JButton("Send");
panel_2.add(sendButton);
Since you've posted code scraps and have not posted a functioning SSCCE that we can test, all we can do is guess -- so you'll get what you paid for, and here goes my guess:
You're listening on the wrong MessageFrame. Your program has 2 or more MessageFrame objects, one of which is displayed, and the other which is being listened to, and so your displayed MessageFrame will of never trip the listener.
If this doesn't help, and you need better help, then please provide us with a better question, and an sscce.
You are adding an empty string:
String insert = mf.getInput(); //all it does is: messField.getText();
mf.addLine(insert); //adding the empty string
mf.refreshInput(); //all it does is: messField.setText("");