I have this code which is basically a home menu with two clickable rectangles.
- Start Game
- Info
Start Game works fine. Info is what is not really working. When pressed, the info screen will appear, but the home menu buttons will still be there though not visible (can be clicked).. it seems that when the info menu is appearing, the home menu buttons are not getting cleared. Also, any point on the info menu is clickable and will show the home menu again. (not what intended, only the back buttons should do that).
How can I fix those problems ?
package test;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.font.FontRenderContext;
import java.awt.font.TextLayout;
import java.awt.geom.Rectangle2D;
import java.awt.image.ImageObserver;
import java.awt.image.ImageProducer;
public class HomeMenu extends JComponent implements MouseListener, MouseMotionListener {
private static final String GAME_TITLE = "BRICK DESTROY";
private static final String START_TEXT = "START";
private static final String INFO_TEXT = "INFO";
private static final String howtoPlay = """
1- Click Start\n
2- Choose the mode\n
3- Each mode has 3 levels\n
4- To play/pause press space, use 'A' and 'D' to move\n
5- To open pause menu press 'ESC'\n
6- To open DebugPanel press 'ALT-SHIFT-F1'""";
private static final String backText = "BACK";
private static final Color BORDER_COLOR = new Color(200,8,21); //Venetian Red
private static final Color DASH_BORDER_COLOR = new Color(255, 216, 0);//school bus yellow
private static final Color TEXT_COLOR = new Color(255, 255, 255);//white
private static final Color CLICKED_BUTTON_COLOR = Color.ORANGE.darker();;
private static final Color CLICKED_TEXT = Color.ORANGE.darker();
private static final int BORDER_SIZE = 5;
private static final float[] DASHES = {12,6};
private Rectangle menuFace;
private Rectangle infoFace;
private Rectangle startButton;
private Rectangle infoButton;
private Rectangle backButton;
private BasicStroke borderStoke;
private BasicStroke borderStoke_noDashes;
private Image img = Toolkit.getDefaultToolkit().createImage("1.jpeg");
private Font gameTitleFont;
private Font infoFont;
private Font buttonFont;
private Font howtoPlayFont;
private GameFrame owner;
private boolean startClicked;
private boolean infoClicked = false;
private boolean backClicked = false;
public HomeMenu(GameFrame owner,Dimension area){
this.setFocusable(true);
this.requestFocusInWindow();
this.addMouseListener(this);
this.addMouseMotionListener(this);
this.owner = owner;
menuFace = new Rectangle(new Point(0,0),area);
infoFace = new Rectangle(new Point(0,0),area);
this.setPreferredSize(area);
Dimension btnDim = new Dimension(area.width / 3, area.height / 12);
startButton = new Rectangle(btnDim);
infoButton = new Rectangle(btnDim);
backButton = new Rectangle(btnDim);
borderStoke = new BasicStroke(BORDER_SIZE,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND,0,DASHES,0);
borderStoke_noDashes = new BasicStroke(BORDER_SIZE,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND);
gameTitleFont = new Font("Calibri",Font.BOLD,28);
infoFont = new Font("Calibri",Font.BOLD,24);
buttonFont = new Font("Calibri",Font.BOLD,startButton.height-2);
howtoPlayFont = new Font("Calibri",Font.PLAIN,14);
}
public void paint(Graphics g){
drawMenu((Graphics2D)g);
}
public void drawMenu(Graphics2D g2d){
if(infoClicked) {
drawInfoMenu(g2d);
return;
}else{
drawContainer(g2d);
Color prevColor = g2d.getColor();
Font prevFont = g2d.getFont();
double x = menuFace.getX();
double y = menuFace.getY();
g2d.translate(x,y);
//methods calls
drawText(g2d);
drawButton(g2d);
//end of methods calls
g2d.translate(-x,-y);
g2d.setFont(prevFont);
g2d.setColor(prevColor);
}
Toolkit.getDefaultToolkit().sync();
}
private void drawContainer(Graphics2D g2d){
Color prev = g2d.getColor();
//g2d.setColor(BG_COLOR);
g2d.drawImage(img,0,0,menuFace.width,menuFace.height,this);
//g2d.fill(menuFace);
Stroke tmp = g2d.getStroke();
g2d.setStroke(borderStoke_noDashes);
g2d.setColor(DASH_BORDER_COLOR);
g2d.draw(menuFace);
g2d.setStroke(borderStoke);
g2d.setColor(BORDER_COLOR);
g2d.draw(menuFace);
g2d.setStroke(tmp);
g2d.setColor(prev);
}
private void drawText(Graphics2D g2d){
g2d.setColor(TEXT_COLOR);
FontRenderContext frc = g2d.getFontRenderContext();
Rectangle2D gameTitleRect = gameTitleFont.getStringBounds(GAME_TITLE,frc);
int sX,sY;
sY = (int)(menuFace.getHeight() / 4);
sX = (int)(menuFace.getWidth() - gameTitleRect.getWidth()) / 2;
sY += (int) gameTitleRect.getHeight() * 1.1;//add 10% of String height between the two strings
g2d.setFont(gameTitleFont);
g2d.drawString(GAME_TITLE,sX,sY);
}
private void drawButton(Graphics2D g2d){
FontRenderContext frc = g2d.getFontRenderContext();
Rectangle2D txtRect = buttonFont.getStringBounds(START_TEXT,frc);
Rectangle2D mTxtRect = buttonFont.getStringBounds(INFO_TEXT,frc);
g2d.setFont(buttonFont);
int x = (menuFace.width - startButton.width) / 2;
int y =(int) ((menuFace.height - startButton.height) * 0.5);
startButton.setLocation(x,y);
x = (int)(startButton.getWidth() - txtRect.getWidth()) / 2;
y = (int)(startButton.getHeight() - txtRect.getHeight()) / 2;
x += startButton.x;
y += startButton.y + (startButton.height * 0.9);
if(startClicked){
Color tmp = g2d.getColor();
g2d.setColor(CLICKED_BUTTON_COLOR);
g2d.draw(startButton);
g2d.setColor(CLICKED_TEXT);
g2d.drawString(START_TEXT,x,y);
g2d.setColor(tmp);
}
else{
g2d.draw(startButton);
g2d.drawString(START_TEXT,x,y);
}
x = startButton.x;
y = startButton.y;
y *= 1.3;
infoButton.setLocation(x,y);
x = (int)(infoButton.getWidth() - mTxtRect.getWidth()) / 2;
y = (int)(infoButton.getHeight() - mTxtRect.getHeight()) / 2;
x += infoButton.getX();
y += infoButton.getY() + (startButton.height * 0.9);
if(infoClicked){
Color tmp = g2d.getColor();
g2d.setColor(CLICKED_BUTTON_COLOR);
g2d.draw(infoButton);
g2d.setColor(CLICKED_TEXT);
g2d.drawString(INFO_TEXT,x,y);
g2d.setColor(tmp);
}
else{
g2d.draw(infoButton);
g2d.drawString(INFO_TEXT,x,y);
}
}
private void drawInfoMenu(Graphics2D g2d){
FontRenderContext frc = g2d.getFontRenderContext();
Rectangle2D infoRec = infoFont.getStringBounds(INFO_TEXT,frc);
Color prev = g2d.getColor();
Stroke tmp = g2d.getStroke();
g2d.setStroke(borderStoke_noDashes);
g2d.setColor(DASH_BORDER_COLOR);
g2d.draw(infoFace);
g2d.setStroke(borderStoke);
g2d.setColor(BORDER_COLOR);
g2d.draw(infoFace);
g2d.fillRect(0,0,infoFace.width,infoFace.height);
g2d.setStroke(tmp);
g2d.setColor(prev);
g2d.setColor(TEXT_COLOR);
int sX,sY;
sY = (int)(infoFace.getHeight() / 15);
sX = (int)(infoFace.getWidth() - infoRec.getWidth()) / 2;
sY += (int) infoRec.getHeight() * 1.1;//add 10% of String height between the two strings
g2d.setFont(infoFont);
g2d.drawString(INFO_TEXT,sX,sY);
TextLayout layout = new TextLayout(howtoPlay, howtoPlayFont, frc);
String[] outputs = howtoPlay.split("\n");
for(int i=0; i<outputs.length; i++) {
g2d.setFont(howtoPlayFont);
g2d.drawString(outputs[i], 40, (int) (80 + i * layout.getBounds().getHeight() + 0.5));
}
backButton.setLocation(getWidth()/3,getHeight()-50);
int x = (int)(backButton.getWidth() - infoRec.getWidth()) / 2;
int y = (int)(backButton.getHeight() - infoRec.getHeight()) / 2;
x += backButton.x+11;
y += backButton.y + (layout.getBounds().getHeight() * 1.35);
backButton.setLocation(getWidth()/3,getHeight()-50);
if(backClicked){
Color tmp1 = g2d.getColor();
g2d.setColor(CLICKED_BUTTON_COLOR);
g2d.draw(backButton);
g2d.setColor(CLICKED_TEXT);
g2d.drawString(backText,x,y);
g2d.setColor(tmp1);
infoClicked = false;
repaint();
}
else{
g2d.draw(backButton);
g2d.drawString(backText,x,y);
}
}
@Override
public void mouseClicked(MouseEvent mouseEvent) {
Point p = mouseEvent.getPoint();
if(startButton.contains(p)){
owner.enableGameBoard();
}
else if(infoButton.contains(p)){
infoClicked = true;
}
else if(backButton.contains(p)){
infoClicked = false;
}
repaint();
}
@Override
public void mousePressed(MouseEvent mouseEvent) {
Point p = mouseEvent.getPoint();
if(startButton.contains(p)){
startClicked = true;
repaint(startButton.x,startButton.y,startButton.width+1,startButton.height+1);
}
else if(infoButton.contains(p)){
infoClicked = true;
}
else if(backButton.contains(p)){
infoClicked = false;
}
repaint();
}
@Override
public void mouseReleased(MouseEvent mouseEvent) {
if(startClicked){
startClicked = false;
repaint(startButton.x,startButton.y,startButton.width+1,startButton.height+1);
}
else if(infoClicked){
infoClicked = false;
}
else if(backClicked){
infoClicked = true;
}
repaint();
}
@Override
public void mouseEntered(MouseEvent mouseEvent) {
}
@Override
public void mouseExited(MouseEvent mouseEvent) {
}
@Override
public void mouseDragged(MouseEvent mouseEvent) {
}
@Override
public void mouseMoved(MouseEvent mouseEvent) {
Point p = mouseEvent.getPoint();
if(startButton.contains(p) || infoButton.contains(p) || backButton.contains(p)) {
this.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
}
else {
this.setCursor(Cursor.getDefaultCursor());
}
}
}
Here are the images of both windows main menu