首页 > 解决方案 > Java 我的图像被切下和上

问题描述

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();
    }
}

编辑:我不认为我可以在不破坏所有内容的情况下缩短它,只有一张图像并且它在线,遇到了与我相同的问题。我在面板和布局上尝试了一些东西来为每个单元格提供图像大小,但没有奏效。

你好 !我在保留完整图像时遇到了一些麻烦,我没有找到一种完全获取它们的方法,我是否错过了有关这些布局的某些内容?我还不习惯在这里发帖问我是否需要添加东西!谢谢 !我有一个包含 2 个网格布局的包布局(一个用于按钮,另一个用于通过单击一个按钮添加随机卡片)

标签: javaimageswing

解决方案


介绍

我重新编写了您的代码以创建以下 GUI。

抽卡 1

抽了几张牌后,这是相同的 GUI。

抽牌 2

计算JFrame结果为 822 x 420 像素。在 Swing 中,您从内到外工作。您创建 Swing 组件,将 Swing 组件放入 中JPanels,放入JPanelsa 中JFrame,然后查看JFrame结果的大小。

解释

每当我创建 Swing GUI 时,我都会使用模型/视图/控制器(MVC) 模式。这种模式意味着您首先创建模型,然后是视图,然后是控制器。对于复杂的项目,该过程比瀑布式更具有迭代性。

Swing 开发中的 MVC 模式意味着:

  • 视图从模型中读取信息。
  • 视图不会修改模型。
  • 控制器修改模型并更新视图。

通常没有一个控制器类“来统治它们”。每个ActionActionListener类都对其模型和视图部分负责。

模型

我假设你最终想要阅读多个卡片图像,所以我创建了一个Card类。此类包含卡片图像和您想要的关于扑克牌的任何信息,包括描述性文本、花色、整数值和整数花色值。

我创建了一个SomeCardGameModel类来保存一张空白卡、一张卡片和一个 int cardCount。cardCount 有助于确保我们不会抽取超过 52 张牌。

减小卡片图像的大小被证明是一个挑战。我使用搜索引擎来查找相关的代码,并将它们放在SomeCardGameModel课堂上。要点是在创建视图之前完成所有模型创建。

看法

我通过调用该SwingUtilities invokeLater方法启动了 Swing 应用程序。此方法确保 Swing 组件将在Event Dispatch Thread上创建和执行。

我将 theJFrame和 the的创建JPanels分成单独的方法。这使得代码更容易让人们理解你在做什么。

JFrame一个默认值BorderLayout。我用 aBorderLayout作为 mainJPanelGridLayoutsbuttonJPanel和 card JPanel。我在 Swing 组件之间添加了一些间距,以便您可以看到单独的卡片。

控制器

创建模型和视图后,您的匿名控制器类就被简化了。您应该能够为 "remove Cards" 创建控制器JButton

代码

这是完整的可运行代码。我将所有其他类都设为内部类,因此我可以将此代码作为一个块发布。

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;
        }

    }

}

推荐阅读