我正在尝试使用主要使用swing编码一个Hangman游戏。它正在发挥作用,但没有Hangman图形。我现在正试图让某些东西出现,但我不知道从哪里开始。这就是我所拥有的。
package ProjectHang;
import java.awt.*;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Scanner;
import javax.sound.sampled.Line;
import javax.swing.*;
public class Hangman extends JFrame{'
public static void main(String[] args)
{
Scanner file = null;
try {
file = new Scanner(new File("data/words.dat"));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
int size=file.nextInt();
file.nextLine();
int chosen=(int)(size*Math.random());
for(int i=0; i<chosen; i++)
file.nextLine();
line=file.nextLine();
new Hangman();
}
public static boolean cont=true;
public static JTextField userInput=new JTextField(20);
public static JButton confirm=new JButton("Ok");
public static JLabel header=new JLabel("HANGMAN");
public static JTextArea correct=new JTextArea("Correct Guesses",10,10);
public static JTextArea incorrect=new JTextArea("Incorrect Guesses", 10,10);
public static JTextArea unguessed=new JTextArea("", 10,10);
public static JLabel blanks=new JLabel();
public static JPanel pan=new JPanel();
public static String line;
public static int wrong=0;
ArrayList<String> chars=new ArrayList<String>();
ArrayList<String> guessy=new ArrayList<String>();
public static Graphics window;
public static MyGraphics mg;
public Hangman()
{
this.setSize(800,800);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setTitle("Hangman");
pan.setLayout(new GridBagLayout());
fillChars();
addItem(pan, blanks, 0,1,3,1,GridBagConstraints.CENTER);
addItem(pan, header,0,0,3,1,GridBagConstraints.CENTER);
addItem(pan, userInput, 0,2,2,1,GridBagConstraints.EAST);
addItem(pan, confirm, 2,2,1,1,GridBagConstraints.WEST);
addItem(pan, correct, 0,3,1,1,GridBagConstraints.CENTER);
addItem(pan, incorrect, 1,3,1,1,GridBagConstraints.CENTER);
addItem(pan,unguessed,2,3,1,1,GridBagConstraints.CENTER);
addItem(pan, mg, 3,0,1,4, GridBagConstraints.CENTER);
confirm.addActionListener(e -> confirmClick());
correct.setEditable(false);
incorrect.setEditable(false);
unguessed.setEditable(false);
blanks.setText(word.printBlanks(line.length()));
correct.append("\n");
incorrect.append("\n");
//unguessed.append("\n");
blanks.setFont(new Font(blanks.getFont().getName(), Font.BOLD, 64));
header.setFont(new Font("Cooper Black", Font.BOLD, 64));
unguessed.append(setUnguessed());
this.add(pan);
this.pack();
this.setVisible(true);
}
public void confirmClick()
{
String guessChar;
String guessWord;
boolean charIsCorrect;
boolean stringIsCorrect;
if(userInput.getText().length()==1){
if(!guessy.contains(userInput.getText()))
guessy.add(userInput.getText().toLowerCase());
else{
userInput.setText("");
return;
}
guessChar=userInput.getText();
guessChar=guessChar.toLowerCase();
charIsCorrect=checkChar(guessChar);
chars.remove(userInput.getText());
unguessed.setText(setUnguessed());
//blanks.setText(word.setBlanks(guessChar));
blanks.setText(word.setBlanks(guessy));
if(charIsCorrect)
correct.append(guessChar+ " ");
else
{
wrong++;
incorrect.append(guessChar+ " ");
}
}
else
{
guessWord=userInput.getText();
guessWord=guessWord.toLowerCase();
stringIsCorrect=checkString(guessWord);
if(stringIsCorrect){
blanks.setText(line);
JOptionPane.showMessageDialog(null,
"You have won the game! Congratulations!",
"WINNER",
JOptionPane.INFORMATION_MESSAGE);
dispose();
}
else
{
wrong++;
}
}
userInput.setText("");
if(wrong>=6){
JOptionPane.showMessageDialog(null,
"You guessed wrong too many times... \nI'm sorry, you lose.\n The correct answer was " + line,
"LOSER",
JOptionPane.ERROR_MESSAGE);
dispose();
}
}
public void addItem(JPanel p, JComponent c, int x, int y, int width,
int height,int align)
{
GridBagConstraints gc=new GridBagConstraints();
gc.gridx=x;
gc.gridy=y;
gc.gridwidth=width;
gc.gridheight=height;
gc.weightx=100.0;
gc.weighty=100.0;
gc.insets=new Insets(4,4,4,4);
gc.anchor=align;
gc.fill=GridBagConstraints.NONE;
p.add(c,gc);
}
public boolean checkChar(CharSequence z)
{
return line.contains(z);
}
public boolean checkString(String s)
{
return line.equals(s);
}
public String setUnguessed()
{
String toRet="Unguessed Characters\n";
int counter=1;
for(String x: chars)
{
if(counter%6==0)
toRet+="\n";
toRet+=x + " ";
counter++;
}
return toRet;
}
public void fillChars()
{
char toAdd ='a';
for(int i=0; i<26; i++)
{
chars.add(Character.toString(toAdd));
toAdd++;
}
}
}
package ProjectHang;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.*;
public class MyGraphics extends JComponent {
public MyGraphics()
{
setBorder(BorderFactory.createLineBorder(Color.black));
}
@Override
public Dimension getPreferredSize()
{
return new Dimension(400,400);
}
@Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.drawRect(600, 10, 10, 10);
}
}
我想让这个矩形显示在屏幕上,但抛出了nullPointerException。我对编码很新,所以可能存在很多错误。谢谢你的帮助。
答案 0 :(得分:3)
首先,关于NullPointerExceptions。您表明他们在addItem(pan, mg, 3, 0, 1, 4, GridBagConstraints.CENTER)
和p.add(c,gc)
。
这两行都会抛出NullPointerException,因为在调用mg
之前,你永远不会实例化addItem
变量。 addItem
方法包含p.add(c, gc)
方法调用,因此它也会抛出相同的异常。我的意思是你从不打电话给mg = new MyGraphics()
(或其他适当的构造函数。)
现在,根据您的标题问题:如何向GridBagLayout添加图形?
简单的答案是:与将任何其他组件添加到GridBayLayout的方式相同。
Oracle有一个很好的Swing tutorial,但我会在这里介绍这些内容。
找到Hangman图片的图片后,您可以通过创建JLabel
将其添加到您的应用中。假设您的图片名为hangman.jpg
,则以下样板文件显示了如何创建图片JLabel
:
URL imageUrl = Hangman.class.getResource("path/to/hangman.jpg");
ImageIcon image = new ImageIcon( imageUrl, "A hangman image" );
JLabel hangmanImage = new JLabel(image);
然后,您将以与添加任何其他组件相同的方式将其添加到GridBayLayout。例如,要替换mg
元素调用:
addItem(pan, hangmanImage, 3, 0, 1, 4, GridBayConstraints.CENTER);
另外,我强烈建议您为变量提供描述性名称。 &#34;窗口&#34;或&#34; Panel&#34;更喜欢&#34; pan。&#34;一旦你有了一个工作程序,你可能想考虑在Code Review StackExchange site发帖,对你的代码进行一些建设性的批评。