Как добавить изображение в GridBagLayout
Я пытаюсь кодировать игру 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. Я довольно новичок в кодировании, так что, вероятно, есть много ошибок. Спасибо за твою помощь.
1 ответ
Во-первых, в отношении исключений NullPointerException. Вы указываете, что они включены 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, но я расскажу здесь об основных моментах.
Как только вы найдете изображение для изображения 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);
Также я очень рекомендую дать вашим переменным описательные имена. "Окно" или "Панель" гораздо предпочтительнее "панорамирования". Если у вас есть работающая программа, вы можете рассмотреть возможность размещения на сайте http://codereview.stackexchange.com/ для конструктивной критики вашего кода.