Как добавить изображение в 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/ для конструктивной критики вашего кода.

Другие вопросы по тегам