2

I'm creating a simple game by Java GUI, but I have some problems with the initial design with panels.

I want the design to be like this (see picture)

enter image description here

But I always have problems with sizes I suppose.

This is my code if you have any suggestions.

public class GameProject extends JFrame { ImagePanel gamePanel; Image image = null; public GameProject() { setTitle(""); setSize(1100, 900); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setLocationRelativeTo(null); ImageIcon image = new ImageIcon("logo.jpg"); JLabel label = new JLabel("", image, JLabel.CENTER); JPanel leftPanel = new JPanel(new BorderLayout()); leftPanel.setBackground(Color.LIGHT_GRAY); leftPanel.setBounds(300, 900, 180, 110); leftPanel.add(label, BorderLayout.WEST); add(leftPanel); gamePanel = new ImagePanel("SnakesLadders2.jpg"); add(gamePanel, BorderLayout.CENTER); setVisible(true); } class ImagePanel extends JPanel { public ImagePanel() { } public ImagePanel(String filename) { image = new ImageIcon(filename).getImage(); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); g.drawImage(image, 0, 0, image.getWidth(null), image.getHeight(null), null); } } public static void main(String[] args) { new GameProject(); } } 
0

1 Answer 1

3

Never use setBounds(...). For one layout managers are geared towards respecting a components preferred size and not its size, and for another, if you hard-code sizes and positions, you almost guarantee that the GUI will not work well on all platforms except your own. For your problem, if you display the image as an ImageIcon within a JLabel, then the JLabel will set its preferred size based on the image. If you need to display the image within a JPanel, then it's up to you to do this. I sometimes do something like:

class ImagePanel extends JPanel { private BufferedImage image; public ImagePanel() { } public ImagePanel(String filename) { // image = new ImageIcon(filename).getImage(); // don't get images this way. // use ImageIO.read(URL url) and get the image as a resource } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); if (image != null) { g.drawImage(image, 0, 0, this); } } @Override public Dimension getPreferredSize() { if (image == null) { return super.getPreferredSize(); } else { int w = image.getWidth(); int h = image.getHeight(); return new Dimension(w, h); } } } 

Also, don't get images as you're doing. Better to

  1. use ImageIO.read(...)
  2. if you're going to use the images as Images, then get the images as images, not as ImageIcons
  3. get the image as a resource, not as a File.

An example.....

enter image description here

import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Image; import java.io.IOException; import java.net.URL; import javax.imageio.ImageIO; import javax.swing.*; @SuppressWarnings("serial") public class SnakesAndLaddersProgram extends JPanel { public static final String GAME_BOARD_PATH = "http://www.righttoremain.org." + "uk/blog/wp-content/uploads/2015/11/snakesladders.jpg"; public static final String GAME_LOGO_PATH = "https://loteries.lotoquebec.com" + "/loteries/___W9a9e8ef6-0c97-4d1b-a4c3-2588fee936d3___.png"; private static final double BOARD_SCALE = 0.5; // online images too big private static final double LOGO_SCALE = 0.3; // online images too big private ImagePanel imagePanel = null; public SnakesAndLaddersProgram() throws IOException { URL gameBoardUrl = new URL(GAME_BOARD_PATH); Image gameBoard = ImageIO.read(gameBoardUrl); // scale to size: int w = (int) (gameBoard.getWidth(this) * BOARD_SCALE); int h = (int) (gameBoard.getHeight(this) * BOARD_SCALE); gameBoard = gameBoard.getScaledInstance(w, h, Image.SCALE_DEFAULT); imagePanel = new ImagePanel(gameBoard); URL logoUrl = new URL(GAME_LOGO_PATH); Image logo = ImageIO.read(logoUrl); // scale to size: w = (int) (logo.getWidth(this) * LOGO_SCALE); h = (int) (logo.getHeight(this) * LOGO_SCALE); Icon logoIcon = new ImageIcon(logo); JLabel logoLabel = new JLabel(logoIcon); JPanel westPanel = new JPanel(); westPanel.add(logoLabel); setLayout(new BorderLayout()); add(imagePanel, BorderLayout.CENTER); add(westPanel, BorderLayout.LINE_START); } private static void createAndShowGui() { SnakesAndLaddersProgram mainPanel = null; try { mainPanel = new SnakesAndLaddersProgram(); } catch (IOException e) { e.printStackTrace(); System.exit(-1); } JFrame frame = new JFrame("Snakes And Ladders"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.getContentPane().add(mainPanel); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } public static void main(String[] args) { SwingUtilities.invokeLater(() -> createAndShowGui()); } } @SuppressWarnings("serial") class ImagePanel extends JPanel { private Image image; public ImagePanel() { } public ImagePanel(Image image) { this.image = image; } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); if (image != null) { g.drawImage(image, 0, 0, this); } } @Override public Dimension getPreferredSize() { if (image == null) { return super.getPreferredSize(); } else { int w = image.getWidth(this); int h = image.getHeight(this); return new Dimension(w, h); } } } 
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.