I have a problem, i searched on many topics how to place a JButton on a JPanel with a defined position. The most current answer i found is that, i should display layout of JFrame and set it to null, so here is my code. But the thing is that when i'm setting layout to null nothing works anymore.
package loto;
import javax.swing.JFrame;
import javax.swing.JButton;
public class Accueil extends JFrame{
public Accueil(){
this.setTitle("Accueil du loto");
this.setSize(1920,1080);
this.setLocationRelativeTo(null);
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
fond pan = new fond();
JButton suivant = new JButton("Commencer le Loto");
pan.setLayout(null);
pan.add(suivant);
suivant.setBounds(1800, 400, 40, 300);
this.setContentPane(pan);
while (true) {
this.repaint();
}
}
}
When you are new to Swing, you have to go by step by step UI,
Ensure the JPanel is added to your JFrame... fond pan = new fond(); Is it a JPanel subclass? you dont need to do this way you can
create JPanel jp = new JPanel();
add this JPanel component to JFrame by calling this.add(jp) in your constructor.
three important properties for every Swing display is a) setVisible b)setLayout c)setContentPane d) add
You have added JButton to Jpanel but you have not added Jpanel to JFrame.
add properties this.add(pan), this.setLayout(new FlowLayout()) in your constructor.
remove the while loop from your constructor.
Using null-Layout, you have to set a size and a location for your JButton like this:
suivant.setSize(120,20);
suivant.setLocation(x,y);
Related
Well, actually I have a Layout problem in java Swing. I simply want to add a JPanel on the bottom of a Frame - a coding snipplet that might be done with every web based language in about 5 Minutes. Not so in Java. I tried to add a jPanel to a jFrame, that Contains a jContentPane, set the size of the jPanel to what I need and to repaint and revalidate the jFrame, as well as setting the LayOutManager to null.
Java shows me in this case a full-width jPanel, that fills my whole jFrame.
Therefore I tried another approach: I divided my jPanel in a fully transparent jPanel on top and a 20%opaque jPanel on the bottom. Still it didn't work out as expected.
Since then I tried to resize the child jPanels of my new Panel and the Panel as well and tried to repaint and revalidate the jFrame. Without any effect.
Despite of my efforts, java still shows me a full sized 20%opaque jPanel on the whole jFrame, that now contains another 20%opaque jPanel on Top.
I know that this whole problem is caused by the LayoutManager, Java useless per Default. However, it is not an option to set the LayoutManager to null or even change the LayoutManager of our jFrame, because that would lead us to refactor the whole functionality of our tiny app we worked on for several weeks.
public void showUndoPanel() {
System .out.println("Show Undo Panel");
JPanel myPanel = new JPanel(null);
JPanel glassPanel = new JPanel();
JPanel ContentPanel = new JPanel();
JLabel myJLabel = new JLabel("Great Job!");
myPanel.setBackground(new Color(255,122,122,100));
glassPanel.setSize(650, 550);
glassPanel.setBackground(new Color(255,122,122,100));
myPanel.add(glassPanel);
ContentPanel.setSize(650, 30);
ContentPanel.setBackground(new Color(255,122,122,20));
ContentPanel.add(myJLabel);
myPanel.revalidate();
myPanel.repaint();
undoPanel = myPanel;
myJFrame.add(undoPanel);
myJFrame.revalidate();
}
What I expected:
What it actually does:
Well, I solved the problem by using a BoxLayoutManager and a RigidArea. In case if anyone else may encounter that problem again in the future, I decided to provide the code for this simple solution.
public void showUndoPanel() {
System .out.println("Show Undo Panel");
JPanel myPanel = new JPanel(null);
JPanel glassPanel = new JPanel();
JPanel ContentPanel = new JPanel();
JLabel myJLabel = new JLabel("Great Job!");
myPanel.setBackground(new Color(255,255,255,0));
myPanel.setLayout(new BoxLayout(myPanel, BoxLayout.PAGE_AXIS));
glassPanel.setSize(650, 650);
glassPanel.setBounds(0,0,650,550);
glassPanel.setBackground(new Color(255,122,122,0));
myPanel.add(glassPanel);
myPanel.add(Box.createRigidArea(new Dimension(0,450)));
ContentPanel.setSize(650, 30);
ContentPanel.setBounds(0,750,650,30);
ContentPanel.setBackground(new Color(255,122,122,20));
ContentPanel.add(myJLabel);
myPanel.add(ContentPanel);
myPanel.revalidate();
myPanel.repaint();
undoPanel = myPanel;
myJFrame.add(undoPanel);
myJFrame.revalidate();
}
Now it behaves as expected:
BorderLyout would make it easier to implement.
Note the comments in the following mre:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Main {
private static JFrame myJFrame;
public static void main(String[] args) {
myJFrame = new JFrame();
myJFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
myJFrame.setLocationRelativeTo(null);
showUndoPanel();
myJFrame.pack();
myJFrame.setVisible(true);
}
public static void showUndoPanel() {
JPanel myPanel = new JPanel();
myPanel.setBackground(new Color(255,255,255,0));
myPanel.setLayout(new BorderLayout());
JPanel glassPanel = new JPanel(); //uses FlowLayout by default
//glassPanel.setSize(650, 650); //use preferred size
glassPanel.setPreferredSize(new Dimension(650, 650));
//glassPanel.setBounds(0,0,650,550); //no need to set bounds. bounds are set by the layout manager
glassPanel.setBackground(new Color(255,122,122,0));
myPanel.add(glassPanel, BorderLayout.CENTER);
JPanel contentPanel = new JPanel(); //uses FlowLayout by default
//contentPanel.setSize(650, 30);//use preferred size
contentPanel.setPreferredSize(new Dimension(650, 30));
//contentPanel.setBounds(0,750,650,30); //no need to set bounds. bounds are set by the layout manager
contentPanel.setBackground(new Color(255,122,122,20));
JLabel myJLabel = new JLabel("Great Job!");
contentPanel.add(myJLabel);
myPanel.add(contentPanel, BorderLayout.SOUTH);
myJFrame.add(myPanel);
}
}
public class Create_JFrame extends JFrame{
public Create_JFrame(){
//Create a Frame
JFrame Frame = new JFrame("Bla-Bla");
JPanel Panel_1 = new JPanel();
JPanel Panel_2 = new JPanel();
JButton Option_1 = new JButton("Option-1");
//Layout management for Panels
Frame.getContentPane().add(BorderLayout.WEST, Panel_1);
//Add button to Panel
Panel_1.add(Option_1);
//Registering Listeners for all my buttons
Option_1.addActionListener(new ListenerForRadioButton(Panel_2));
//Make the frame visible
Frame.setSize(500, 300);
Frame.setVisible(true);
}//end of Main
}//end of Class
public class ListenerForRadioButton implements ActionListener{
JPanel Panel_2;
JButton browse = new JButton("Browse");
//Constructor, will be used to get parameters from Parent methods
public ListenerForRadioButton(JPanel Panel){
Panel_2 = Panel;
}
//Overridden function, will be used for calling my 'core code' when user clicks on button.
public void actionPerformed(ActionEvent event){
Panel_2.add(browse);
System.out.println("My listener is called");
}//end of method
}//end of class
Problem Statement:
I have 2 JPanel components in a a given JFrame. Panel_1 is having a Option_1 JButton. When user clicks on that I am expecting my code to add a JButton 'browse' in Panel_2 at runtime.
Runtime Output:
System is not adding any JButton in Panel_2. However, I see my debug message in output, indicating that system was successful in identifying user's click action on 'option-1'.
Question:
Why is JPanel not adding any component at Runtime?
Panel_2.add(browse);
Panel_2.revalidate();
adding a 'revalidate' will solve the problem.
There are some reasons. but:
usually it's because of using unsuitable LayoutManager.
sometimes it's because of adding the JPanel to it's root component in worng way. which any operation (add, remove,...) works but is not visible.
you must refresh the view when you make some changes on it, like adding or removing components to/from it.
try to use Panel_2.revalidate() to refresh.
if it doesn't work properly use it with Panel_2.repaint() method.
see Java Swing revalidate() vs repaint()
see Difference between validate(), revalidate() and invalidate() in Swing GUI
using setSize twice for your jframe is another way.
Frame.setSize(498, 300); then Frame.setSize(500, 300);
My JFrame is not displaying the button or background color that is set in the constructor. I am only getting a blank box when I start the program. Not sure what is wrong with the code.
//imports
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;;
public class StartingTheCode{
JButton CalculateButton;
JTextField Ans;
JPanel p;
JFrame f;
public static void main (String[] args){
new StartingTheCode();
}
//constructor
StartingTheCode(){
f = new JFrame("test");
f.setVisible(true);
f.setSize(600,600);
f.setLocationRelativeTo(null);
f.setResizable(false);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
p = new JPanel();
p.setBackground(Color.BLUE); // not displaying blue background
CalculateButton = new JButton("+"); // should display button
CalculateButton.setSize(30,30);
CalculateButton.setLocation(5,5);
}
}
You're not adding your button or your JPanel to anything, and so no JFrame is magically going to display them.
You should add your JButton to your JPanel via its add(...) method, and then add the JPanel to the JFrame via its add(...) method, and do so before setting the JFrame visible.
Most importantly, you should read the Swing tutorials, since I speak from experience when saying you'll get no-where just guessing at this stuff. This is all well explained there.
As an aside, avoid setting the sizes of any components and instead read the tutorial section on use of the layout managers as it will allow you to simplify and empower your code greatly.
You need to add your calculateButton to the JPanel with p.add(calculateButton) and add the panel to the frame with f.add(p)
I am trying to make a Rock, Paper, Scissors game and I have added 3 buttons to the frame, however when I launch the program two of the buttons don't appear until you hover over them, anyone have any idea why?
import javax.swing.*;
import java.awt.event.*;
import java.util.Random;
import java.awt.FlowLayout;
import javax.swing.JOptionPane;
public class RPSFrame extends JFrame {
public static void main(String [] args){
new RPSFrame();
}
public RPSFrame(){
JFrame Frame1 = new JFrame();
this.setSize(500,500);
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setTitle("Rock, Paper or Scissors game");
this.setLocationRelativeTo(null);
ClickListener cl1 = new ClickListener();
ClickListener cl2 = new ClickListener();
ClickListener cl3 = new ClickListener();
JPanel panel1 = new JPanel();
JLabel label1 = new JLabel("Result:");
panel1.setLayout(new FlowLayout(FlowLayout.CENTER, 25, 25));
this.add(panel1);
this.setVisible(false);
JPanel panel2 = new JPanel();
JButton Rock = new JButton("Rock");
Rock.addActionListener(cl1);
panel2.setLayout(new FlowLayout(FlowLayout.LEFT));
panel2.add(Rock);
this.add(panel2);
this.setVisible(true);
JPanel panel3 = new JPanel();
JButton Paper = new JButton("Paper");
Paper.addActionListener(cl2);
panel3.setLayout(new FlowLayout(FlowLayout.CENTER));
panel3.add(Paper);
this.add(panel3);
this.setVisible(true);
JPanel panel4 = new JPanel();
JButton Scissors = new JButton("Scissors");
Scissors.addActionListener(cl3);
panel4.setLayout(new FlowLayout(FlowLayout.RIGHT));
panel4.add(Scissors);
this.add(panel4);
this.setVisible(true);
}
private class ClickListener implements ActionListener{
public void actionPerformed(ActionEvent e){
if(e.getSource() == "Rock"){
int AI = new Random().nextInt(3) + 1;
JOptionPane.showMessageDialog(null, "I have been clicked!");
}
}
}
}
The setVisible(true) statement should be invoked AFTER all the components have been added to the frame.
You currently have two setVisible(...) statements, so you need to get rid of the first one.
Edit:
Took a second look at the code. You have multiple setVisible(...) statements. Get rid of them all except for the last one.
Don't create separate panels for each button. Instead you create one panel (called buttonPanel) for all the buttons. In your case you might use a horizontal BoxLayout. Add a button to the panel, then add glue then add a button, then add glue and then add your final button. Then add this buttonPanel to the NORTH of the frame. ie. this.add(buttonPanel, BorderLayout.NORTH). Read the section from the Swing tutorial on How to Use Box Layout for more information on how the layout works and on what glue is.
The problem is that JFrame has a default BorderLayout. When you just add(component) without specifying a BorderLayout.[POSITION] e.g add(panel, BorderLayout.SOUTH), then the component will get added to the CENTER. The problem with that is each POSITION can only have one component. So the only component you see id the last one you add.
Now I don't know after specifying the positions, if you will get your desired result. A BorderLayout may not be the right fit. But just to see a change, you can set the layout to GridLayout(0, 1) and you will see the component.
this.setLayout(new GridLayout(0, 1));
If this is not the result you want, then you should look over Laying out Components within a Container to learn the different layouts available to you.
Also as I pointed out in my comment
if(e.getSource() == "Rock"){
with the above, you are trying to compare an object (ultimately a button) with a String. Instead you will want to compare the actionCommand
String command = e.getActionCommand();
if("Rock".equals(command)){
I need to write a simple tennis game.
To move between different windows(panel with main menu, panel with game, panel with settings) I decided to use inner classes extends JPanel and replace it when some events like start new game occurs.
but the problem is - it doesn't see my inner class. I mean I add it to JFrame
mainframe.add(new MainMenuPanel());
but there is nothing on the screen when I run program. What's the problem?
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class MainFrame{
JFrame mainframe;
public static void main(String[] args){
new MainFrame();
}
public MainFrame() {
mainframe = new JFrame();
mainframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainframe.setSize(300, 400);
mainframe.setTitle("X-Tennis v0.1");
mainframe.add(new MainMenuPanel());
mainframe.getContentPane().setLayout(new GridLayout());
mainframe.getContentPane().setBackground(Color.WHITE);
mainframe.setVisible(true);
}
public class MainMenuPanel extends JPanel {
JPanel mainmenupanel;
JLabel label1;
JButton btnNewGame,btnJoinGame;
ImageIcon iconNewGame,iconJoinGame;
public MainMenuPanel(){
mainmenupanel = new JPanel();
label1 = new JLabel("X-TENNIS");
label1.setFont(new Font("Comic Sans MS",Font.ITALIC,20));
label1.setForeground(Color.BLUE);
btnNewGame = new JButton("New Game", iconNewGame);
btnNewGame.setFocusPainted(false);
btnNewGame.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent e){
JOptionPane.showMessageDialog(mainframe, "New game");
//delete current panel and add another to mainframe
}
}
);
btnNewGame.setPreferredSize(new Dimension(140,30));
btnJoinGame = new JButton("Join game",iconJoinGame);
mainmenupanel.add(label1);
mainmenupanel.add(btnNewGame);
}
}
}
There is no need for mainmenupanel within the MainMenuPanel class as MainMenuPanel is a JPanel itself
Simple add all the components in MainMenuPanel directly to itself
You create a new JPanel, mainmenupanel, inside MainMenuPanel but never add that to the container itself. You could do
add(mainmenupanel);
If you intend for this JPanel to occupy the full area of the parent, then you can simply add your components directly to your instance of MainMenuPanel as indicated by #Mad
First you should add your component to the ContentPane. In Swing, all the non-menu components displayed by the JFrame should be in the ContentPane.
mainframe.getContentPane().add(new MainMenuPanel());
Edit: I was wrong about the content pane, see #MadProgrammer comment.
Then you have to add the JPanel that you create in MainMenuPanel to the MainMenuPanel instance itself.
add(mainmenupanel);
But you should probably get rid of that intermediary container itself and add your labels to the MainMenuPanel instance itself:
add(label1);
add(btnNewGame);
mainmenupanel.add(label1);
mainmenupanel.add(btnNewGame);
try this :
super.add(label1);
super.add(btnNewGame);