JLabel-Array create on Button push - java

I want to create a JLabel of an Array on a button push. I've never done something with Arrays, so maybe it's some sort of training. I tried it, but it won't work. Expected result: Everytime I push the button, would one of the 20 JLabels be created.
Here's my class:
public class JLabelArray {
static JFrame frame;
static JButton button;
public static void main(String[] args) {
final JLabel[] label = new JLabel[20];
//
button = new JButton("push me");
button.setBounds(0, 0, 100, 30);
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// This is where a new JLabel should be created
for (int i = 0; i < label.length; i++) {
label[i] = new JLabel("Label" + i);
label[i].setBounds(button.getX(), button.getY()+ 10 + i * 15, 50, 50);
frame.add(label[i]);
frame.revalidate();
frame.repaint();
}
}
});
//
frame = new JFrame();
frame.setSize(500, 500);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(null);
frame.setVisible(true);
frame.add(button);
}
}
EDIT: Updated code
EDIT2: Updated for-loop
EDIT3: I reworked the whole question

You should re-validate/repaint when you add Components after the parent container has been validated - this includes not only when you add the JButton (add this prior to setting the JFrame to visible) but also when you add the JLabels
frame.add(label[i]);
frame.revalidate();
frame.repaint();
I would also recommend not using a null layout, rather choose the appropriate LayoutManager: see https://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html . If you wish to continue using a null layout, then you should set the added Labels to different positions or they will just overlap each other.

Related

How do I make separate buttons do separate things?

I have a button in a simple application I'm making which will increment a variable by one once pressed. This is it's code:
public class GUI implements ActionListener {
int clicks = 0;
int autoClickLevel = 0;
JLabel label;
JFrame frame;
JPanel panel;
public GUI() {
JButton button = new JButton("Click me!");
button.addActionListener(this);
panel = new JPanel();
panel.setBorder(BorderFactory.createEmptyBorder(60, 100, 30, 100));
panel.setLayout(new GridLayout(0, 1));
panel.add(button);
frame.add(panel, BorderLayout.CENTER);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
}
public static void main(String[] args) {
new GUI();
}
#Override
public void actionPerformed(ActionEvent e) {
clicks++;
}
I would like to know how to make a separate button (which I have already made, and it shows up; JButton button2 = new JButton("Click me too!");) which changes a separate variable. button2.addActionListener(this); [plus different ways of doing it,] instead increments the clicks variable instead of a separate clicks2 variable.
My code is a bit of a mess regarding this, and this second button's script doesn't work at all. I'm also fairly new to Java so I'm not much good at figuring out this either. What's a good way to make the second button increment the other variable?
Have different ActionListeners. You can do this like this:
button2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// do something
}
});
Or you could define the ActionListener as its own class.

Button Layout Issues with JFrame

Picture included I have another issue where my buttons go to the top-right after the user inputs their name. At this point, text shows up in the GUI on the LEFT side of the center which seems it would be "WEST" when I put "CENTER". Code:
public TheDungeon()
{
setTitle("InsertGameNameHere");
setSize(750, 600);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new BorderLayout());
setLocationRelativeTo(null);
buildButtonPanel();
characterInfoPanel = new JLabel("<html>Character information will go here</html>");
gameScreen = new JLabel();
inventoryPanel = new JLabel("<html>This is for the inventory</html>");
add(gameScreen, BorderLayout.CENTER);
add(buttonPanel, BorderLayout.SOUTH);
setVisible(true);
//Program run
userName();
gameScreen.setText("<html>Welcome "+name+", to the game that has no name!</html>");
classWindow();
}
private void buildButtonPanel()
{
// Create a panel for the buttons.
buttonPanel = new JPanel();
// Create the buttons.
b1 = new JButton("Button 1");
b2 = new JButton("Button 2");
b3 = new JButton("Button 3");
b4 = new JButton("Button 4");
b5 = new JButton("Button 5");
// Add the buttons to the button panel.
buttonPanel.add(b1);
buttonPanel.add(b2);
buttonPanel.add(b3);
buttonPanel.add(b4);
buttonPanel.add(b5);
}
private void userName() {
name = JOptionPane.showInputDialog("What will your name be?");
}
I'm not sure why your program is behaving as it seems to be since when I ran it, it did not do this. You may wish to check your code to make sure that it's the code you're posting here. But regardless, I do have some suggestions:
Best to not set the sizes of anything, but rather to let the components and the layout managers do this for you.
Consider if you must overriding getPreferredSize() if you need to control the size of a component more fully.
Call pack() on your top level window after adding all components and before calling setVisible(true). This will tell the layout managers to do their things.
Avoid extending JFrame since you will rarely need to override one of its innate behaviors.
If you do add or remove components, or change their preferredSizes somehow after rendering your top-level window, you will want to call revalidate() and then repaint() on the component's container to have the container re-layout the components it holds and then redraw them.
For example:
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import javax.swing.*;
public class TheDungeon2 extends JPanel {
private static final int PREF_W = 750;
private static final int PREF_H = 600;
private static final String[] BUTTON_LABELS = {"Button 1", "Button 2",
"Button 3", "Button 4", "Button 5"};
private static final String WELCOME_TEXT = "Welcome %s to the game that has no name!";
private JLabel welcomeLabel = new JLabel("", SwingConstants.CENTER);
private String name;
public TheDungeon2() {
JPanel buttonPanel = new JPanel(new GridLayout(1, 0, 5, 0));
for (String buttonLabel : BUTTON_LABELS) {
JButton button = new JButton(buttonLabel);
buttonPanel.add(button);
}
setLayout(new BorderLayout());
add(welcomeLabel, BorderLayout.CENTER);
add(buttonPanel, BorderLayout.PAGE_END);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(PREF_W, PREF_H);
}
public void getAndSetName() {
name = JOptionPane.showInputDialog(this, "What will your name be?");
welcomeLabel.setText(String.format(WELCOME_TEXT, name));
}
private static void createAndShowGui() {
TheDungeon2 dungeon2 = new TheDungeon2();
JFrame frame = new JFrame("Nameless Game");
dungeon2.getAndSetName();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(dungeon2);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
I tested your code with an empty classWindow() method and the buttons are correctly placed in south,
for the CENTER issue, you should place something in WEST to have your text centred (even an empty panel) otherwise CENTER will take all the place,
look at this , i added this line :
add(new JButton("a button for test"),BorderLayout.WEST);
and here is the result :

How do i make next button go to next Frame? GUI

How do I make the next button go to the next Frame in this GUI? I need to have it where I can click next to display 20 more details:
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class FilledFrameViewer
{
public static void main(String[] args)
{
JFrame frame = new JFrame();
/*JButton button = new JButton*/
JButton nextButton = new JButton("NEXT");
JLabel label = new JLabel("Frame 1.");
JPanel panel = new JPanel();
panel.add(nextButton);
panel.add(label);
frame.add(panel);
final int FRAME_WIDTH = 300;
final int FRAME_HEIGHT = 100;
frame.setSize(FRAME_WIDTH, FRAME_HEIGHT);
frame.setTitle("A frame with two components");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
If you want to hide or show the frame, you can use like this
JFrame f1 = new JFrame("Frame 1");
JFrame f2 = new JFrame("Frame 2");
to hide f1, call f1.setVisible(false);
to show f2, call f2.setVisible(true);
A bit unclear. Do you want to move a JButton to another JFrame? I don't think you can manage that without dynamic programming or such (I guess?).
You should look through a tutorial of the Swing components from Oracle http://docs.oracle.com/javase/tutorial/uiswing/
And see your comments. I agree having multiple JFrame is a bad habit.
Edit
Use the eventlistner (see other answer) and make it follow a switch case? Then there you can make it display like a dialog or change a JLable inside your JFrame?
Dialog tutorial here: http://docs.oracle.com/javase/tutorial/uiswing/components/dialog.html.
I think you should go with a lable and change it's text.
JButton nextButton = new JButton("Next");
nextButton.addActionListener(new ActionListner(
private int counter = 0;
public void actionPerformed(ActionEvent e) {
counter++;
switch(counter){
case 1: somelable.setText("Your text here");
};
}));
I wrote this on free hand but I guess something like this would work?
You have to edit the codes in your next frame...
Example for your NextFrame,
public class NextFrame
public static void main(String[] args)
{
private static FilledFrameViewer parentFrame; //ADD THIS FOR CONNECTION TO FIRST FRAME
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
NextFrame frame = new NextFrame(null); //CHANGES MADE HERE
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
public NextFrame(FilledFrameViewer f) { //CHANGES MADE HERE
this.parentFrame = f; //CHANGES MADE HERE
setTitle("Personal Assistant");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
Ah, Yes...and also you'll have to add some things in the Next button...
Example:
btnNext = new JButton();
btnNext.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
goNext();
{
private void goNext(){
NextFrame nextframe= new NextFrame(null);
nextframe.setVisible(true);
}
}
});

My whole code is complete but I am not able to add a second button

Please take a look at my code it is working fine the way I want but the only issue is that I want to add another button opposite my current button and I am not able to do so can any body please help me.
import java.awt.event.*;
import javax.swing.*;
public class Example2 extends JFrame {
public Example2() {
initUI();
}
public final void initUI() {
JPanel panel = new JPanel();
getContentPane().add(panel);
panel.setLayout(null);
panel.setToolTipText("A Panel container");
JButton button = new JButton("Even");
button.setBounds(100, 60, 100, 30);
button.setToolTipText("A button component");
JButton button2 = new JButton("Odd");
button2.setBounds(100, 60, 100, 30);
button2.setToolTipText("A button component");
//Add action listener to button
button.addActionListener(new ActionListener () {
public void actionPerformed(ActionEvent e)
{
//Execute when button is pressed
System .out.println("You clicked the button");
int sum=0;
for(int i=1;i<=100;i++){
if(i%2==0){
System.out.println(i);
sum+=i;
}
}
System.out.println("Sum of even numbers: "+sum);
}
});
panel.add(button);
panel.add(button2);
setTitle("Tooltip");
setSize(500, 400);
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public static void main(String[] args) {
Example2 ex = new Example2();
ex.setVisible(true);
}
}
panel.setLayout(null);
That is where it starts to go wrong.
Use layouts. See Laying Out Components Within a Container & Effective Layout Management: Short Course for more details.
Use:
The appropriate layouts.
Possibly nested inside one another.
With appropriate layout padding and component border/insets for white space.
As an aside.
...
button.setBounds(100, 60, 100, 30);
button.setToolTipText("A button component");
JButton button2 = new JButton("Odd");
button2.setBounds(100, 60, 100, 30);
...
Did you notice how the bounds of the two buttons were identical? What do you think happens when you put two components of the same size in the same place?
You have to change panel.setLayout(null) to layout you need. For example:
panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
or
panel.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.CENTER));
Andrew Thompson +1 ,
Here are some usefull links :
A Visual Guide to Layout Managers
Using Layout Managers
Adding space between components

Having trouble repainting circles on button click

I am having trouble making my window repaint when clicking a button. What's supposed to happen when I click the button is more circles should be drawn on the frame (it should technically be the number of circles drawn last time * 2). For some reason, it's not working and I can't really figure out why it wont repaint. Here's my code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Roaches {
public static void main(String[] args) {
//Create the frame
JFrame frame = new JFrame();
//Set the frame's size
frame.setSize(800, 600);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle("Roaches!");
//Create the button
JButton button = new JButton("Multiply Roaches!");
button.addActionListener(new Roach());
JPanel buttonPanel = new JPanel();
//Add the button to the panel
buttonPanel.add(button);
//Add the panel to the frame
frame.add(buttonPanel, BorderLayout.SOUTH);
//Add the roach panel to the frame
frame.add(new Roach());
//Make frame visible
frame.setVisible(true);
}
}
class Roach extends JComponent implements ActionListener {
//Keep track of how many roaches to draw
private int roachCount = 1;
protected void paintComponent(Graphics g) {
Graphics2D gr = (Graphics2D)g;
for(int i = 0; i < roachCount; i++) {
int x = 5 * i;
int y = 5 * 1;
gr.drawOval(x, y, 50, 50);
}
System.out.println("REPAINT"); //For testing
}
public void actionPerformed(ActionEvent e) {
roachCount = roachCount * 2;
repaint();
System.out.println("CLICK!!!!"); //For testing
}
}
I don't know if I have the concept of events or repainting wrong, so any help/pointers would be appreciated. Thanks!
You don't want to create a new Roach() the second time. Just create one roach and keep a reference to it and use the reference everywhere.
public static void main(String[] args) {
//Create the frame
JFrame frame = new JFrame();
//Set the frame's size
frame.setSize(800, 600);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle("Roaches!");
//Create the button
JButton button = new JButton("Multiply Roaches!");
Roach roach = new Roach();
button.addActionListener(roach);
JPanel buttonPanel = new JPanel();
//Add the button to the panel
buttonPanel.add(button);
//Add the panel to the frame
frame.add(buttonPanel, BorderLayout.SOUTH);
//Add the roach panel to the frame
frame.add(roach);
//Make frame visible
frame.setVisible(true);
}
The issue is that you're creating two instances of Roach. One that you add as an action listener to your JButton and the other that you add to the frame to draw. Because they are different instances, the Roach that is drawn never receives an action and thus always has a count of 1.
This is actually a good example of why I dislike the practice of implementing listener interfaces on gui objects.

Categories

Resources