java - 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 个网格布局的包布局(一个用于按钮,另一个用于通过单击一个按钮添加随机卡片)
解决方案
介绍
我重新编写了您的代码以创建以下 GUI。
抽了几张牌后,这是相同的 GUI。
计算JFrame
结果为 822 x 420 像素。在 Swing 中,您从内到外工作。您创建 Swing 组件,将 Swing 组件放入 中JPanels
,放入JPanels
a 中JFrame
,然后查看JFrame
结果的大小。
解释
每当我创建 Swing GUI 时,我都会使用模型/视图/控制器(MVC) 模式。这种模式意味着您首先创建模型,然后是视图,然后是控制器。对于复杂的项目,该过程比瀑布式更具有迭代性。
Swing 开发中的 MVC 模式意味着:
- 视图从模型中读取信息。
- 视图不会修改模型。
- 控制器修改模型并更新视图。
通常没有一个控制器类“来统治它们”。每个Action
或ActionListener
类都对其模型和视图部分负责。
模型
我假设你最终想要阅读多个卡片图像,所以我创建了一个Card
类。此类包含卡片图像和您想要的关于扑克牌的任何信息,包括描述性文本、花色、整数值和整数花色值。
我创建了一个SomeCardGameModel
类来保存一张空白卡、一张卡片和一个 int cardCount。cardCount 有助于确保我们不会抽取超过 52 张牌。
减小卡片图像的大小被证明是一个挑战。我使用搜索引擎来查找相关的代码,并将它们放在SomeCardGameModel
课堂上。要点是在创建视图之前完成所有模型创建。
看法
我通过调用该SwingUtilities
invokeLater
方法启动了 Swing 应用程序。此方法确保 Swing 组件将在Event Dispatch Thread上创建和执行。
我将 theJFrame
和 the的创建JPanels
分成单独的方法。这使得代码更容易让人们理解你在做什么。
有JFrame
一个默认值BorderLayout
。我用 aBorderLayout
作为 mainJPanel
和GridLayouts
buttonJPanel
和 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;
}
}
}
推荐阅读
- wordpress - Reactjs 应用程序收到错误此页面正在尝试从未经身份验证的源加载脚本
- windows - 包 pdftex.def 错误:找不到文件:使用草稿设置
- sql - 从车间到车间的条目顺序
- php - laravel 中的 Sql whereNOTIn
- .net - Gmail API .NET:如何向一位发件人请求邮件
- botframework - 如何让聊天机器人使用原始正文 (JSON) 发送 API 发布调用
- javascript - Sequelize 中的 FOR SHARE 和 FOR UPDATE 语句
- azure - 当有多个连接字符串(包括 azure)时,如何从 ASP.NET Identity 连接到 DB?
- javascript - 在特定日期添加课程的 WordPress 功能
- bash - 在 shell 中查询 InfluxDB 时如何获取输出