simple GUI not showing up? - java

Ok so, when I run it, it works all fine but it just doesn't pop up with the answer.
What did I do wrong?
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class AF implements ActionListener{
double length;
double width;
double answer;
JTextField twidth;
JTextField tlength;
void AFWindow() {
JFrame AFwindow = new JFrame();
JPanel pan2 = new JPanel(new GridBagLayout());
AFwindow.setVisible(true);
AFwindow.setSize(250, 150);
AFwindow.setResizable(false);
GridBagConstraints c = new GridBagConstraints();
AFwindow.add(pan2);
pan2.setBackground(Color.LIGHT_GRAY);
c.gridx = 0;
c.gridy = 5;
tlength = new JTextField();
tlength.setText(" Length ");
pan2.add(tlength, c);
c.gridx = 0;
c.gridy = 0;
twidth = new JTextField();
twidth.setText(" Width ");
pan2.add(twidth, c);
JButton Find = new JButton("Ok");
c.gridx = 0;
c.gridy = -5;
pan2.add(Find);
Find.addActionListener(this);
Find.setActionCommand("ok");
}
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equalsIgnoreCase("ok")){
try {
this.length = Double.parseDouble(tlength.getText());
this.width = Double.parseDouble(twidth.getText());
}
catch(NumberFormatException ex){
System.out.println("There was an issue!");
}
}
}
int area = (int) (length * width);
public void answer(){
JFrame answer = new JFrame();
answer.setVisible(true);
answer.setBackground(Color.yellow);
JPanel pan2 = new JPanel();
JLabel howanswer = new JLabel("Your answer is" + area + "We got this by multiplying the length and width");
pan2.add(howanswer);
}
}

That code has multiple issues. Forgot to document them, but look at this code for the beginnings of the fixes.
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
public class AF implements ActionListener{
double length;
double width;
JTextField twidth;
JTextField tlength;
JFrame AFwindow;
void AFWindow() {
AFwindow = new JFrame();
JPanel pan2 = new JPanel(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
AFwindow.add(pan2);
pan2.setBackground(Color.LIGHT_GRAY);
pan2.setBorder(new EmptyBorder(100,100,100,100));
c.gridx = 0;
c.gridy = 5;
tlength = new JTextField();
tlength.setText(" Length ");
pan2.add(tlength, c);
c.gridx = 0;
c.gridy = 0;
twidth = new JTextField();
twidth.setText(" Width ");
pan2.add(twidth, c);
JButton Find = new JButton("Ok");
c.gridx = 0;
c.gridy = -5;
pan2.add(Find);
Find.addActionListener(this);
Find.setActionCommand("ok");
AFwindow.pack();
AFwindow.setLocationByPlatform(true);
AFwindow.setVisible(true);
}
int area;
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equalsIgnoreCase("ok")){
try {
this.length = Double.parseDouble(tlength.getText());
this.width = Double.parseDouble(twidth.getText());
area = (int) (length * width);
answer();
}
catch(NumberFormatException ex){
ex.printStackTrace();
// System.out.println("There was an issue!");
// Can you vague that up for me?!?!
JOptionPane.showMessageDialog(AFwindow, ex);
}
}
}
public void answer(){
JPanel pan2 = new JPanel();
JLabel howanswer = new JLabel("Your answer is " + area + " We got this by multiplying the length and width");
pan2.add(howanswer);
JOptionPane.showMessageDialog(AFwindow, pan2);
}
public static void main(String[] args) {
System.out.println("Hi!");
new AF().AFWindow();
}
}

Are you expecting the answer frame to pop up when you push the OK button? If so, you need to call the answer method:
if (e.getActionCommand().equalsIgnoreCase("ok")){
try {
this.length = Double.parseDouble(tlength.getText());
this.width = Double.parseDouble(twidth.getText());
answer(); // <--- This is missing
}
Also, some other things you need to do:
Generally, you should call JFrame.setVisible at the end of your GUI construction method, after you have added components to the frame. I have shown this in the example below, but you should move setVisible(..) to the bottom of the AFwindow() method as well.
When you do int area = (int) (length * width); outside of any method, this statement will be interpreted as an instance variable initialization and occur when you instantiate the AF object. And when the object is instantiated, you have not yet assigned any values to length and with. Hence, area will always be 0. Move that statement to the inside of the answer function instead.
You forgot to add the actual components to the frame in the answer method. Hence, when you set the frame to visible, only an empty frame will be displayed.
Here are examples of some suitable changes:
public void answer(){
int area = (int) (length * width); // <--- Move this inside answer method
JFrame answer = new JFrame();
answer.setBackground(Color.yellow);
JPanel pan2 = new JPanel();
JLabel howanswer = new JLabel("Your answer is" + area + "We got this by multiplying the length and width");
pan2.add(howanswer);
answer.add(pan2); // <--- Don't forget to add your components to the frame
answer.pack(); // <--- Resize the frame to a suitable size
answer.setVisible(true); // <--- Set the frame to visible AFTER you have added the components
}

This code works for me:
public class Test {
public static void main(String[] args){
JFrame test = new JFrame();
test.setVisible(true);
test.setSize(100,100);
test.setResizable(false);
test.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
I assume that you can try to reduce your code and try to find problem point such way. You can put some logging to ensure setVisible(true) was called. Also I recomend to use setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); to terminate thread after exit GUI (if do not want to perform some post-exit actions).

Related

Java JFrame will not update inputted text

I am pretty new to java when compared to python, having only really using it for about 5 months, and up until 2 months ago only using it for android development. I want to learn more about java especially since I basically just skipped strait to the android dev stuff, and learned only what I needed for whatever project I was working on in that. To help me learn, I decided to learn to make a GUI with swing and a simple calculator. I did it in an hour or two, not counting learning swing, and for a very first non-android java program I'm pretty happy with it
the problem i'm having tho, is that when you input 2 numbers, click a button to perform a calculation, then change the numbers and do it again, the program will still use the original numbers, despite them no longer being there
It does read when there are no numbers or a missing number in the input, but just won't use the new numbers for any calculations.
here is the entire program, sorry for the poorly named variables and generally bad code
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class calc implements ActionListener {
private JLabel num1;
private JLabel num2;
private JLabel lans;
private JFrame frame;
private JButton add;
private JButton sub;
private JButton mult;
private JButton div;
private JPanel panel;
private JTextField tnum1;
private JTextField tnum2;
public calc() {
panel = new JPanel();
frame = new JFrame();
frame.setSize(300, 300);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.add(panel);
panel.setLayout(null);
num1 = new JLabel("1st Number");
num1.setBounds(20, 20, 80, 25);
panel.add(num1);
num2 = new JLabel("2nd Number");
num2.setBounds(20, 50, 80, 25);
panel.add(num2);
tnum1 = new JTextField();
tnum1.setBounds(100, 20, 80, 25);
panel.add(tnum1);
tnum2 = new JTextField();
tnum2.setBounds(100, 50, 80, 25);
panel.add(tnum2);
add = new JButton("+");
add.setBounds(20, 100, 50, 40);
add.addActionListener(this);
panel.add(add);
sub = new JButton("-");
sub.setBounds(80, 100, 50, 40);
sub.addActionListener(this);
panel.add(sub);
mult = new JButton("×");
mult.setBounds(140, 100, 50, 40);
mult.addActionListener(this);
panel.add(mult);
div = new JButton("÷");
div.setBounds(200, 100, 50, 40);
div.addActionListener(this);
panel.add(div);
lans = new JLabel("");
lans.setBounds(120, 150, 150, 25);
panel.add(lans);
frame.setVisible(true);
}
public static void main(String[] args) {
new calc();
}
#Override
public void actionPerformed(ActionEvent e) {
if (!tnum1.getText().isEmpty() && !tnum2.getText().isEmpty()) {
String snum1 = tnum1.getText();
String snum2 = tnum1.getText();
Double fnum1 = Double.valueOf(snum1);
Double fnum2 = Double.valueOf(snum2);
if (e.getSource() == add) {
Double nans = fnum1 + fnum2;
lans.setText(String.valueOf(nans));
} else if (e.getSource() == sub) {
Double nans = fnum1 - fnum2;
lans.setText(String.valueOf(nans));
} else if (e.getSource() == mult) {
Double nans = fnum1 * fnum2;
lans.setText(String.valueOf(nans));
} else if (e.getSource() == div) {
Double nans = fnum1 / fnum2;
lans.setText(String.valueOf(nans));
}
} else if (!tnum1.getText().isEmpty()) {
lans.setText("No number 2");
} else if (!tnum2.getText().isEmpty()) {
lans.setText("No number 1");
} else {
lans.setText("enter 2 numbers");
}
}
}
yea I know the variables are a bit confusing, but i'm not super familiar with naming conventions yet and i figured since this was a program that I was only using to learn a few select things I didn't really need to use them, especially since I was not planning on actually posting this anywhere.
Edit: im blind, took the first number twice instead of taking both numbers
so I think I found your problem. The only thing you need to change is this.
int snum1 = Integer.parseInt(tnum1.getText());
int snum2 = Integer.parseInt(tnum2.getText());
This portion should go in the actionPerformed. I think the only problem you had was that you used the first variable two times and not the first and the second to do your math.
I rearranged your code because I wanted to explain a few principles about Swing development.
Here's the GUI I created.
All Swing applications must start with a call to the SwingUtilities invokeLater method. This method call ensures that all Swing components are created and executed on the Event Dispatch Thread.
Absolute positioning of Swing components is painful to do and not conducive to the various operating systems and monitor resolutions that people use. I used a GridBagLayout for the main JPanel and a FlowLayout for the button JPanel. Sure, the code looks more complicated. But I didn't have to calculate any component size or location. The Swing layout managers do this for me.
I added a couple of JFrame methods to give the GUI a title and position it on the screen according to the operating system.
I broke up the GUI creation code into methods, so I could focus on one part of the GUI at a time.
Here's the code.
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
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;
import javax.swing.WindowConstants;
public class SimpleCalculatorGUI implements ActionListener {
private JLabel lans;
private JFrame frame;
private JButton add;
private JButton sub;
private JButton mult;
private JButton div;
private JTextField tnum1;
private JTextField tnum2;
public SimpleCalculatorGUI() {
frame = new JFrame();
frame.setTitle("Calculator");
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.add(createMainPanel());
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JPanel createMainPanel() {
JPanel panel = new JPanel();
panel.setLayout(new GridBagLayout());
panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
GridBagConstraints gbc = new GridBagConstraints();
gbc.anchor = GridBagConstraints.LINE_START;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.insets = new Insets(5, 5, 5, 5);
gbc.gridx = 0;
gbc.gridy = 0;
gbc.weightx = 1d;
JLabel num1 = new JLabel("1st Number");
panel.add(num1, gbc);
gbc.gridx++;
tnum1 = new JTextField(10);
panel.add(tnum1, gbc);
gbc.gridx = 0;
gbc.gridy++;
JLabel num2 = new JLabel("2nd Number");
panel.add(num2, gbc);
gbc.gridx++;
tnum2 = new JTextField(10);
panel.add(tnum2, gbc);
gbc.gridx = 0;
gbc.gridy++;
gbc.gridwidth = 2;
panel.add(createButtonPanel(), gbc);
gbc.gridy++;
lans = new JLabel(" ");
lans.setHorizontalAlignment(JLabel.CENTER);
panel.add(lans, gbc);
return panel;
}
private JPanel createButtonPanel() {
JPanel panel = new JPanel(new FlowLayout());
add = new JButton("+");
add.addActionListener(this);
panel.add(add);
sub = new JButton("-");
sub.addActionListener(this);
panel.add(sub);
mult = new JButton("×");
mult.addActionListener(this);
panel.add(mult);
div = new JButton("÷");
div.addActionListener(this);
panel.add(div);
return panel;
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new SimpleCalculatorGUI();
}
});
}
#Override
public void actionPerformed(ActionEvent e) {
if (!tnum1.getText().isEmpty()
&& !tnum2.getText().isEmpty()) {
String snum1 = tnum1.getText();
String snum2 = tnum2.getText();
Double fnum1 = Double.valueOf(snum1);
Double fnum2 = Double.valueOf(snum2);
if (e.getSource() == add) {
Double nans = fnum1 + fnum2;
lans.setText(String.valueOf(nans));
} else if (e.getSource() == sub) {
Double nans = fnum1 - fnum2;
lans.setText(String.valueOf(nans));
} else if (e.getSource() == mult) {
Double nans = fnum1 * fnum2;
lans.setText(String.valueOf(nans));
} else if (e.getSource() == div) {
Double nans = fnum1 / fnum2;
lans.setText(String.valueOf(nans));
}
} else if (!tnum1.getText().isEmpty()) {
lans.setText("No number 2");
} else if (!tnum2.getText().isEmpty()) {
lans.setText("No number 1");
} else {
lans.setText("Enter 2 numbers");
}
}
}
the problem with your code is that you used tnum1.getText() tow times instead of tnum2.getText()
you just need to change the third line in actionPerformed(e) to String snum2 = tnum2.getText(); and it will work

Which layout should I be using?

I have created a form with 5 buttons using a GridBagLayout to get this form:
What I want is for The buttons to be bigger and more evenly spaced like this:
Here is my code:
package com.GUI;
import java.awt.Color;
import javax.swing.*;
import com.seaglasslookandfeel.*;
public class JFramePlus extends JFrame{
public JFramePlus(){
super("OmegaBrain");
setSize(1000,800);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
getContentPane().setBackground(Color.black);
setResizable(false);
}
}
This is the superclass of the class in question.
package com.GUI;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import java.util.Stack;
class GamePlay extends JFramePlus implements ActionListener{
//Create Stack
Stack sequence = new Stack();
//Declare Variables
String greekSequence;
int stackCount;
int timeLeft;
static int optionNo;
//Create Constraints
GridBagConstraints c = new GridBagConstraints();
//Defining new objects
JLabel timeDisplay, sequenceViewer;
JButton mainMenu, input1, input2, input3, input4, input5;
JPanel timerPane, centerPane, exitPane;
Timer t;
GamePlay(){
//Create Labels
timeDisplay = new JLabel();
sequenceViewer = new JLabel();
//Create Panels
timerPane = new JPanel();
centerPane = new JPanel();
exitPane = new JPanel();
//Change layout of centerPane
centerPane.setLayout(new GridBagLayout());
//Creates JButtons
mainMenu = new JButton("Main Menu");
input1 = new JButton("Ξ");
c.gridx = 0;
c.gridy = 1;
centerPane.add(input1, c);
input2 = new JButton("Ω");
c.gridx = 2;
c.gridy = 1;
centerPane.add(input2, c);
input3 = new JButton("Ψ");
c.gridx = 4;
c.gridy = 1;
centerPane.add(input3, c);
input4 = new JButton("Φ");
c.gridx = 1;
c.gridy = 2;
centerPane.add(input4, c);
input5 = new JButton("Γ");
c.gridx = 3;
c.gridy = 2;
centerPane.add(input5, c);
//Create Timer
t = new Timer(1000, this);
//Changes the size of the font
timeDisplay.setFont(timeDisplay.getFont().deriveFont(64.0f));
//Generate Sequence
sequenceGenerator();
//Add components to panels
timerPane.add(timeDisplay);
centerPane.add(sequenceViewer, c);
exitPane.add(mainMenu);
//add panels to frame
add(timerPane, BorderLayout.LINE_END);
add(centerPane, BorderLayout.CENTER);
add(exitPane, BorderLayout.SOUTH);
//Change colors to fit theme
timeDisplay.setForeground(Color.WHITE);
sequenceViewer.setForeground(Color.WHITE);
timerPane.setBackground(Color.BLACK);
centerPane.setBackground(Color.BLACK);
exitPane.setBackground(Color.BLACK);
//Add ActionListeners to buttons
mainMenu.addActionListener(this);
input1.addActionListener(this);
input2.addActionListener(this);
input3.addActionListener(this);
input4.addActionListener(this);
input5.addActionListener(this);
}
public void sequenceGenerator(){
sequence.push(1 + (int)(Math.random() * optionNo));
stackCount++;
greekSequence = "";
for(int i = 0; i < stackCount; i++){
if (sequence.get(i) == 1){
greekSequence = greekSequence + 'Ξ';
}
}
sequenceViewer.setText(greekSequence);
}
void startTimer() {
t.start();
}
public void actionPerformed(ActionEvent evt) {
Object source = evt.getSource();
if(source == t){
timeDisplay.setText(String.valueOf(timeLeft));
timeLeft--;
if(timeLeft == -1){
t.stop();
}
}
else if(source == mainMenu){
int yesNo = JOptionPane.showConfirmDialog(
null,
"Are you sure you want to exit? Your current score will be saved as it is." ,
"Exit Game?",
JOptionPane.YES_NO_OPTION);
if(yesNo == JOptionPane.YES_OPTION){
dispose();
mainMenu menu = new mainMenu();
}
else{
}
}
}
}
This is a loaded question. I'll start by saying GridBagLayout is just fine for what you're trying to achieve. I think you should invest some time looking into: How to Use GridBagLayout.
You should also look into "Insets" for spacing options, and utilizing gridwidth, gridheight, and maybe even ipadx and ipady when dealing with GridBagConstraints.
You can also use a BoxLayout. (How to use BoxLayout ).
You would be able to position your components as desired and if you want to add space between components, you can add an empty border to your components or put invisible components between them.
You can see this discussion for more information.

Replacing component in panel without it going to the end?

I am working on a program that has no errors when I compile, and the logic runs soundly for it's purpose (I'm making a basic Penny Pitch program in GUI). The board is filled with image icons that contain the number of points a player will receive if they land on it, and when they land on a spot the image icon is suppose to switch to a picture of the same spot with a penny on it. However, when the previous icon is removed and the new "occupied" one is assigned, it is assigned at the end of the panel rather than the previous spot the "empty" icon was taken from.
To illustrate:
this is the normal layout,
before "tossing" a penny,
and this is the shifted layout,
after "tossing" a penny.
I can't find any sources explaining how to add a component to a panel in a spot previously occupied by a removed component. If anyone knows how, it would be great help!
-----------------------------------EDIT-----------------------------------------
New pictures:,.
I'm using a GridBagLayout now, and since I'm still not sure what is the cause of the new added component not taking the space of the removed one, I cut down my entire program to illustrate it's aspects:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
public class PennyPitch extends JFrame implements ItemListener{
//variables
int aa=0, thrown=0, place=0, illit=1, illit2=1;
Random pitch = new Random();
private ImageIcon full = new ImageIcon("pitchFull.png");
//map
private Map tossing;
//jbuttons
private JButton confirm = new JButton (new ImageIcon("pitchPenny.png"));
//map
private Map<Integer, ColorPanel> spot = new HashMap<Integer, ColorPanel>();
//declared icon to use when button is pushed
private ColorPanel rSet = new ColorPanel(Color.white, full);
//panel
private JPanel input = new JPanel(new GridBagLayout ());
private GridBagConstraints c = new GridBagConstraints();
public PennyPitch(){
prepareGUI();
}
public static void main(String[] args){
PennyPitch pitch = new PennyPitch(); }
private void prepareGUI(){
//background
input.setBackground(Color.WHITE);
//button design
confirm.setBorder(BorderFactory.createEmptyBorder());
confirm.setContentAreaFilled(false);
//icon for use
ImageIcon one = new ImageIcon("pitchOne.png");
//components for map
ColorPanel i1 = new ColorPanel(Color.white, one);
ColorPanel i2 = new ColorPanel(Color.white, one);
ColorPanel i3 = new ColorPanel(Color.white, one);
//MAP FOR THE STATS
spot.put(1, i1);
spot.put(2, i2);
spot.put(3, i3);
//PANEL
c.ipady = 50;
c.ipadx = 50;
c.gridx = 1;
c.gridy = 1;
c.gridwidth = 1;
input.add(spot.get(1),c);
c.ipady = 50;
c.ipadx = 50;
c.gridx = 2;
c.gridy = 1;
c.gridwidth = 1;
input.add(spot.get(2),c);
c.ipady = 50;
c.ipadx = 50;
c.gridx = 3;
c.gridy = 1;
c.gridwidth = 1;
input.add(spot.get(3),c);
c.ipady = 50;
c.ipadx = 50;
c.gridx = 4;
c.gridy = 1;
c.gridwidth = 2;
input.add(confirm,c);
//listener for button
confirm.addActionListener (new AddListener());
//CONTAINER
Container container = getContentPane();
container.add(input);
//frame information
Toolkit tk = Toolkit.getDefaultToolkit();
setSize(600, 600);
setTitle("PENNY PITCH");
setMinimumSize(new Dimension(600,600));
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack ();
setVisible(true);
}
private class AddListener implements ActionListener {
public void actionPerformed(ActionEvent a){
if (a.getSource()== confirm) {
//generates number to land on
thrown = pitch.nextInt(3) + 1;
System.out.println(thrown);
place=illit;
spot.put(place, rSet);
Component old = input.getComponent(thrown);
Component newn = input.getComponent(place);
Component[] compSet=input.getComponents();
for(int i=0; i<compSet.length; i++){
if(old.equals(compSet[i])) {
input.remove(old);
c.ipady = 50;
c.ipadx = 50;
c.gridwidth = 1;
input.add(newn, i);
}
}
illit++;
repaint();
}
}
}
public void itemStateChanged(ItemEvent e) {
System.out.println (aa);
}
}
class ImageLabel extends JLabel {
public ImageLabel (String img){
this (new ImageIcon (img));
}
public ImageLabel (ImageIcon icon){
setIcon(icon);
setIconTextGap(0);
setBorder(null);
setText(null);
setSize(icon.getImage().getWidth(null),icon.getImage().getHeight(null));
}
}
Container has a method getComponents(). JPanel is a descendant and will hopefully have it. To check for a given component you do the following:
Component[] cmp=myPanel.getComponents();
for(int i=0; i<cmp.length; i++)
if(myComponent.equals(cmp[i])) {
myPanel.remove(myComponent);
myPanel.add(myNewComponent, i);
}
where myComponent is the component you want to remove and myNewComponent is the component you want to add.
--
Ok your code uses some ColorPanel which I'm not familiar with but lets suppose its something like a JLabel.
I understand that you actually add (in the full code) as many colorpanels as coins in the image.
GridBag is out of my consideration - but maybe you should just skip the ipadx etc and just remove/add. Better yet use some /normal/ layout such as GridLayout or even FlowLayout for testing purposes.
Suggestion: have a JPanel (input) with a GridLayout(5, 5) where you add only the color panels (numbers). Have another JPanel (jp2) where you add the previous JPanel (input) and the button(confirm) - this jp2 is added to the jframe. You should add/remove on the input.
for(i=0; i<25; i++) input.add(new ColorPanel(...));
thrown = pitch.nextInt(25);
System.out.println(thrown);
place=illit;
spot.put(place, rSet);
input.remove(thrown);
Component newn = input.getComponent(place);
input.add(newn, thrown);
Also make sure you call validate after each removal/addition:
input.validate();
In summary, the following is a simplified working program of what you are trying to do:
class T extends Frame {
public T() {
setSize(500, 500);
setLayout(new GridLayout(5, 5));
for(int i=0; i<25; i++) add(new Label(""+i));
setVisible(true);
}
public static void main(String args[]) {
T t=new T();
for(int i=0; i<5; i++) {
int r=(int)(Math.random()*25);
t.remove(r);
t.add(new Label(""+(i+1)), r);
t.validate();
t.repaint();
try { Thread.sleep(5000); } catch(InterruptedException ie) {}
}
}
}

I'm new to Java Swing, and coding in general and a code I wrote today is having an odd glitch involving the button.doClick() method.

If someone could review my code for me, give me some pointers etc, I would be very grateful!
So in this game in case you've never played Mastermind, basically three colours are hidden in a specific order and the user has to guess what they are out of four possible colours. The code appears to work fairly well, even though it is currently unfinished, however an odd glitch occurs once the user wins. When the player properly guesses the three hidden colours, they are prompted to press the "Play again" button, which is then supposed to reset the game, which it appears to do, however once the user inputs another colour into the JTextFields designated to do so, the words last entered in those fields are revealed. I have implemented a small line that displays the word "working" on a nearby JLabel to show that the doClick() methods are activating, but the reset button doesn't work as intended, even though the newGame button does. Its an odd glitch, if anyone has a fix or reason for this glitch or any other general improvements you would make my day!
import java.awt.Color;
import java.awt.ComponentOrientation;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
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 Summative2 extends JFrame {
static int guessNum;
static String colourGuess[] = new String[3];
static String colourArgument;
static int[] solution = new int[3];
public Summative2() {
for (int x=0;x<3;x++)
{
solution[x] = solution(); //Setting the solution for the first game
}
displayIntro(); //Activating the intro screen to start the program
}
public void displayIntro()
{
JPanel introPanel = new JPanel(new GridBagLayout());
this.getContentPane().add(introPanel);
GridBagConstraints c = new GridBagConstraints(); //The variable name being defined for the layout's constraints
introPanel.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT); //Setting the orientation of the Grid layout
c.insets = new Insets(2,2,2,2); //Basic spacing and anchoring
c.anchor = GridBagConstraints.CENTER;
JLabel welcome = new JLabel("Welcome to MASTERMIND");
c.ipady = 40;
c.gridx = 1; //Large welcome label, introducing the game
c.gridy = 0;
c.gridwidth = 3;
introPanel.add(welcome, c);
c.ipady = 0; //Resetting the characteristics of the components back to normal after the large intro message
c.gridwidth = 1;
JButton start = new JButton ("Start");
c.gridx = 1; //The start button
c.gridy = 1;
introPanel.add(start, c);
JLabel space = new JLabel(" ");
c.gridx = 2;
c.ipadx = 10; //Space between the Start and Rules buttons
c.gridy = 1;
introPanel.add(space, c);
c.ipadx= 0;
JButton rulesButton = new JButton("Rules");
c.gridx = 3; //Rules button
c.gridy = 1;
introPanel.add(rulesButton, c);
rulesButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
introPanel.setVisible(false);
displayRules("intro"); //Makes the intro panel invisible and activates the rules panel, along with an argument that tells the displayRules method to return the user to the intro screen when they press back after reading the rules
}
});
start.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
introPanel.setVisible(false); //Makes the intro invisible and starts the main game.
displayGame(false);
}
});
}
public void displayRules(String previousScreen) {
JPanel rulesPanel = new JPanel(new GridBagLayout());
GridBagConstraints r = new GridBagConstraints();
rulesPanel.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
this.getContentPane().add(rulesPanel);
JTextField rulesText = new JTextField("insert rules here");
rulesText.setEditable(false);
r.gridx = 0;
r.gridy = 0;
r.gridwidth = 3;
r.ipady=100; //Big rules text box` NOT YET FINISHED
r.ipadx = 100;
rulesPanel.add(rulesText, r);
r.gridwidth =1;
r.ipadx=1;
r.ipady=1;
JButton backFromRules = new JButton("Back");
r.gridx = 2; //back button
r.gridy=1;
rulesPanel.add(backFromRules, r);
backFromRules.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
rulesPanel.setVisible(false);
if (previousScreen.compareTo("intro")==0) //When the user presses the back button they are returned to the screen from which they activated the rules screen
{
displayIntro();
}
if (previousScreen.compareTo("game")==0)
displayGame(false);
}
});
}
public void displayGame(boolean restart)
{
JPanel gamePanel = new JPanel(new GridBagLayout());
GridBagConstraints g = new GridBagConstraints();
gamePanel.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
this.getContentPane().add(gamePanel);
g.anchor=GridBagConstraints.WEST;
g.weightx =1;
int coloursY = 0;
JButton redButton = new JButton("Red");
redButton.setBackground(Color.RED); //the red button, which is red
g.gridx= 0;
g.gridy=coloursY;
gamePanel.add(redButton, g);
JButton greenButton = new JButton("Green");
greenButton.setBackground(Color.GREEN);
g.gridx = 1; //The green button, which is green
g.gridy = coloursY;
gamePanel.add(greenButton, g);
JButton blueButton = new JButton("Blue");
blueButton.setBackground(Color.CYAN); //The blue button, which is cyan
g.gridx =2;
g.gridy=coloursY;
gamePanel.add(blueButton, g);
JButton yellowButton = new JButton("Yellow");
yellowButton.setBackground(Color.yellow); //The yellow button which is yellow
g.gridx=3;
g.gridy=coloursY;
gamePanel.add(yellowButton, g);
g.weightx=0;
g.weighty=0;
JLabel firstGuess = new JLabel("First Block Guess:");//The label for the first guess in each guessing sequence, followed by labels for the seconds and third
g.gridx = 0;
g.gridy=1;
g.gridwidth = 2;
gamePanel.add(firstGuess, g);
JLabel secondGuess = new JLabel("Second Block Guess:");
g.gridx = 0;
g.gridy=2;
gamePanel.add(secondGuess, g);
JLabel thirdGuess = new JLabel("Third Block Guess:");
g.gridx = 0;
g.gridy=3;
gamePanel.add(thirdGuess, g);
JTextField guessOne = new JTextField(""); //The text field where the user can enter thier guess for the first colour in a possible solution
guessOne.setPreferredSize(new Dimension(50,24));
g.gridx = 2;
g.gridy = 1;
guessOne.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
gamePanel.add(guessOne, g);
JTextField guessTwo = new JTextField(""); //Second colour
guessTwo.setPreferredSize(new Dimension(50,24));
g.gridx = 2;
g.gridy = 2;
gamePanel.add(guessTwo, g);
JTextField guessThree = new JTextField(""); //Third
guessThree.setPreferredSize(new Dimension(50,24));
g.gridx = 2;
g.gridy = 3;
gamePanel.add(guessThree, g);
JButton update = new JButton();//The update button, which doesn't exist but I used it as a type of repeatable method for whenever the user presses a colour button
JLabel GOneIndicator = new JLabel("<--"); //These arrows move when the user presses a colour button, letting them know where their next colour guess will be applied
g.gridx = 3;
g.gridy = 1;
gamePanel.add(GOneIndicator, g);
JLabel GTwoIndicator = new JLabel("<--");
g.gridx = 3;
g.gridy = 2;
gamePanel.add(GTwoIndicator, g);
GTwoIndicator.setVisible(false);
JLabel GThreeIndicator = new JLabel("<--");
g.gridx = 3;
g.gridy = 3;
gamePanel.add(GThreeIndicator, g);
GThreeIndicator.setVisible(false);
g.gridwidth = 2;
g.fill = GridBagConstraints.HORIZONTAL;
JButton submitButton = new JButton("SUBMIT"); //Submit guess
g.gridx = 0;
g.gridy = 4;
gamePanel.add(submitButton, g);
JButton resetButton = new JButton("Reset"); //Reset your guess JTextFields
g.gridx = 2;
g.gridy = 4;
gamePanel.add(resetButton, g);
JButton newGame = new JButton("New Game"); //Generates a new solution and presses the reset button
g.gridx = 0;
g.gridy = 5;
gamePanel.add(newGame, g);
JButton rulesButton = new JButton("Rules");
g.gridx = 2; //Displays the rules
g.gridy = 5;
gamePanel.add(rulesButton, g);
submitButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
String guess[] = new String[3];
boolean proper = true;
guess[0]= guessOne.getText();
guess[1] = guessTwo.getText();
guess[2] = guessThree.getText();
for (int y = 0;y<3;y++)
{
if ((guess[y].compareToIgnoreCase("blue")!=0) && (guess[y].compareToIgnoreCase("red")!=0) && (guess[y].compareToIgnoreCase("green")!=0) && (guess[y].compareToIgnoreCase("yellow")!=0))
{
proper = false; //If one of the text fields had a word that wasn't one of the colours available for guessing, the user will be told so.
}
}
if (proper)
check(guess);//If everything was in order, check the guess against the solution
else
errorWindow();//Otherwise, nope
}
});
resetButton.addActionListener(new ActionListener() {//Sets all of the textFields blank, the guessnumber to 1 and makes the fiirst arrow appear as if it were the first guess.
#Override
public void actionPerformed(ActionEvent e) {
guessOne.setText("");
guessTwo.setText("");
guessThree.setText("");
guessNum=1;
GOneIndicator.setVisible(true);
GTwoIndicator.setVisible(false);
GThreeIndicator.setVisible(false);
}
});
newGame.addActionListener(new ActionListener () {
#Override
public void actionPerformed(ActionEvent e) {//Clicks the reset and generates a new solution set.
resetButton.doClick();
for(int d=0;d<3;d++)
solution[d]= solution();
}
});
if (restart)//If this screen was generated from the user pressing the play again button after winning, the game should be automatically reset and new solutions generated, this is bugging out somehow.
{
newGame.doClick();
GOneIndicator.setText("working");
resetButton.doClick();
restart=false;
}
rulesButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {//more rules display that isnt finished yet
gamePanel.setVisible(false);
displayRules("game");
}
});
update.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {//When a colour button is pressed, the next guess Field is filled in order, depending on the last one that was filled
colourGuess[guessNum-1] = colourArgument;
if (guessNum ==1 ){
guessOne.setText(colourArgument);
GOneIndicator.setVisible(false);
GTwoIndicator.setVisible(true);
guessNum++;
}
else if (guessNum ==2){
guessTwo.setText(colourArgument);
GTwoIndicator.setVisible(false);
GThreeIndicator.setVisible(true);
guessNum++;
}
else if (guessNum==3){
guessThree.setText(colourArgument);
GThreeIndicator.setVisible(false);
GOneIndicator.setVisible(true);
guessNum = 1;
}
}
});
redButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) { //Red is put into the next guess slot0
colourArgument = "Red";
update.doClick();
}
});
blueButton.addActionListener(new ActionListener() {//Then blue
#Override
public void actionPerformed(ActionEvent arg0) {
colourArgument = "Blue";
update.doClick();
}
});
yellowButton.addActionListener(new ActionListener() {//Or yellow
#Override
public void actionPerformed(ActionEvent arg0) {
colourArgument = "Yellow";
update.doClick();
}
});
greenButton.addActionListener(new ActionListener() {//or green
#Override
public void actionPerformed(ActionEvent arg0) {
colourArgument = "Green";
update.doClick();
}
});
}
public void check(String guess[])
{
JFrame checkWindow = new JFrame();
checkWindow.setSize(300,100);
JPanel pane = new JPanel(new GridBagLayout());
checkWindow.getContentPane().add(pane); //This is all to set up the initial window generally, and activate the layouts and whatnot
GridBagConstraints c = new GridBagConstraints();
pane.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
checkWindow.setVisible(true);
c.insets = new Insets(2,2,2,2);
int numGuess[] = new int[3]; //
int colourCount=0;
int positionCount=0; //Converts the information in the textFields to numbers which can be more easily compared
for (int x =0;x<3;x++)
{
if (guess[x].compareToIgnoreCase("red")==0)
{
numGuess[x] = 1;
}
if (guess[x].compareToIgnoreCase("blue")==0)
{
numGuess[x] = 2;
}
if (guess[x].compareToIgnoreCase("green")==0)
{
numGuess[x] = 3;
}
if (guess[x].compareToIgnoreCase("yellow")==0)
{
numGuess[x] = 4;
}
}
for (int z=0;z<3;z++) //Runs through the inputs compared to the solution, finding out how many of the colours were correct, and any of those colours that were in the correct positions
{
boolean guessed = false;
for (int k=0;k<3;k++)
{
if (solution[z] == numGuess[k])
{
guessed = true;
}
}
if (solution[z] == numGuess[z])
positionCount++;
if (guessed)
colourCount++;
}
c.fill=GridBagConstraints.HORIZONTAL;
c.anchor = GridBagConstraints.CENTER;
if (positionCount ==3) //If all three positions are correct the user wins
{
JLabel colours = new JLabel(guess[0] + ", " + guess[1] + ", " + guess[2] + " is correct!");
c.gridx=0;
c.gridy=0;
pane.add(colours, c);
JLabel winner = new JLabel("You WIN!");
c.gridx=0;
c.gridy=1;
pane.add(winner, c);
JButton playAgain = new JButton("Play Again");
c.gridx=0;
c.gridy=1;
pane.add(playAgain, c);
playAgain.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {//Glitch causing button
for(int x=0;x<3;x++)
{
solution[x] = (int) (Math.random()*4)+1;
}
checkWindow.dispose();
displayGame(true);
}
});
}
else
{
JLabel labelOne = new JLabel(guess[0] + ", " + guess[1] + ", " +guess[2]);//If the user doesn't win, how many correct colours and positions they had are displayed
c.gridx = 0;
c.gridy = 0;
pane.add(labelOne, c);
JLabel colourMessage = new JLabel("You had " + colourCount + " correct colours.");
c.gridx=0;
c.gridy=1;
pane.add(colourMessage, c);
JLabel positionMessage = new JLabel("You had " + positionCount + " in the correct positions");
c.gridx=0;
c.gridy=2;
pane.add(positionMessage, c);
}
}
public void errorWindow()
{
JFrame checkWindow = new JFrame();
checkWindow.setSize(200,100);
JPanel pane = new JPanel(new GridBagLayout());//This window is displayed if the user inputs impossible values for their colour guesses
checkWindow.getContentPane().add(pane);
GridBagConstraints c = new GridBagConstraints();
pane.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
checkWindow.setVisible(true);
JLabel whoops = new JLabel("Try Again with valid colours.");
c.gridx=0;
c.gridy=0;
pane.add(whoops, c);
}
public static void main(String[] args) {
Summative2 frame = new Summative2(); //main method making the JFrame work properly
guessNum = 1;
frame.pack();
frame.setVisible(true);
frame.setSize(300, 225);
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public static int solution()
{
return (int) (Math.random()*4+1);//Solution method returning random numbers between 1 and 4 for solutions.
}
}
Every time you call the check() method, you're creating new ActionListener and registering it on the playAgain button.
This way, you get lots and lots of action listeners, and once the user finally clicks the playAgain button, they are all called, one by one.
You can see that yourself by setting a breakpoint inside the ActionListener code and debugging the application.
The solution would be to move that logic out of the check() method, to someplace where the form is initialized.

Location set up with GridBagLayout is not going good & JTextField & JButton wont take affect

So I am working on this small program when I ran in to this problem.Its mostly about location set up with GridBagLayout it wont show me the text for the JLable.Another problem is that every ones in a will my progress that was working stops working and later comes back.Any idea what it is?I would also like some one too help me with the location problem I want to place the JTextField in the bottom left corner any help?I cant go around this problem and no info online to specifically help me.So maybe you can help me.Hers my code so far...
package Main;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class code extends JFrame{
public static JTextField consol;
public static String title = "Metal-Lock:The Start";
public static Dimension size = new Dimension(650, 550);
public static JPanel panel;
public static JButton enter;
public static JLabel output;
public static void main(String args[]) {
code frame = new code();
}
public code() {
setTitle(title);
setSize(size);
setResizable(true);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
// VISITOR LIST
CONSOL();
P1();
P2();
}
//******************************************************************************************************************************
public void CONSOL() {
consol = new JTextField(30);
consol.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e){
String input = consol.getText();
output.setText(input);
}});
final JButton enter = new JButton("Enter");
enter.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e){
String input = consol.getText();
output.setText(input);
panel.add(consol);
add(panel);
panel.add(enter);
add(panel);
output = new JLabel();
panel.add(output);
add(panel);
}
});
}
//******************************************************************************************************************************
public void P1() {
}
//******************************************************************************************************************************
public static JLabel grid1;
public static JLabel grid2;
public static JLabel grid3;
public static JLabel grid4;
public static JLabel grid5;
public void P2() {
JPanel panel = new JPanel(new GridBagLayout());
GridBagConstraints R = new GridBagConstraints();
JLabel grid1 = new JLabel ("Hello"); panel.add(grid1, R);
R.gridx = 0; R.gridy = 0;
JLabel grid2 = new JLabel ("Hello"); panel.add(grid2, R);
R.gridx = 0; R.gridy = 0;
JLabel grid3 = new JLabel ("Hello"); panel.add(grid3, R);
R.gridx = 0; R.gridy = 0;
JLabel grid4 = new JLabel ("Hello"); panel.add(grid4, R);
R.gridx = 0; R.gridy = 0;
JLabel grid5 = new JLabel ("Hello"); panel.add(grid5, R);
R.gridx = 0; R.gridy = 0;
}
}
Just went really quickly through your code.
Change these lines:
GridBagConstraints R = new GridBagConstraints();
R.gridx = 0; R.gridy = 0;
JLabel grid1 = new JLabel ("Hello");
//important to set these R values BEFORE you ad grid1.
panel.add(grid1, R);
Change this in all lines there...
You are adding 6 Labels all to the location gridx=0 and gridy=0, which is wrong. Imagine it like an excel tabel, you are inserting every label to field 1.
If you want to add fields do it like this
E.g.
x y
z
//a.gridx=0; a.gridy=0;
//y.gridx=1; y.gridy=0;
//z.gridx=0; z.gridy=1;
x coordinates are horizontal.
y are vertical starting from the top left corner.
Read this article, it's really good:
http://docs.oracle.com/javase/tutorial/uiswing/layout/gridbag.html

Categories