How to set size and location of JButton in JPanel - java

I'm trying to set the size and location of a button on a panel using setBounds. It works when I put the button on the frame and have setLayout(null). But when placed on the panel, the button is always a set size at the top of the panel, if I set the layout to null, the frame just shows up blank.
import javax.swing.JFrame;
import javax.swing.*;
public class Main {
public static void main(String[] args) {
MyFrame cl=new MyFrame("A");
cl.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class MyFrame extends JFrame implements ActionListener{
MyPanel panel;
Container cont;
JButton b;
public MyFrame(String title) {
super(title);
panel= new MyPanel();
b = new JButton();
b.setBounds(100, 100, 100, 100 );
cont= this.getContentPane();
cont.setLayout(new BorderLayout());
cont.add(panel, BorderLayout.CENTER);
panel.add(b);
this.setLayout(null);
this.setVisible(true);
this.setSize(1000,1000);
}
}
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JPanel;
public class MyPanel extends JPanel {
public MyPanel() {
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
this.setBackground(Color.BLACK);
}
}

Related

How to properly call a shape drawing method in an ActionListener

I'm trying to make it so that after clicking on the button, a figure is added to the canvas.
But I can't correctly implement the listener method in the OvalDrawTool class.
package com.company;
import javax.swing.*;
import java.awt.*;
public class TestFrame extends JFrame{
public final OvalDrawTool odt = new OvalDrawTool();
public static void main(String[] args){
new TestFrame().start();
}
public void start(){
setLayout(new BorderLayout());
JPanel buttonsPanel = new JPanel();
JButton buttonOval = odt.getButtonOval();
buttonsPanel.add(buttonOval);
add(buttonsPanel, BorderLayout.NORTH);
setSize(500,500);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
}
I do not understand how should I create a Graphics object and pass it in actionPerformed method
package com.company;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class OvalDrawTool implements ActionListener{
public JButton getButtonOval() {
JButton buttonOval = new JButton();
buttonOval.setPreferredSize(new Dimension(100, 50));
buttonOval.setText("Oval");
buttonOval.addActionListener(this);
return buttonOval;
}
public void paintOval(Graphics g) {
g.setColor(Color.green);
g.fillOval(100, 100, 50, 50);
}
#Override
public void actionPerformed(ActionEvent e) {
paintOval();
}
}
I moved the figure drawing method into a separate class since I want to add more other shapes.

JPanel's size in function of another JPanel

I would like to adjust the size of a JPanel in function of another panel which contains it.
When I run my code, the panel is tiny and centered on the top of the content panel.
So here's my code :
package test;
import java.awt.Color;
import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class CodeForStackOverFlow {
public static void main(String[] args) {
Frame frame = new Frame();
}
}
class Frame extends JFrame {
private class Panel extends JPanel {
private JPanel content = new JPanel();
Panel() {
content.setBackground(Color.red);
this.add(content);
}
void adjustSize() {
this.content.setSize(new Dimension(this.getHeight(), this.getHeight()));
}
}
private Panel contentPane = new Panel();
Frame() {
this.setSize(new Dimension(500, 400));
this.setResizable(false);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setContentPane(contentPane);
contentPane.adjustSize();
this.setVisible(true);
}
}

Need to size JPanel to fill JFrame window

I have a JPanel that holds the main menu screen for a game project in my computer science class. The MainMenu class creates a panel that holds a button to start the game as well as a background image. However, when I add the panel to the parent JFrame (defined in OgGui class), there is about a cm of space between the top of the frame and where the panel/background image starts.
Does anyone know how to fill the frame window with the image?
//Creates parent JFrame to hold all game components
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class OgGui extends JPanel{
public static void main(String[] args){
JFrame frame = new JFrame ("OG Ball");
boolean start=true;
MainMenu mainm=new MainMenu();
while (start==true) {
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 600);
frame.setVisible(true);
frame.add(mainm);
start=mainm.returnscreen();
}
frame.add(new Draw());
//frame.pack();
}
}
MainMenu
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import javax.swing.JFrame;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JButton;
public class MainMenu extends JPanel{
//Creates JFrame and menu background
JPanel main = new JPanel();
ImageIcon icon = new ImageIcon("og.png");
JLabel menu = new JLabel(icon);
//Sets up button to begin play
JButton startBtn = new JButton();
boolean gamestart;
public MainMenu(){
startBtn.setSize(4, 4);
startBtn.setVisible(false);
startBtn.addActionListener(new startScreen());
main.add(menu);
main.add(startBtn);
main.revalidate();
this.add(main);
}
public boolean returnscreen() {
return gamestart; }
private class startScreen implements ActionListener{
public void actionPerformed(ActionEvent event){
gamestart=false;
}
}
}

Simple Pong game; Can't get paddle to move across the screen

I'm trying to create simple Pong game.
The first thing I'm working on is getting a paddle to move left or right when the user clicks the "Left" or "Right" button provided in the frame.
When the user clicks a button, an action listener in the MainPanel class changes the constant in the Paddle class called "paddlePosition" and then calls "repaint()".
However, it's not working, and the paddle is not moving. I know the buttons are working because it outputs "Hello World" and the value of paddlePosition but apparently something is wrong with the repaint.
I'm using Swing, JFrame, and Graphics2D to get everything working so far.
MY CLASSES:
Pong Frame (run class)
import java.awt.BorderLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
public class PongFrame extends JFrame{
private static final long serialVersionUID = 1L;
public PongFrame(){
ButtonPanel buttonPanel = new ButtonPanel();
MainPanel mainPanel = new MainPanel();
add(buttonPanel, BorderLayout.SOUTH);
add(mainPanel);
setSize(400, 400);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setVisible(true);
}
public static void main(String[] args) {
new PongFrame();
}
}
Main Panel:
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class MainPanel extends JPanel implements ActionListener{
public Paddle paddle;
public MainPanel(){
setSize(300, 300);
paddle = new Paddle();
}
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2 = (Graphics2D)g;
paddle.draw(g2);
}
public void actionPerformed(ActionEvent e) {
System.out.println("Hello World");
Paddle.movePaddleLeft();
System.out.println(Paddle.paddlePosition);
this.repaint();
}
}
Button Panel:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JPanel;
public class ButtonPanel extends JPanel {
private static final long serialVersionUID = 1L;
public MainPanel mainPanelActionListener = new MainPanel();
JButton left;
JButton right;
public ButtonPanel(){
left = new JButton("Left");
right = new JButton("Right");
add(left);
add(right);
left.addActionListener(mainPanelActionListener);
right.addActionListener(mainPanelActionListener);
}
}
Paddle:
import java.awt.Graphics2D;
public class Paddle{
public static int paddlePosition = 200;
private java.awt.Rectangle paddle;
private int centerCoordinateX;
private int centerCoordinateY;
public Paddle(){
//paddle = new java.awt.Rectangle(paddlePosition, 285, 100, 10); // x, y, width, height
}
public void draw(Graphics2D g2){
paddle = new java.awt.Rectangle(paddlePosition, 285, 100, 10);
g2.draw(paddle);
}
public static void movePaddleLeft(){
paddlePosition = (paddlePosition + 3);
}
}
Does anyone see what is wrong? Why won't the paddle move when the buttons are clicked?
In the ButtonPanel you're creating a new MainPanel. This causes you to create a new invisible panel that you're updating.
What you actually need to do, is send the MainPanel to your ButtonPanel in it's constructor.
Edit: (disclaimer: all code here is generated without an IDE)
In the PongFrame constructor do the following:
MainPanel mainPanel = new MainPanel();
ButtonPanel buttonPanel = new ButtonPanel(mainPanel);
This creates a ButtonPanel with a reference to the MainPanel.
Now for the ButtonPanel:
public MainPanel mainPanelReference;
JButton left;
JButton right;
public ButtonPanel(MainPanel mainPanelReference) {
this.left = new JButton("Left");
this.right = new JButton("Right");
add(left);
add(right);
this.mainPanelReference = mainPanelReference;
left.addActionListener(mainPanelReference);
right.addActionListener(mainPanelReference);
}

CardLayout in Java change by action in one of the 'cards'

I am making a simple game using a JFrame. I have made a simple "Start" screen which basically consists of a String and a JButton. I am picking up the button click with the actionPerformed(ActionEvent e) method. I don't know how to change the cards using a button click. This may seem like a simple problem to solve, but the twist comes with this: My main JFrame, my StartScreen and my JPanel where the game takes place are all in separate files. My main file, Virus.java, is where I create the JFrame. My file VirusGamePanel.java is where the game takes place. My file StartScreen.java is the screen with the button. I want to change 'cards' to the game screen when the player clicks the button. How can I do this?
My StartScreen.java file:
package virus;
import javax.swing.JPanel;
import java.awt.event.ActionListener;
import java.awt.Graphics;
import java.awt.Font;
import java.awt.Color;
import javax.swing.JButton;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.CardLayout;
public class StartScreen extends JPanel implements ActionListener{
private static final long serialVersionUID = 1L;
JButton start = new JButton("Start");
public StartScreen(){
start.addActionListener(this);
start.setBounds(new Rectangle(400,300,100,30));
this.add(start);
}
public void paint(Graphics g){
super.paint(g);
g.setFont(new Font("Impact",Font.BOLD,72));
g.setColor(Color.MAGENTA);
g.drawString("Virus",275,300);
}
public void actionPerformed(ActionEvent e)
{
if(e.getSource()==start)
{
//what to do here?
}
}
}
My Virus.java file:
package virus;
import javax.swing.*;
import java.awt.CardLayout;
import virus.StartScreen;
public class Virus extends JFrame{
private static final long serialVersionUID =1L;
JFrame jf = new JFrame("Virus");
static JPanel thegame = new JPanel(new CardLayout());
JPanel game = new VirusGamePanel();
JPanel start = new StartScreen();
public Virus(){
jf.setResizable(false);
jf.setSize(600,600);
jf.setLocationRelativeTo(null);
jf.setDefaultCloseOperation(EXIT_ON_CLOSE);
jf.setVisible(true);
jf.add(thegame);
thegame.add(start);
thegame.add(game);
}
public static void main(String[] args) {
new Virus();
}
}
You simply have to right this in your actionPerformed(...) method :
public void actionPerformed(ActionEvent e)
{
if(e.getSource()==start)
{
//what to do here?
CardLayout cardLayout = (CardLayout) Virus.thegame.getLayout();
cardLayout.next(Virus.thegame);
}
}
As very much pointed out by #kleopatra (THE EMPRESS) herself, don't override paint() instead do your painting stuff inside paintComponent(Graphics g) method of any JPanel/JComponent. Moreover, first add the components to your JFrame, once it's size is realized, then only set it to Visible, not before that. Instead of setting sizes for the JFrame simply override the JPanel's method getPreferredSize(), make it return some valid Dimension Object.
Do watch this sequence, as you write your code the next time :
public Virus(){
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setResizable(false);
thegame.add(start);
thegame.add(game);
jf.add(thegame);
jf.pack();
jf.setLocationRelativeTo(null);
jf.setVisible(true);
}
Here is your full code :
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.event.ActionListener;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Font;
import java.awt.Color;
import javax.swing.JButton;
import javax.swing.JLabel;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.CardLayout;
public class Virus extends JFrame{
private static final long serialVersionUID =1L;
JFrame jf = new JFrame("Virus");
static JPanel thegame = new JPanel(new CardLayout());
JPanel game = new VirusGamePanel();
JPanel start = new StartScreen();
public Virus(){
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setResizable(false);
thegame.add(start);
thegame.add(game);
jf.add(thegame);
jf.pack();
jf.setLocationRelativeTo(null);
jf.setVisible(true);
}
public static void main(String[] args) {
new Virus();
}
}
class StartScreen extends JPanel implements ActionListener{
private static final long serialVersionUID = 1L;
JButton start = new JButton("Start");
public StartScreen(){
start.addActionListener(this);
start.setBounds(new Rectangle(400,300,100,30));
this.add(start);
}
#Override
protected void paintComponent(Graphics g){
super.paintComponent(g);
g.setFont(new Font("Impact",Font.BOLD,72));
g.setColor(Color.MAGENTA);
g.drawString("Virus",275,300);
}
#Override
public Dimension getPreferredSize()
{
return (new Dimension(600, 600));
}
public void actionPerformed(ActionEvent e)
{
if(e.getSource()==start)
{
//what to do here?
CardLayout cardLayout = (CardLayout) Virus.thegame.getLayout();
cardLayout.next(Virus.thegame);
}
}
}
class VirusGamePanel extends JPanel
{
public VirusGamePanel()
{
JLabel label = new JLabel("I am ON", JLabel.CENTER);
add(label);
}
#Override
public Dimension getPreferredSize()
{
return (new Dimension(600, 600));
}
}
Your StartScreen class has to have access to the instance of the CardLayout of the JFrame and the instance of the VirusGamePanel class. You can pass these instances in the constructor or a setLayout method and setVirusGamePanel method of your StartScreen class.
Something like:
layout.next(virusGamePanel);
should work.

Categories