How to add a background image in JPanel? - java

I did exactly according to the excellent guide but it does not work, I want to click a button that will change the background of the program. I would love to make the picture change
Code Guide https://stackhowto.com/how-to-set-background-image-in-java-swing/
public class Main {
public static void main(String[] args) {
JFrame frame = new JFrame("Display an image in the background");
final ImageIcon icon = new ImageIcon("background.png");
JTextArea text = new JTextArea()
{
Image img = icon.getImage();
// instance initializer
{setOpaque(false);}
public void paintComponent(Graphics graphics)
{
graphics.drawImage(img, 0, 0, this);
super.paintComponent(graphics);
}
};
JScrollPane pane = new JScrollPane(text);
Container content = frame.getContentPane();
content.add(pane, BorderLayout.CENTER);
frame.setDefaultCloseOperation(3);
frame.setSize(400, 300);
frame.setVisible(true);
}
}

Related

paintComponent is not erasing JPanel

The program is to display 3 buttons on the JPanel. The program is compiled successfully. The GUI Window then appears and is empty. When I minimise the window and then maximise it again the Buttons appear. On doing this again another set of Buttons appear. The button keeps on appearing when the window is refreshed and the older data is kept intact.
JPanel Class
class MyJPanel extends JPanel {
JButton jb1, jb2, jb3;
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.WHITE);
g.fillRect(0, 0, this.getWidth(), this.getHeight());
jb1 = new JButton();
jb2 = new JButton("Green");
jb3 = new JButton("Blue");
//g.drawString("Welcome!", 100, 100);
ImageIcon img = new ImageIcon("next.png");
jb1.setIcon(img);
jb1.setToolTipText("Button 1");
this.add(jb1);
this.add(jb2);
this.add(jb3);
}
}
JFrame Class
class MyJFrame extends JFrame {
MyJPanel mjp;
public MyJFrame(String title) {
super(title);
mjp = new MyJPanel();
Container ct = getContentPane();
ct.add(mjp);
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
Driver Class
class Gui5JButton {
public static void main(String[] args) {
MyJFrame mjf = new MyJFrame("Prakhar");
mjf.repaint();
}
}
paintComponent is called everytime your panel needs to be redraw, so everytime you minimize the window it will put the button again. If I understood what you want to do correctly, you need to remove the override and put this code :
jb1 = new JButton();
jb2 = new JButton("Green");
jb3 = new JButton("Blue");
//g.drawString("Welcome!", 100, 100);
ImageIcon img = new ImageIcon("next.png");
jb1.setIcon(img);
jb1.setToolTipText("Button 1");
this.add(jb1);
this.add(jb2);
this.add(jb3);
in the constructor of your MyJPanel class.

In Java, how can I combine CardLayout and GridBagLayout and still be able to switch panels?

New to Java and very new to Java's GUI classes. I'm making a GUI to showcase a few games, but am having difficulties switching panels. I read about CardLayout but I'm having an issue implementing it because I can't get the JPanels that hold the different games' GUIs to send their events back to the class that uses the CardLayout. (This is probably where I'm going wrong -- I can't get my head around how to structure this properly.)
This is my main menu (called mainContainer):
This is the overall structure of the GUI driver:
public class CasinoDriverGUI {
//CardLayout is here in the main method Container contentPane.add(cardLayout)
public static void main(String[] args) throws IOException
//MainContainer is MenuScreen: GridBagLayout for nice button placement
static class MainContainer extends JPanel implements ActionListener{...}
static class CrapsContainer extends JPanel implements ActionListener{...}
static class PokerContainer extends JPanel implements ActionListener{...}
//Button with custom look
class CButton extends JButton
}//end CasinoDriverGUI
Here is the main method: It grabs an image from a website and then adds the menu screen (mainContainer) to the contentPane. The menu screen uses GridBagLayout, but it's where the button components are added. Because of this, I can't figure out how to get the CardLayout of the contentPane to listen to the menu screen's buttons. I tried using ContainerListener but that seemed to be a dead end.
public class CasinoDriverGUI {
public static void main(String[] args) throws IOException {
// load the texture resource image
System.out.println("Please wait, Loading Texture : http://www.pngall.com/wp-content/uploads/2016/04/Casino-PNG-Pic.png");
MainContainer.textureImg = ImageIO.read(new URL("http://www.pngall.com/wp-content/uploads/2016/04/Casino-PNG-Pic.png"));
System.out.println("Loading finished. Starting the Casino!");
MainContainer.textureImg = MainContainer.textureImg.getSubimage(0, 0, 580, 309);
// Starting the Swing GUI in the EDT
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
final CardLayout cardLayout = new CardLayout();
JFrame frame = new JFrame("Midnight Casino");
// frame about the size of background src image
frame.setPreferredSize(new Dimension(580, 329));
final Container contentPane = frame.getContentPane();
contentPane.setLayout(cardLayout);
MainContainer mainContainer = new MainContainer();
mainContainer.setPreferredSize( frame.getPreferredSize() );
contentPane.add(mainContainer, "mainContainer");
frame.pack();
frame.setLocationRelativeTo(null);
frame.setResizable(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
});
}
As I have it so far, I have just tried using the "menu screen" (mainContainer) to instantiate all the games' panels and use an ActionListener on some buttons to simply call thisGame.setVisible(true). but this is forcing the window to be minimized and re-opened for any change to be detectable.Edit: fixed this.
Any advice on how I can restructure this code to be able to switch the panels from the menu screen to the different game's panels? (Code is below, but the craps and poker GUIs are incomplete.. just using the code as placeholders.
public class CasinoDriverGUI {
public static void main(String[] args) throws IOException {
// load the texture resource image
System.out.println("Please wait, Loading Texture : http://www.pngall.com/wp-content/uploads/2016/04/Casino-PNG-Pic.png");
MainContainer.textureImg = ImageIO.read(new URL("http://www.pngall.com/wp-content/uploads/2016/04/Casino-PNG-Pic.png"));
System.out.println("Loading finished. Starting the Casino!");
MainContainer.textureImg = MainContainer.textureImg.getSubimage(0, 0, 580, 309);
// Starting the Swing GUI in the EDT
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
final CardLayout cardLayout = new CardLayout();
JFrame frame = new JFrame("Midnight Casino");
// frame about the size of background src image
frame.setPreferredSize(new Dimension(580, 329));
final Container contentPane = frame.getContentPane();
contentPane.setLayout(cardLayout);
MainContainer mainContainer = new MainContainer();
mainContainer.setPreferredSize( frame.getPreferredSize() );
contentPane.add(mainContainer, "mainContainer");
frame.pack();
frame.setLocationRelativeTo(null);
frame.setResizable(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
});
}
static class MainContainer extends JPanel implements ActionListener
{
public BufferedImage gradientImage = null;
public static BufferedImage textureImg; // static for ease
public static boolean loadingFinished = false;
protected JButton pokerJBtn;
protected JButton crapsJBtn;
CrapsContainer crapsContainer;
PokerContainer pokerContainer;
public MainContainer() {
setBorder(new EmptyBorder(50, 50, 50, 50)); // setting the insets
setLayout(new GridBagLayout());
// working with GridBagConstraints
GridBagConstraints labCnst = new GridBagConstraints();
GridBagConstraints txtCnst = new GridBagConstraints();
labCnst.ipady = txtCnst.ipady = 10;
labCnst.fill = GridBagConstraints.HORIZONTAL;
labCnst.gridwidth = 1;
labCnst.weightx = 0.3;
labCnst.gridx = 2;
labCnst.gridy = 2;
labCnst.ipady = 13;
labCnst.insets = new Insets(0, 0, 0, 150);
pokerJBtn = new CButton("5-Card Poker");
add(pokerJBtn, labCnst);
labCnst.gridx = 2;
labCnst.gridy = 20;
labCnst.ipady = 13;
labCnst.insets = new Insets(0, 0, 0, 150);
crapsJBtn = new CButton("Craps");
add(crapsJBtn, labCnst);
crapsContainer = new CrapsContainer();
pokerContainer = new PokerContainer();
add(crapsContainer);
add(pokerContainer);
crapsContainer.setVisible(false);
pokerContainer.setVisible(false);
//Add Action Listeners
crapsJBtn.addActionListener(this);
pokerJBtn.addActionListener(this);
}
public void changeCompFont(JComponent comp)
{
comp.setForeground(Color.WHITE);
comp.setFont(getFont().deriveFont(Font.BOLD, 13));
}
// To PAINT THE TEXTURE ABOVE THE COMPONENTS
#Override
public void paint(Graphics g)
{
super.paint(g);
Graphics2D g2d = (Graphics2D)g.create(); // cloning
Rectangle2D txRect = new Rectangle2D.Double(0, 0, textureImg.getWidth(), textureImg.getHeight());
TexturePaint txPaint = new TexturePaint(textureImg, txRect);
g2d.setPaint(txPaint);
//make the texture transparent
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.233f));
g2d.fillRect(0, 0, getWidth(), getHeight());
g2d.dispose();// disposing the graphics object
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
if(gradientImage==null || gradientImage.getHeight() != getHeight() )
{
gradientImage = createGradientImg();
}
g2d.drawImage(gradientImage, 0, 0, getWidth(), getHeight(), this);
g2d.dispose();
}
public BufferedImage createGradientImg()
{
BufferedImage image = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB);
// background gradient paint, linear gradient paint for the background
// Gradient paint rendering could be made more optimized
LinearGradientPaint lgrPaint = new LinearGradientPaint(0.0f, 0.0f, getWidth(), getHeight(),
new float[] { 0.0f, 0.5f, 0.6f, 1.0f },
new Color[] { new Color(0x0530E),// new Color[] { new Color(0x002AFF),
new Color(0x0A31B),
new Color(0x0A31B),
new Color(0x0530E ) });
Graphics2D g2d = (Graphics2D) image.getGraphics();
g2d.setPaint(lgrPaint);
//g2d.shear(0.2, 0);
g2d.fillRect(0, 0, getWidth(), getHeight());
g2d.dispose();
g2d.drawImage(textureImg, 0, 0, getWidth(), getHeight(), null);
return image;
}
#Override
public void actionPerformed(ActionEvent e)
{
if (e.getSource() == pokerJBtn)
{
pokerContainer.setVisible(true);
}
else if (e.getSource() == crapsJBtn){
this.setVisible(false);
invalidate();
crapsContainer.setVisible(true);
revalidate();
repaint();
}
}
}
//Either Flow, Border, or GridBag Layout
static class CrapsContainer extends JPanel implements ActionListener
{...}
//Either Flow, Border, or GridBag Layout
static class PokerContainer extends JPanel implements ActionListener
{...}
//Custom Button to change aesthetic look
class CButton extends JButton
{...}
}

How do I change what's being displayed in Java Swing?

I don't really know how to word this question, but I can explain what I'm trying to do.
I have my program drawing a basic menu with a background image and 3 buttons along the bottom. I want to make it so that when I press one of the buttons, the menu and the background image change to a different scene. Like pressing play to start a game or pressing options to go to an option menu.
This is my code for the primary menu:
private final void initUI() {
JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
add(panel);
panel.add(Box.createVerticalGlue());
JPanel bottom = new JPanel();
bottom.setAlignmentX(1f);
bottom.setLayout(new BoxLayout(bottom, BoxLayout.X_AXIS));
JButton plyBtn = new JButton("Play");
plyBtn.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent event){
GameFrame_Test1 game1 = new GameFrame_Test1();
game1.setVisible(true);
}
});
JButton opBtn = new JButton("Options");
JButton quitButton = new JButton("Exit");
quitButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent event) {
System.exit(0);
}
});
bottom.add(plyBtn);
bottom.add(Box.createRigidArea(new Dimension(100, 0)));
bottom.add(opBtn);
bottom.add(Box.createRigidArea(new Dimension(100, 0)));
bottom.add(quitButton);
bottom.add(Box.createRigidArea(new Dimension(100, 0)));
panel.add(new GraphicTest_1());
panel.add(bottom);
panel.add(Box.createRigidArea(new Dimension(0,15)));
setTitle("Justice GUI");
setSize(1280, 720);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
DisplayFrame ex = new DisplayFrame();
ex.setVisible(true);
}
});
}
This is my code for the frame I want to change to so far:
class GameFrame_Test1 extends JPanel{
private Image mshi;
public GameFrame_Test1() {
loadImage();
setSurfaceSize();
}
private void loadImage() {
mshi = new ImageIcon("content/Placeholder_Map.png").getImage();
}
private void setSurfaceSize() {
Dimension d = new Dimension();
d.width = mshi.getWidth(null);
d.height = mshi.getHeight(null);
setPreferredSize(d);
}
private void doDrawing(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
g2d.drawImage(mshi, 0, 0, null);
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
doDrawing(g);
}
}
I am very new to Java Swing, and this is a test program for me to learn how to use it. I have looked online for a solution, but not being able to word my question makes it hard. Thanks to anyone who can help!
I want to make it so that when I press one of the buttons, the menu and the background image change to a different scene.
You should be using a Card Layout as the layout manager of the content panel. Then you can swap a different panel on the frame when a button is clicked.
Check out the section from the Swing tutorial on How to Use CardLayout for more information and working examples.

How do I place components in specific(more or less) positions using GridBagLayout?

I want to create a window where there is a background image and components on top of that. I have managed to get the components and background 'stacked', but my problem is positioning the components.
I have tried using AbsoluteLayout but it doesn't seem to work.
This is my (beginner) code thus far:
public class RegionPrompt extends JPanel {
public RegionPrompt () throws IOException {
JFrame frame = new JFrame("Map");
GridBagConstraints gbc = new GridBagConstraints();
JPanel pane = new JPanel() {
URL image2 = getClass().getResource("map.jpg");
BufferedImage image = ImageIO.read(image2);
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, 0, 0, image.getWidth(), image.getHeight(), this);
}
};
frame.setContentPane(pane);
JPanel pane2 = new JPanel();
pane2.setOpaque(false);
pane2.setSize(DefaultGUI.defaultSize);
pane2.setLayout(new GridBagLayout());
JButton c = new JButton("Map Location");
//gbc.gridx = 0;
//gbc.gridy = 0;
c.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(null, "Location information", JOptionPane.INFORMATION_MESSAGE);
}
});
pane2.add(c,gbc);
frame.add(pane2);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(653, 448);
frame.setVisible(true);
}
}
Any help (as well as forgiveness for this code chunk) is greatly appreciated!

how can i put a JButton on an image?

I am trying to fix a JFrame where there will be a background image and on the image JButtons which will do some commands. I try to do it without layout because i want to put small buttons in some specific locations on the JFrame but every time i do it, the background image comes to the front or the JFrame has size equal to the JFrame size. With the following code, the JButton has the same size to JFrame. I have tried to change the size and location of the JButton but nothing. Can you help me please?
here is the code
public final class Test extends JComponent
{
private Image background;
private JFrame frame;
private Dimension dimension;
public Test()
{
dimension = new Dimension(15, 15);
frame = new JFrame("Iphone");
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(this);
frame.setBounds(641, 0, 344, 655);
frame.setVisible(true);
test = displayButton("tigka");
frame.getContentPane().add(test);
}
public void update(Graphics g)
{
paint(g);
}
public void paintComponent(Graphics g)
{
super.paintComponents(g);
g.drawImage(background, 0, 25, null); // draw background
// label();
test = displayButton("test");
}
public JButton displayButton(String name)
{
JButton button = new JButton(name);
button.setSize(100, 100);
button.setPreferredSize(dimension);
return button;
}
You need to change the content pane to get a background for your Frame.
public static void main(String[] args) throws IOException {
JFrame frame = new JFrame("Test");
frame.setContentPane(new JPanel() {
BufferedImage image = ImageIO.read(new URL("http://upload.wikimedia.org/wikipedia/en/2/24/Lenna.png"));
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, 0, 0, 300, 300, this);
}
});
frame.add(new JButton("Test Button"));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(300, 300);
frame.setVisible(true);
}
Output:
Have you tried using a JLabel with HTML in the label? Something like this:
import javax.swing.*;
public class SwingImage1
{
public static void main( String args[] )
{
JFrame frm = new JFrame( "Swing Image 1" );
JLabel lbl = new JLabel( "<html><body><img src=\"http://liv.liviutudor.com/images/liv.gif\"></body></html>" );
frm.getContentPane().add( lbl );
frm.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frm.pack();
frm.setVisible( true );
}
}
then on top of your label you can add your button?
You should swap those two lines:
super.paintComponents(g); //paints the children, like the button
g.drawImage(background, 0, 25, null); // draw background later possibly overwriting the button
Thus it should be this order:
g.drawImage(background, 0, 25, null);
super.paintComponents(g);
Additionally, note that the content pane's default layout is BorderLayout. Thus you'd set the layout of your content pane to null explicitly.
/*it is simple to put button on image first set image by making object then make button object & add the button object direct to image object rather then add to frame.*/
package frame;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class frame
{
public frame()
{
JFrame obj = new JFrame("Banking Software");
JButton b1 = new JButton("Opening Account");
JLabel image = new JLabel(new ImageIcon("money.jpg"));
image.setBounds(0,0, 1600, 1400);
obj.setExtendedState(JFrame.MAXIMIZED_BOTH);
obj.add(image);
b1.setBounds(500,400, 100, 40);
image.add(b1);
obj.setVisible(true);
}
public static void main(String args[])
{
new frame();
}
}

Categories

Resources