JButton doesn't appear until clicked - java

For this program, the JButton doesn't seem to show up unless you click the area where the JButton should be; the JFrame starts up blank. The moment you click the button, the respective code runs and the button finally shows up.
How do I get the buttons to show up upon starting the program?
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
/*
The Amazing BlackJack Advisory Tool by JoshK,HieuV, and AlvinC.
Prepare to be amazed :O
*/
public class BlckJackUI {
//main class, will contain the JFrame of the program, as well as all the buttons.
public static void main(String args[])
{
//Creating the JFrame
JFrame GUI = new JFrame("Blackjack Advisor");
GUI.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
GUI.setSize(1300, 900);
GUI.setContentPane(new JLabel(new ImageIcon("C:\\Users\\Hieu Vo\\Desktop\\Green Background.png")));
GUI.setVisible(true);
// Because each button needs to run through the Math class.
final Math math = new Math();
// The Ace Button:
ImageIcon Ace = new ImageIcon("/Users/computerscience2/Downloads/Ace.jpg");
JButton ace = new JButton(Ace);
ace.setSize(300, 100);
ace.setLocation(100, 100);
ace.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
//Automatically default the the Ace to 11, and if Bust, Ace becomes 1.
if (math.array.playerhandtotal <= 21)
{
math.cardvalue = math.cardvalue + 11;
}
else
{
math.cardvalue = math.cardvalue + 1;
}
math.array.clicktracker++;
math.calcResult();
JOptionPane.showMessageDialog(null,math.array.result);
}
});
GUI.add(ace);
ImageIcon Two = new ImageIcon("/Users/computerscience2/Downloads/2.jpg");
JButton two = new JButton(Two);
two.setSize(300, 100);
two.setLocation(100, 200);
two.addActionListener(new ActionListener ()
{
public void actionPerformed(ActionEvent e)
{
/*
This generally repeats throughout the whole class, and the only
thing different is the changing cardvalue. When a button is pressed,
respective cardvalues are added into the playerhand ArrayList, and
totaled up to form playerhandtotal, which is a major factor in
bringing up the advice.
*/
math.cardvalue = math.cardvalue + 2;
math.array.clicktracker++;
math.calcResult();
JOptionPane.showMessageDialog(null,math.array.result);
}
});
GUI.add(two);
Et cetera, Et cetera... Just a bunch of the same stuff, more buttons coded the same exact way as JButton two, but with different value associated to them.
JButton start = new JButton("Start/Reset");
start.setSize(300, 100);
start.setLocation(500,500);
start.addActionListener(new ActionListener ()
{
public void actionPerformed(ActionEvent e)
{
/*
The start button also acts like a reset button, and the concept is fairly
simple. If we reset all the important values to 0 or "null," then the
program acts as if it was just opened.
*/
Arrays array = new Arrays();
array.playerhand.clear();
array.dealer = 0;
math.array.starttracker++;
math.array.clicktracker = 0;
array.playerhandtotal = 0;
math.cardvalue = 0;
array.result = null;
JOptionPane.showMessageDialog(null,"Please select the card \nthat the dealer is showing :)");
}
});
GUI.add(start);
GUI.setLayout(null);
This is all in the same class, and I understand a layout would be nicer, but perhaps there's a way to fix this issue using what I have now?

The program starts blank because you are calling setVisible before you add components. Call setVisible after you add components (in the end of contructor) and it should work fine.
Also, avoid absolute positioning and call of set|Preferred|Minimum|MaximumSize methods for your components. Learn how to use layout managers.

Write GUI.validate(); after you add all the components to your frame. Any time you add something to a frame you have to validate it like this. Otherwise, you will get the behavior that you have described.

No. The problem is caused by the layout. Before adding anything to a JFrame or a JPanel which you want it to have an absolute position, you have to setLayout(null). Otherwise, you'll have unexpected behaviours all the time. I just figured it out by myself after three hours of experimenting; suddenly, I connected your post with other different subject, and it worked, but this isn't well explained on the Internet yet.

Related

Can you make a JPanel randomly generate each time a button is clicked?

Basically just started coding in Java using Eclipse and as my first "serious" project I'm trying to code a simple quiz game. I already set up all the graphics and the answering system but I'm getting stuck at the part where, if you click the right answer, the JPanel restarts with a new question.
I already tried some solutions I've seen online including a do/while method, which proved worthless and calling the main method ( the one where all the code is) which seems impossible.
Here's the method I'm talking about:
public static void main(String []args) throws IOException
{
//here was unnecessary stuff i cut out
ImageIcon image = new ImageIcon (Imagetesting.class.getResource(i+".jpg"));
JLabel label = new JLabel (image);
JFrame f = new JFrame("Quiz");
JLabel x1 = new JLabel(question);
JButton x2 = new JButton(answer1);
//+ other graphic stuff
f.getContentPane().add(MyPanel, "Center"); // Paste MyPanel in center
// of the contentPane
f.setExtendedState(JFrame.MAXIMIZED_BOTH);
f.setVisible(true);
x3.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if(answer2.equals("therightanswer")){
score = score +1;
x1.setText("Right answer Punteggio:"+String.valueOf(punteggio)
// what am I supposed to put here?
);
;
}
}});
So what am I supposed to do? Is it even possible to call the main method to make it restart? Am I doing something wrong?
You can pass the labels into the actionPerformed function to change the values of those objects when the answer is correct.

JButtons in GUI

I'm a beginner in GUI.
Is there a quick way of setting the same JButton/Image to multiple locations within the GUI? For better clarification, if I want to use this JButton 10 times at different locations in my GUI, would I have to create a new JButton(new ImageIcon...) 10 times?
The buttons don't have to lead to anything, this is just for show.
JButton jb = new JButton(new ImageIcon("myImage.png"));
jb.setLocation(10,10);
jb.setSize(40, 40);
getContentPane().add(jb);
The short answer is, yes, you will need multiple instances of JButton.
You can use an Action which can be applied to multiple instance of a button (the same instance of Action). The Action class carries properties which will be used to configure the buttons, such as text and icon properties.
A component (like JButton) can only reside within in a single container, therefore, you will need multiple instances of JButton.
Take a look at How to Use Actions and How to Use Buttons, Check Boxes, and Radio Buttons for more details...
Generally, you should avoid using setLocation and setSize and rely more on the use of layout managers, but you've not provided enough context to say if this useful to you or not.
Yes, you need to create a Jbutton object for each desired instance.
Since you have so many JButton that are all similar, I suggest that you declare an array JButton[] buttons = new JButton[10]; and use a for loop to create each individual button and set their attributes.
If it is just for a show, I would do the following to show the 10 button in a row:
int buttonHeight = 10;
int buttonWidth = 10;
for (int i = 0; i < 10; i++) {
JButton button = new Button("Button " + i);
button.setSize(buttonWidth, buttonHeight);
button.setLocation(10 + i * buttonWidth, 10);
getContentPane().add(button);
}
import java.util.Scanner;
import javax.swing.*;
import java.awt.*;
class PROB4_CHAL1 extends JFrame
{
JButton b[]=new JButton[10];
public PROB4_CHAL1()
{
setLayout(null);
setVisible(true);
setSize(100,100);
for(int i=0;i<10;i++)
{
b[i]=new JButton(""+i);// or b[i]=new JButton(new ImageIcon("path"));
b[i].setBounds(i*10,i*20,50,20);
add(b[i]);
}
}
public static void main(String[] args)
{
new PROB4_CHAL1();
}
}
You can Create array of 'JButton [10]' .

No visual appearing

I am working on a java game for class where we implement a game of nim. I thought that I was nearing completion but when I ran the program, nothing appears. It just says build successful and quits. I never get to see the game or play it. Below is my code for the application.
package Nim;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Nim extends JFrame implements ActionListener {
// Number of stickSpace that is needed for the sticks;
int rowspace = 3;
// Buttons for the human to click to take turns playing witht the computer.
private JButton humanMove,
computerMove;
// whatRow = what row the user would like to remove from
// howMany = how many sticks to take from each row
private JComboBox whatRow,
howMany;
// Creates an array of JTextFields with the rowspace as a size.
private JTextField[] stickSpace = new JTextField[rowspace];
// Creates the game;
private Nimgame nimgame;
public void Nim(){
//As requireed, we use a loop to fill the array.
for(int i=0; i<rowspace ;i++){
stickSpace[i] = new JTextField(5);
}
// Creates pulldown menus for the user to select the whatRow s/he
// wants to choose from, and another for howMany s/he wants to take.
whatRow = new JComboBox();
howMany = new JComboBox();
// Add the options to the pulldown menus so the player can choose.
// 0-2 because the array index starts at 0. 1-3 for the amount of sticks.
for(int p=0; p<=3; p++){
if(p<3){
whatRow.addItem(p);
}
if(p>0){
howMany.addItem(p);
}
}
// Adds the text "Human Turn" and "CPU Turn" to the buttons used for turns.
humanMove = new JButton("Human Turn");
computerMove = new JButton("CPU Turn");
// Adds a listener to the buttons to signal the game its time to act.
humanMove.addActionListener(this);
computerMove.addActionListener(this);
// Creates a gridlayout (3,2) with 3 rows and two columns.
JPanel gridpanel = new JPanel(new GridLayout(3,2));
// Labels the rows so the player knows it starts at row Zero - Three.
gridpanel.add(new JLabel("Row Zero", JLabel.LEFT));
gridpanel.add(stickSpace[0]);
gridpanel.add(new JLabel("Row One", JLabel.LEFT));
gridpanel.add(stickSpace[1]);
gridpanel.add(new JLabel("Row Two", JLabel.LEFT));
gridpanel.add(stickSpace[2]);
// Creates another gridlayout this time with 4 rows and 2 columns.
// This sill be used to add the comboboxes, labels, and buttons.
JPanel mainPanel = new JPanel(new GridLayout(4,2));
mainPanel.add(new JLabel("Remove from Row:", JLabel.RIGHT));
mainPanel.add(whatRow);
mainPanel.add(new JLabel("# To Remove:", JLabel.RIGHT));
mainPanel.add(howMany);
mainPanel.add(humanMove);
mainPanel.add(computerMove);
// This adds the gridpanel and the main panel to the visual
// application, but they are still not visiable at this moment.
getContentPane().add(gridpanel, BorderLayout.NORTH);
getContentPane().add(mainPanel, BorderLayout.SOUTH);
// This sections sets the title, size, position on screen, sets it visiable,
// sets the background color, and makes it exit on close of the visual application.
setTitle("The Game of Nim");
setSize(300, 250);
setBackground(Color.yellow);
setVisible(true);
// Creates the actual game to play.
nimgame = new Nimgame();
// Prints out the sticks in each row.
for(int p=0; p<3; p++){
stickSpace[p].setText(nimgame.addSticks(p));
}
}
// Method to handle when an action lister find an action event
public void actionPerformed(ActionEvent e){
// Checks if the humanMove button has been pressed
if(e.getSource() == humanMove){
int foo = whatRow.getSelectedIndex();
int bar = howMany.getSelectedIndex()+1;
nimgame.stickRemove(foo, bar);
for(int p=0; p<3; p++){
stickSpace[p].setText(nimgame.addSticks(p));
}
}
// Checks if the computerMove button has been pressed.
if(e.getSource() == computerMove){
nimgame.computerRandom();
for(int p=0; p<3; p++){
stickSpace[p].setText(nimgame.addSticks(p));
}
}
// Checks to see if the game is over or not.
if(nimgame.isDone()){
JOptionPane.showMessageDialog(null, "Game Over Player Player" + nimgame.whoWon());
}
}
public static void main(String[] args) {
Nim NIM = new Nim();
}
}
Any idea why nothing would be showing up? I figured I forgot to setVisible, but that wasn't the case. Any help would be much appreciated.
public void Nim(){
This isn't a constructor, it's a void method declaration with an awfully confusing name. As you don't declare a constructor at all, you have an implicit default constructor which is called here:
Nim NIM = new Nim();
but the default constructor doesn't do what you'd expect, so you don't see anything. To fix this, change the aforementioned method definition to a constructor definition by removing void:
public Nim() {

GUI action listeners for each tab in a tabbed pane

I am fairly new to java so bear with me please, basically, below I have a tabbed pane for each of the four rooms in the rooms Arraylist, and I am creating buttons in each tab depending how many lights each room has, How can I associate the buttons in each tab with a specified the rooms?. So like when I click the light button in the Room 1 tab, the event listener knows that the button belongs to the room1?
Any help is appreciated, thanks.
import java.util.ArrayList;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class MasterGUI extends JFrame implements ActionListener{
public MasterGUI(){
}
public void DisplayFrame(){
ArrayList<Rooms> rooms;
rooms = Building.getRoomList();
JFrame master = new JFrame("Solar Master Control Panel");
master.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container content = master.getContentPane();
content.setBackground(Color.lightGray);
JTabbedPane tabbedPane = new JTabbedPane();
JPanel tmpPanel;
for(int x = 0; x < rooms.size(); x++){
tmpPanel = new JPanel();
String roomName = rooms.get(x).getName();
int id = rooms.get(x).getId();
tabbedPane.addTab(roomName + " Room " + id, tmpPanel);
}
for(int x = 0; x < rooms.size(); x++){
for(int i = 0; i < rooms.get(x).roomLights.size(); i++){
int num = i + 1;
((JPanel) tabbedPane.getComponentAt(x)).add(new JButton("Light" + num));
}
}
master.add(tabbedPane, BorderLayout.CENTER);
master.setSize(800, 600);
content.add(tabbedPane);
master.setVisible(true);
}
public void actionPerformed(ActionEvent e){
}
First of, you need to add the ActionListener to the button so it will be called when the button is clicked.
...
JButton button = new JButton("Light" + num);
button.addActionListener(this);
((JPanel) tabbedPane.getComponentAt(x)).add(button);
...
As far as differentiating between which button was clicked, there are two main ways to address this. The first is to use getSource() on the ActionEvent to get a reference to the object that triggered the event. You can use this to decide how you want to proceed further. The other option is to have MasterGUI not implement ActionListener. Instead, make a unique ActionListener for each button that immediately know what action needs to occur when it was called. The first option makes it easier to register listeners, but requires more work in the handler to determine the source. I prefer the second method.
ActionEvent in actionPerformed() will tell you the source of the button pressed. So you can do one of two things, you can name the button (which is not the same as the button text) something indicative of the room, or you can provide a command string that the button invokes, which is also available from the ActionEvent.
Check out the JButton JavaDoc, it has links to dealing with Actions and specifically button Actions supported.
It will focus your question a little better as well, since you'll have a better idea of how you're looking to achieve your goal.

Java Hangman Project: Action Listener

I am creating a hangman game. I made a button A - Z using the GUI Toolbars in Netbeans as follows:.
My problem is, how can I add an actionlistener to all of it. Is it possible to use a loop? If i click the button A, i will get the character 'a' and so on..
Yes it is possible to use a loop, but since your JButtons were created by using NetBeans code-generation, they won't be in an array or collection initially, and so this is something that you'll have to do: create an array of JButton and fill it with the buttons created by NetBeans. Then it's a trivial matter to create a for loop and in that loop add an ActionListener that uses the ActionEvent's actionCommand (as noted above) in its logic.
Having said this, I think that the better solution is to forgo use of the NetBean's GUI builder (Matisse) and instead to create your Swing code by hand. This will give you much greater control over your code and a much better understanding of it as well. For instance, if you do it this way, then in your for loop you can both create your buttons, add the listeners, and add the button to its container (JPanel).
e.g.,
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;
public class Foo2 {
public static void main(String[] args) {
JPanel buttonContainer = new JPanel(new GridLayout(3, 9, 10, 10));
List<JButton> letterButtons = new ArrayList<JButton>(); // *** may not even be necessary
for (char buttonChar = 'A'; buttonChar <= 'Z'; buttonChar++) {
String buttonText = String.valueOf(buttonChar);
JButton letterButton = new JButton(buttonText);
letterButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String actionCommand = e.getActionCommand();
System.out.println("actionCommand is: " + actionCommand);
// TODO fill in with your code
}
});
buttonContainer.add(letterButton);
letterButtons.add(letterButton);
}
JOptionPane.showMessageDialog(null, buttonContainer);
}
}
Well, with some pseudo code, wouldn't this make sence for you?
for(button in bord) {
button.addActionListener(my_actionlistener);
}
Then in your actionlistener you can see which button was pressed
public void actionPerformed(ActionEvent e) {
// button pressed
if ("string".equals(e.getActionCommand()) {
// do something
}
// and so forth
}
You'll need to add the buttons to a list of some kind so you can iterate through them, Netbeans doesn't do this for you when you generate the buttons.
After that, just run a for each loop on the list containing all the buttons. To get the values of the characters just cast the relevant ascii value, which starts at 97 for a lower case a or 65 for an upper case A:
int charNum = 97;
for(Button b : board) {
char charVal = (char)charNum;
charNum++;
//add the action listener
}

Categories

Resources