java - drawImage() 方法未在 Java Swing 中完全绘制图像
问题描述
我正在尝试用 Java Swing 为我的游戏编写主菜单。我有一个普通View
班和一个单独的MainMenuView
班。在我View
的扩展类中,JFrame
我创建了Jpanel
一个具有CardLayout
. 卡片的第一个“卡片”是我的主菜单。
重要的部分来了:我重写了paintComponent(Graphics g)
使用方法的drawImage()
方法。它绘制了我想要的图像,但它会从每一侧进行裁剪。
这是我覆盖该paintComponent(Graphics g)
方法的方式:
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
Image img = new ImageIcon("Project_2_files/menu_background.png").getImage();
g2d.drawImage(img, 0, 0, this);
}
另一个问题:抗锯齿也不适用于绘制的图像。
提前感谢您的回答!
编辑:我在下面发布我的完整代码:
查看.java:
import javax.swing.*;
import java.awt.*;
public class View extends JFrame {
private final MainMenuModel mainMenuModel;
public MainMenuView mainMenuView;
public MainMenuView getMainMenuView() {
return mainMenuView;
}
public void setMainMenuView(MainMenuView mainMenuView) {
this.mainMenuView = mainMenuView;
}
public View(MainMenuModel mainMenuModel) {
this.mainMenuModel = mainMenuModel;
mainMenuView = new MainMenuView(mainMenuModel);
CardLayout cl = new CardLayout();
JPanel cards = new JPanel();//the main panel which contains all other panels
JPanel mainMenuCard = mainMenuView;//panel card for main menu
add(cards);
cards.setLayout(cl);
cards.add(mainMenuCard);
cl.show(cards, "abc");
pack();
setVisible(true);
setTitle("__Main_View__");
setSize(new Dimension(1280,720));
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
}
主菜单视图.java:
import javax.swing.*;
import javax.swing.border.LineBorder;
import java.awt.*;
public class MainMenuView extends JPanel {
private MainMenuModel model;
public MainMenuSurface surface;
public MainMenuModel getModel() {
return model;
}
public void setModel(MainMenuModel model) {
this.model = model;
}
public MainMenuView(MainMenuModel model) {
this.model = model;
surface = new MainMenuSurface(model);
JLabel label1 = new JLabel("AntiPlague", SwingConstants.CENTER);
label1.setFont(new Font("Serif", Font.PLAIN, 25));
label1.setBorder(new LineBorder(Color.GREEN));
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.BOTH;
c.gridx = 0;
c.gridy = 1;
c.weightx = 0.5;
c.insets = new Insets(150,0,150,0);
GridBagConstraints b = new GridBagConstraints();
b.fill = GridBagConstraints.BOTH;
b.weightx = 0.5;
b.gridx = 0;
b.gridy = 0;
b.anchor = GridBagConstraints.CENTER;
setLayout(new GridBagLayout());
add(surface, c);
add(label1, b);
setVisible(true);
setBounds(0,0,1280,720);
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
Image img = new ImageIcon("Project_2_files/menu_background.png").getImage();
g2d.drawImage(img, 0, 0, this);
}
}
包含一些按钮的MainMenuSurface.java类(不是问题所必需的):
import javax.swing.*;
import javax.swing.border.LineBorder;
import java.awt.*;
public class MainMenuSurface extends JPanel {
private MainMenuModel model;
private JButton btnNewGame, btnHighScores, btnExit;
public MainMenuSurface(MainMenuModel model) {
this.model = model;
btnNewGame = new JButton(model.choices[0]);
btnHighScores = new JButton(model.choices[1]);
btnExit = new JButton(model.choices[2]);
add(Box.createVerticalGlue());
add(btnNewGame);
add(Box.createRigidArea(new Dimension(0, 15)));
add(btnHighScores);
add(Box.createRigidArea(new Dimension(0, 15)));
add(btnExit);
btnNewGame.setAlignmentX(CENTER_ALIGNMENT);
btnHighScores.setAlignmentX(CENTER_ALIGNMENT);
btnExit.setAlignmentX(CENTER_ALIGNMENT);
add(Box.createVerticalGlue());
setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
setVisible(true);
setBorder(new LineBorder(Color.BLACK));
setOpaque(false);
}
public JButton getBtnNewGame() {
return btnNewGame;
}
public JButton getBtnExit() {
return btnExit;
}
}
这是我的main.java :
import java.awt.*;
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException {
EventQueue.invokeLater(() -> {//for concurrency-safety purposes
MainMenuModel mainMenuModel = new MainMenuModel();
View ex = new View(mainMenuModel);
MainMenuController mainMenuController = new MainMenuController(mainMenuModel, ex);
mainMenuController.initController();
ex.setVisible(true);
});
}
}
编辑2:我发现出了什么问题。我必须使用```drawImage()` 方法,不仅要给出x 和y,还要给出宽度和高度。
解决方案
1 - 在调用之前加载图像paintComponent
- 可以经常调用此方法来实现组件(例如滚动,重绘,......)(除非图像文件正在更改并且必须重新加载,即使这样也可能用那种方法读错了)
2 -ImageIcon
加载图像不是最好的方法 - 我认为在加载图像时它不会阻塞。我建议使用ImageIO
在问题更新/浏览器缓存更新之前写
推荐阅读
- actions-on-google - 谷歌操作:谷歌帐户登录仅限于白名单
- time - 如何将时间转换为数字?
- powershell - 有没有办法优化这个脚本,使它更有效地运行?
- python - 使用添加函数的python列表连接
- javascript - 当列表包含“按钮”元素时,我怎样才能只找到列表的值,但按钮
- sql - 如何查看用户第一次订阅产品的时间?
- pandas - 如何从日期时间序列中构建带有月份的列?
- javascript - 如何在不打开窗口的情况下打开电子应用程序
- java - 如何防止 DialogFragment 调整大小
- facebook-graph-api - 从服务器调用 Facebook API /{user-id}/picture?access_token=xxxxxx 的最佳方式?