Monday, January 28, 2019

java - JFrame with Background Image and a JPanel



I have the following:



public class Frame {

public static void main(String[] args) {

JFrame frame = new JFrame("Frame Demo");


Panel panel = new Panel();

frame.add(panel);

frame.setBounds(250,100,800,500);
frame.setVisible(true);
}
}


public class Panel extends JPanel {

JButton singlePlayerButton;
JButton multiPlayerButton;

BufferedImage image;

Gui gui;



public Panel() {
gui = new Gui();
add(gui);

try {
image = ImageIO.read(new File("C:\\Users\\void\\workspace\\BattleShips\\src\\Testumgebung\\background\\battleship_main.jpg"));

} catch (IOException e) {
e.getMessage();
e.printStackTrace();

}

}

public void paintComponent(Graphics g) {
g.drawImage(image, 0, 0, this.getWidth(), this.getHeight(), null);
}


JLabel text;

JPanel mainMenuPanel;


private class Gui extends JPanel {

public Gui() {

setVisible(true);
setSize(500, 300);
setLayout(null);


mainMenuPanel = new JPanel();

mainMenuPanel.setLayout(null);
mainMenuPanel.setBackground(Color.BLUE);
mainMenuPanel.setBounds(150, 10, 200, 230);
add(mainMenuPanel);
mainMenuPanel.setVisible(true);



singlePlayerButton = new JButton("Single Player");
singlePlayerButton.setBounds(100,50 , 150, 40);

singlePlayerButton.setVisible(true);

mainMenuPanel.add(singlePlayerButton);

multiPlayerButton = new JButton("Multi Player");
multiPlayerButton.setBounds(100, 100, 150, 40);


multiPlayerButton.setVisible(true);
mainMenuPanel.add(multiPlayerButton);

repaint();
}

}
}



I just want a MainMenu with a BackgroundImage and buttons like Singleplayer etc. Do I have to set a Layout or is it possible without one. I just started with GUI, as you can probably assume from the code. Thanks in advance...


Answer




Do I have to set a Layout or is it possible without one




As a general rule of thumb, yes, you should make use of a layout manager where ever it's possible, it will save you a lot of work in the long run.



Based on you code and what I presume you want to do, I would suggest having a look at:






As additional advice:




  • Don't use null layouts, pixel perfect layouts are an illusion within modern ui design. There are too many factors which affect the individual size of components, none of which you can control. Swing was designed to work with layout managers at the core, discarding these will lead to no end of issues and problems that you will spend more and more time trying to rectify

  • Don't reference src ever, it will no exist once the program is exported. Try and avoid absolute paths as well, as different computers will place your program in different locations (and not all OS's have a concept of drive letters). Instead, in your case, you should be using something like getClass().getResource("/Testumgebung/background/battleship_main.jpg")

  • You should be calling super.paintComponent before performing any custom painting as a general rule.

  • In order for your background to show up, all components which are added to it should be made transparent (setOpaque(false)) so the background can show through.

  • Separate your classes into areas of responsibility. For example Panel should do nothing but manage the background image and should not be managing anything else, this would mean having the Gui added to the Panel as a separate step and not part of the Panels initialisation




As a conceptual example...



Be free



import java.awt.AlphaComposite;
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Color;

import java.awt.Composite;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Frame {

public static void main(String[] args) {


EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}


Panel background = new Panel();

JFrame frame = new JFrame("Testing");
frame.setContentPane(background);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new Gui());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}

});
}

public static class Panel extends JPanel {

BufferedImage image;

public Panel() {
setLayout(new BorderLayout());
try {

image = ImageIO.read(getClass().getResource("/Testumgebung/background/battleship_main.png"));
} catch (IOException e) {
e.printStackTrace();
}

}

@Override
public Dimension getPreferredSize() {
return image == null ? super.getPreferredSize() : new Dimension(image.getWidth(), image.getHeight());

}

@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, 0, 0, this);
}

}


public static class Gui extends JPanel {

private MainMenuPane mainMenuPane;
private CardLayout cardLayout;

public Gui() {

setOpaque(false);

setVisible(true);

cardLayout = new CardLayout();
setLayout(cardLayout);

mainMenuPane = new MainMenuPane();
// Other views

add(mainMenuPane, "MainMenu");

cardLayout.show(this, "MainMenu");


}

}

public static class MainMenuPane extends JPanel {

JButton singlePlayerButton;
JButton multiPlayerButton;

JLabel text;


public MainMenuPane() {

setLayout(new GridBagLayout());
setOpaque(false);
setBackground(Color.BLUE);

GridBagConstraints gbc = new GridBagConstraints();
gbc.ipadx = 20;
gbc.ipady = 20;


singlePlayerButton = new JButton("Single Player");

add(singlePlayerButton, gbc);

multiPlayerButton = new JButton("Multi Player");

add(multiPlayerButton, gbc);
}


@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
// This is faking transparency, so the background color
// will be see through
Graphics2D g2d = (Graphics2D) g.create();
Composite old = g2d.getComposite();
g2d.setComposite(AlphaComposite.SrcOver.derive(0.5f));
g2d.fillRect(0, 0, getWidth(), getHeight());
g2d.setComposite(old);

}

}

}

No comments:

Post a Comment

plot explanation - Why did Peaches' mom hang on the tree? - Movies & TV

In the middle of the movie Ice Age: Continental Drift Peaches' mom asked Peaches to go to sleep. Then, she hung on the tree. This parti...