Swing 刽子手游戏背景图像不高效?
我正在做一个刽子手游戏,我的代码似乎没有给我提供太多的使用布局的自由。我在JFrame中添加了一个图像,然后在图像中添加了一个JPanel,用于所有的jLabel和JTextFields,但在我看来,这是低效的,因为为了更改JTextFields或jLabel的布局,我必须更改图像的布局,这会弄乱整个游戏的外观。我怎样才能使这段代码更高效,并让自己更自由地更改我的jlabel和JTextFields的布局,而不会把一切都搞糟?感谢您在advanced中的帮助Swing 刽子手游戏背景图像不高效?,swing,jframe,jpanel,jlabel,Swing,Jframe,Jpanel,Jlabel,我正在做一个刽子手游戏,我的代码似乎没有给我提供太多的使用布局的自由。我在JFrame中添加了一个图像,然后在图像中添加了一个JPanel,用于所有的jLabel和JTextFields,但在我看来,这是低效的,因为为了更改JTextFields或jLabel的布局,我必须更改图像的布局,这会弄乱整个游戏的外观。我怎样才能使这段代码更高效,并让自己更自由地更改我的jlabel和JTextFields的布局,而不会把一切都搞糟?感谢您在advanced中的帮助 /*PACKAGE DECLARA
/*PACKAGE DECLARATION*/
package Game;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
/************************
* GAME MECHANICS CLASS *
* **********************/
public class GameStructure {
/* INSTANCE DECLARATIONS */
private String []wordList = {"computer","java","activity","alaska","appearance","article",
"automobile","basket","birthday","canada","central","character","chicken","chosen",
"cutting","daily","darkness","diagram","disappear","driving","effort","establish","exact",
"establishment","fifteen","football","foreign","frequently","frighten","function","gradually",
"hurried","identity","importance","impossible","invented","italian","journey","lincoln",
"london","massage","minerals","outer","paint","particles","personal","physical","progress",
"quarter","recognise","replace","rhythm","situation","slightly","steady","stepped",
"strike","successful","sudden","terrible","traffic","unusual","volume","yesterday"};
private int []length = new int [64];
private JTextField tf;//text field instance variable (used)
private JLabel jl2;//label instance variable (used)
private JLabel jl3;//label instance (working on)
private String letter;
/*****************
* LENGTH METHOD *
* ***************/
public void length(){
jl3 = new JLabel();
int j = 0;
for(j = 0; j<64; j++) {
length[j] = wordList[j].length();//gets length of words in wordList
}//end for
int l = 0;
String line = "";
//create line first then put into .setText
for(int m = 0; m<length[l]; m++) {
line += "__ ";
l++;
}//end for
jl3.setText(line);
}//end length method
/*****************
* WINDOW METHOD *
* ***************/
public void window() {
LoadImageApp i = new LoadImageApp();//calling image class
JFrame gameFrame = new JFrame();//declaration
JPanel jp = new JPanel();
//JPanel jp2 = new JPanel();//jpanel for blanks
JLabel jl = new JLabel("Enter a Letter:");//prompt with label
jl.setFont(new Font("Rockwell", Font.PLAIN, 20));//set font
tf = new JTextField(1);//length of text field by character
jl2 = new JLabel("Letters Used: ");
tf.setFont(new Font("Rockwell", Font.PLAIN, 20));//set font
jl2.setFont(new Font("Rockwell", Font.PLAIN, 20));//set font
jp.add(jl);//add label to panel
jp.add(tf);//add text field to panel
jp.add(jl2);//add letters used
gameFrame.add(i); //adds background image to window
i.add(jp); // adds panel containing label to background image panel
gameFrame.setTitle("Hangman");//title of frame window
gameFrame.setSize(850, 600);//sets size of frame
gameFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//exit when 'x' button pressed
gameFrame.setIconImage(new ImageIcon("Hangman-Game-grey.png").getImage());//set the frame icon to an image loaded from a file
gameFrame.setLocationRelativeTo(null);//window centered
gameFrame.setResizable(false);//user can not resize window
gameFrame.setVisible(true);//display frame
}//end window method
/*********************
* USER INPUT METHOD *
* *******************/
public void userInput() {
tf.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {//when enter key pressed
JTextField tf = (JTextField)e.getSource();
letter = tf.getText();
jl2.setText(jl2.getText() + letter + " ");//sets jlabel text to users entered letter
}//end actionPerformed method
});
}//end userInput method
}//end GameMechanics class
/*PACKAGE DECLARATION*/
package Game;
/***********************
* IMPORT DECLARATIONS *
* *********************/
import java.awt.BorderLayout;
import java.awt.Graphics;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
/***************
* IMAGE CLASS *
* *************/
public class LoadImageApp extends JPanel {
private static final long serialVersionUID = 1L;
private ImageIcon image;
/***********************
* PAINT IMAGE METHOD *
* *********************/
public void paintComponent (Graphics g) {
//setLayout(new BorderLayout());
super.paintComponent(g);
image = new ImageIcon("hangman.png");//image name & type
image.paintIcon(this, g, 270, 20);
}//end paintComponent method
}//end LoadImageApp class
/*PACKAGE DECLARATION*/
package Game;
/*******************
* GAME MAIN CLASS *
* *****************/
public class GameMain {
/***************
* MAIN METHOD *
* *************/
public static void main (String []args) {
GameStructure game = new GameStructure();//declaration
game.length();
game.window();
game.userInput();
}//end main method
}//end GameMain class
/*包声明*/
包装游戏;
导入java.awt.Font;
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入javax.swing.*;
/************************
*游戏力学课*
* **********************/
公共类游戏结构{
/*实例声明*/
私有字符串[]单词列表={“计算机”、“java”、“活动”、“阿拉斯加”、“外观”、“文章”,
“汽车”、“篮子”、“生日”、“加拿大”、“中央”、“人物”、“鸡肉”、“精选”,
“切割”、“每日”、“黑暗”、“图表”、“消失”、“驱动”、“努力”、“建立”、“精确”,
“建立”、“十五”、“足球”、“外国”、“频繁”、“恐惧”、“功能”、“逐渐”,
“匆忙”、“身份”、“重要性”、“不可能”、“发明”、“意大利语”、“旅程”、“林肯”,
“伦敦”、“按摩”、“矿物”、“外部”、“油漆”、“颗粒”、“个人”、“身体”、“进步”,
“四分之一”,“识别”,“替换”,“节奏”,“情况”,“轻微”,“稳定”,“步伐”,
“罢工”、“成功”、“突然”、“可怕”、“交通”、“异常”、“数量”、“昨天”};
私有整数[]长度=新整数[64];
私有JTextField;//文本字段实例变量(已使用)
私有JLabel jl2;//标签实例变量(已使用)
私有JLabel jl3;//标签实例(正在处理)
私人字符串字母;
/*****************
*长度法*
* ***************/
公共空间长度(){
jl3=新的JLabel();
int j=0;
对于(j=0;j一些建议:
- 不要重写JPanel的
paint(…)
方法,而是它的paintComponent(Graphics g)
方法,除非您需要更改它呈现其子组件或其边框的方式(您不需要)。通过这样做,您还可以获得一些Swing Graphics的优势,包括自动双缓冲
- 永远不要将图像读入
paint
或paintComponent
方法。这些方法是GUI对用户的响应程度的主要决定因素之一,因此您永远不希望在该方法中执行文件I/O。此外,为什么每次使用paint或paintComponent时,都会让代码低效地重新读取相同的图像lled?为什么不简单地将图像或ImageIcon存储在一个变量中一次,然后使用它呢
- 学习并使用布局管理器
- 在绘图或图像渲染JPanel上使用的JPanel通常应该是非不透明的-因此一定要在它们上调用
setOpaque(false)
,在其他一些重叠的Swing组件上也要调用
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
编辑
例如,下面是我的示例,它显示了获取图像的示例(这里是从internet获取的)在一个类构造函数中。还要注意,我的SCSCE将在连接到Internet的任何计算机上工作,因为它不需要图像文件,不像您的。还没有与显示GUI相关的代码,使剩下的代码更符合问题。下次在发布SSCCE时考虑这样做。
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;
class GameStructure {
private JTextField tf;
private JLabel jl2;
public void window() {
LoadImageApp loadImageApp = new LoadImageApp();
JFrame gameFrame = new JFrame();
JPanel jp = new JPanel();
jp.setOpaque(false); //!!
jp.setBorder(BorderFactory.createTitledBorder("jp"));
JLabel jl = new JLabel("Enter a Letter:");
jl.setFont(new Font("Rockwell", Font.PLAIN, 20));
tf = new JTextField(1);
jl2 = new JLabel("Letters Used: ");
tf.setFont(new Font("Rockwell", Font.PLAIN, 20));
jl2.setFont(new Font("Rockwell", Font.PLAIN, 20));
jp.add(jl);
jp.add(tf);
jp.add(jl2);
gameFrame.add(loadImageApp);
loadImageApp.add(jp);
gameFrame.setTitle("Hangman");
gameFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// gameFrame.setIconImage(
// new ImageIcon("Hangman-Game-grey.png").getImage());
gameFrame.setResizable(false);
gameFrame.pack();
gameFrame.setLocationRelativeTo(null);
gameFrame.setVisible(true);
}
}
class LoadImageApp extends JPanel {
private static final long serialVersionUID = 1L;
private static final int PREF_W = 850;
private static final int PREF_H = 600;
private BufferedImage img;
public LoadImageApp() {
// just used as an example public image
String spec = "https://duke.kenai.com/"
+ "SunRIP/.Midsize/SunRIP.png.png";
URL url;
try {
url = new URL(spec);
img = ImageIO.read(url);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public Dimension getPreferredSize() {
return new Dimension(PREF_W, PREF_H);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
if (img != null) {
g.drawImage(img, 0, 0, getWidth(), getHeight(), this);
}
}
}
public class GameMain {
public static void main(String[] args) {
GameStructure game = new GameStructure();
game.window();
}
}
看看你在代码审查上发布了同样的问题!现在,双重发布只是浪费我们的时间,对我们和其他人都不公平。请不要这样做!但是@jzd的答案是1+。那么我应该根本不使用paintComponent来获得我的图像吗?如果是,我应该使用什么?@Anon:到第一部分:上面已经回答了。到第二部分:你可以n读入一次,也许是在构造函数中。