Home > Software engineering >  Java My images are being cut bottom and top
Java My images are being cut bottom and top

Time:10-21

public class Main {
    public static class GUI extends JFrame {
        public GUI() {
            //Title
            super("Draw Card");
            //panel
            Panel buttonsPanel = new Panel();
            Panel imagePanel = new Panel();
            //App layout
            setSize(600,480);
            setLayout(new GridBagLayout());
            GridBagConstraints gc = new GridBagConstraints();
            //gc value
            gc.gridy=0;gc.gridx=0;gc.gridwidth=1;gc.gridheight=1;gc.weightx=0.5;gc.weighty=0;gc.fill = GridBagConstraints.HORIZONTAL;
            //layout in layout
            GridLayout buttonsLayout = new GridLayout(1,2);
            GridLayout imageLayout = new GridLayout(4,13);
            buttonsPanel.setLayout(buttonsLayout);
            imagePanel.setLayout(imageLayout);
            //add
            add(buttonsPanel,gc);
            //change gc value
            gc.gridy=1;gc.weighty=1;gc.gridheight=9;gc.fill = GridBagConstraints.BOTH;
            //add
            add(imagePanel,gc);
            //button
            JButton btn = new JButton("Draw card");
            buttonsPanel.add(btn);
            buttonsPanel.add(new JButton("Remove cards."));
            //event
            btn.addActionListener(e ->{
                //just image from link
                Image image = null;
                try {
                    URL url = new URL("https://www.improvemagic.com/wp-content/uploads/2020/11/kj.png");
                    image = ImageIO.read(url);
                } catch (IOException ee) {
                    ee.printStackTrace();
                }
                //add to label then add label to panel
                JLabel label = new JLabel(new ImageIcon(image));
                imagePanel.add(label);
                revalidate();
            });
            //set visible
            setVisible(true);
        }
    }
    public static void main(String[] args){
            GUI test = new GUI();
    }
}

EDITED: I dont think i can make it shorter without destroying everything, only one image and it's online, got the same problem that i have. I've tryed a couple a thing on the pannel and the layout to give the image size for each cell but didnt worked.

Hello ! I have some trouble to keep the full image, i didn't find a single way of getting them fully, did I miss something about those layout ? I'm still not used to post here ask me if i need to add things ! Thank you ! I have a baglayout that contain 2 gridlayout (one for button and another one where I want to add random card by clicking on one button)

CodePudding user response:

Introduction

I reworked your code to create the following GUI.

Draw Card 1

Here's the same GUI after drawing a few cards.

Draw Card 2

The JFrame worked out to be 822 x 420 pixels. In Swing, you work from the inside out. You create Swing components, put the Swing components in JPanels, put the JPanels in a JFrame, and see what the size of the JFrame turns out to be.

Explanation

Whenever I create a Swing GUI, I use the model/view/controller (MVC) pattern. This pattern implies that you create the model first, then the view, then the controller. For complex projects, the process is more iterative than waterfall.

The MVC pattern in Swing development means:

  • The view reads information from the model.
  • The view does not modify the model.
  • The controller modifies the model and updates the view.

There's usually not one controller class "to rule them all". Each Action or ActionListener class is responsible for its portion of the model and the view.

Model

I assumed you eventually wanted to read more than one card image, so I created a Card class. This class holds the card Image and whatever information you want about a playing card, including descriptive text, suit, int value, and int suit value.

I created a SomeCardGameModel class to hold a blank card, a card, and an int cardCount. The cardCount helps ensure that we don't draw more than 52 cards.

Reducing the size of the card image turned out to be a bit of a challenge. I used a search engine to find relevant bits of code and put them together in the SomeCardGameModel class. The main point is that you do all of the model creation before you create the view.

View

I started the Swing application with a call to the SwingUtilities invokeLater method. This method ensures that the Swing components will be created and executed on the Event Dispatch Thread.

I separated the creation of the JFrame and the JPanels into separate methods. This makes the code much easier for people to understand what you're doing.

The JFrame has a default BorderLayout. I used a BorderLayout for the main JPanel and GridLayouts for the button JPanel and the card JPanel. I added some spacing between the Swing components so you can see individual cards.

Controller

After creating a model and a view, your anonymous controller class is simplified. You should be able to create the controller for the "remove Cards" JButton.

Code

Here's the complete runnable code. I made all the additional classes inner classes so I can post this code as one block.

import java.awt.BorderLayout;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;

import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class SomeCardGame implements Runnable {
    
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new SomeCardGame());
    }
    
    private JLabel[] cardLabels;
    
    private final SomeCardGameModel model;
    
    public SomeCardGame() {
        this.model = new SomeCardGameModel();
    }

    @Override
    public void run() {
        JFrame frame = new JFrame("Draw Card");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        frame.add(createMainPanel(), BorderLayout.CENTER);
        
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
        
        System.out.println(frame.getSize());
    }
    
    public JPanel createMainPanel() {
        JPanel panel = new JPanel(new BorderLayout());
        panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
        
        panel.add(createButtonPanel(), BorderLayout.NORTH);
        panel.add(createCardPanel(), BorderLayout.CENTER);
        
        return panel;
    }
    
    public JPanel createButtonPanel() {
        JPanel panel = new JPanel(new GridLayout(0, 2, 5, 5));
        panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
        
        JButton drawButton = new JButton("Draw card");
        panel.add(drawButton);

        drawButton.addActionListener(e -> {
            int count = model.getCardCount();
            if (count < 52) {
                cardLabels[model.getCardCount()].setIcon(
                        new ImageIcon(model.getCard().getCardImage()));
                model.incrementCardCount(1);
            }
        });
        
        JButton removeButton = new JButton("Remove cards");
        panel.add(removeButton);
        
        return panel;
    }
    
    public JPanel createCardPanel() {
        JPanel panel = new JPanel(new GridLayout(0, 13, 5, 5));
        panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
        
        this.cardLabels = new JLabel[52];
        
        for (int index = 0; index < cardLabels.length; index  ) {
            cardLabels[index] = new JLabel(new ImageIcon(
                    model.getBlankCard().getCardImage()));
            panel.add(cardLabels[index]);
        }
        
        return panel;
    }
    
    public class SomeCardGameModel {
        
        private int cardCount;
        
        private final Card blankCard;
        private final Card card;
        
        public SomeCardGameModel() {
            this.blankCard = new Card(createBlankCard());
            BufferedImage image = readCard();
            Image reducedImage = image.getScaledInstance(
                    56, 78, Image.SCALE_SMOOTH);
            this.card = new Card(toBufferedImage(reducedImage));
            this.cardCount = 0;
        }
        
        private BufferedImage createBlankCard() {
            BufferedImage image = new BufferedImage(56, 78, 
                    BufferedImage.TYPE_INT_RGB);
            return image;
        }
        
        private BufferedImage readCard() {
            try {
                URL url = new URL("https://www.improvemagic.com/"
                          "wp-content/uploads/2020/11/kj.png");
                return ImageIO.read(url);
            } catch (IOException ee) {
                ee.printStackTrace();
                return null;
            }
        }
        
        private BufferedImage toBufferedImage(Image img) {
            if (img instanceof BufferedImage) {
                return (BufferedImage) img;
            }

            BufferedImage bimage = new BufferedImage(
                    img.getWidth(null), img.getHeight(null),
                    BufferedImage.TYPE_INT_RGB);

            // Draw the image on to the buffered image
            Graphics2D bGr = bimage.createGraphics();
            bGr.drawImage(img, 0, 0, null);
            bGr.dispose();

            // Return the buffered image
            return bimage;
        }

        public Card getBlankCard() {
            return blankCard;
        }

        public Card getCard() {
            return card;
        }

        public int getCardCount() {
            return cardCount;
        }

        public void incrementCardCount(int increment) {
            this.cardCount  = increment;
        }
        
    }
    
    public class Card {
        
        private final BufferedImage cardImage;
        
        public Card(BufferedImage cardImage) {
            this.cardImage = cardImage;
        }

        public BufferedImage getCardImage() {
            return cardImage;
        }

    }

}
  • Related