So I have the following code, and whenever I run the program it gives me an error. It all seems correct to me, but it isn't.
It is supposed to take the value of whatever is in the textfields and move the square to that position, and whenever the user enters a new value it is supposed to change the square to whatever the textfield says it should be. Can anybody fix this, or at least tell me whats wrong? Sorry about the code, it got even more screwed up when I started trying to debug it.
The error is
Exception in thread "main" java.lang.NullPointerException
at com.theDevCorner.Game$OptionPanel.<init>(Game.java:228)
at com.theDevCorner.Game$GridPane.<init>(Game.java:81)
at com.theDevCorner.Game.<init>(Game.java:35)
at com.theDevCorner.Game.main(Game.java:52)
Code
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenuBar;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class Game extends JPanel implements ActionListener {
private static final long serialVersionUID = 1L;
private GridPane gridPane;
private DragPanel drag;
public boolean isMouseClicked = false;
public static JMenuBar bar = new JMenuBar();
public int gridY = 1;
public int gridX = 1;
public Game() {
setLayout(new BorderLayout());
OptionPanel options = new OptionPanel();
options.addActionListener(this);
add(options, BorderLayout.NORTH);
gridPane = new GridPane();
gridPane.setBorder(BorderFactory.createLineBorder(Color.white));
add(gridPane);
drag = new DragPanel(options);
drag.setBorder(BorderFactory.createLineBorder(Color.white));
drag.setBackground(new Color(100, 100, 125));
add(drag, BorderLayout.WEST);
}
public static void main(String args[]) {
Game game = new Game();
JFrame frame = new JFrame();
frame.setTitle("Game");
frame.setVisible(true);
frame.setAlwaysOnTop(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(game);
frame.pack();
frame.setLocationRelativeTo(null);
}
#Override
public void actionPerformed(ActionEvent e) {
System.out.println(e);
if (e.getActionCommand().equalsIgnoreCase("grid")) {
gridPane.setGridOn(!gridPane.isGridOn());
}
if (e.getActionCommand().equalsIgnoreCase("square")) {
gridPane.setSqaureOn(!gridPane.isSquareOn());
}
if (e.getActionCommand().equalsIgnoreCase("vgrid")) {
gridPane.setVertOn(!gridPane.isVertOn());
}
}
public class GridPane extends JPanel {
public OptionPanel op = new OptionPanel();
private static final long serialVersionUID = 1L;
private boolean gridOn = false;
private boolean squareOn = false;
private boolean vertOn = false;
public int x = 0,y = 0,w = 0,h = 0;
public GridPane() {
setBackground(Color.BLACK);
}
public boolean isGridOn() {
return gridOn;
}
public boolean isSquareOn() {
return squareOn;
}
public boolean isVertOn() {
return vertOn;
}
public void setGridOn(boolean value) {
if (value != gridOn) {
this.gridOn = value;
repaint();
}
}
public void setVertOn(boolean value) {
if (value != vertOn) {
this.vertOn = value;
repaint();
}
}
public void setSqaureOn(boolean value) {
if (value != squareOn) {
this.squareOn = value;
repaint();
}
}
#Override
public Dimension getPreferredSize() {
return new Dimension(320, 240);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Toolkit tk = Toolkit.getDefaultToolkit();
if (gridOn) {
System.out.println("Grid works");
g.setColor(Color.white);
for (int i = 0; i < tk.getScreenSize().height; i += 64) {
gridY++;
g.drawLine(0, (64 * gridY), tk.getScreenSize().width, (64 * gridY));
}
}
gridY = -1;
gridX = -1;
if (vertOn) {
System.out.println("vert grid works");
g.setColor(Color.white);
for (int ig = 0; ig < tk.getScreenSize().width; ig += 64) {
gridX++;
g.drawLine((64 * gridX), 0, (64 * gridX), tk.getScreenSize().height);
}
}
if (squareOn) {
System.out.println("Square works");
g.setColor(Color.red);
x = Integer.parseInt(op.squareX.getText());
y = Integer.parseInt(op.squareY.getText());
w = Integer.parseInt(op.squareW.getText());
h = Integer.parseInt(op.squareH.getText());
g.fillRect(x,y,w,h);
}
x = 0;
y = 0;
w = 64;
h = 64;
}
}
public class DragPanel extends JPanel {
OptionPanel op;
public DragPanel(OptionPanel op) {
this.op = op;
this.add(this.op.squareButton);
this.op.squareButton.setActionCommand("square");
}
public void addActionListener(ActionListener listener) {
System.out.println(listener);
this.op.squareButton.addActionListener(listener);
}
}
private static class Square {
}
private class OptionPanel extends JPanel {
public JButton grid;
public JButton vgrid;
public JButton squareButton;
public JTextField squareX;
public JTextField squareY;
public JTextField squareW;
public JTextField squareH;
public int x,y,w,h;
public Square square = new Square();
public OptionPanel() {
//Sets the stuff for the panel
setBackground(new Color(155, 0, 255));
setLayout(new GridBagLayout());
//end
//The Show Grid Button Stuff
grid = new JButton("Show Horizontal Grid");
grid.setActionCommand("grid");
//end
//The vertical grid
vgrid = new JButton("Show Vertical Grid");
vgrid.setActionCommand("vgrid");
//end
//The Square tool button stuff
squareButton = new JButton("Sqaure Tool");
//end
squareX = new JTextField(gridPane.x); //<----- THIS IS WHERE THE PROBLEM IS!!!!!
squareY = new JTextField("1",3);
squareW = new JTextField("1",3);
squareH = new JTextField("1",3);
//The gridbagConstraints things
GridBagConstraints gbc = new GridBagConstraints();
gbc.anchor = GridBagConstraints.NORTH;
//kind of like padding
gbc.weighty = 1;
//sets the positions
gbc.gridx = 0;
gbc.gridy = 0;
//add it
add(grid, gbc);
//changes position for the second button
gbc.gridx = -1;
gbc.gridy = 0;
// adds it
add(vgrid, gbc);
//end
add(squareX, gbc);
add(squareY, gbc);
add(squareW, gbc);
add(squareH, gbc);
}
public void addActionListener(ActionListener listener) {
//adds action listeners
grid.addActionListener(listener);
vgrid.addActionListener(listener);
squareButton.addActionListener(listener);
squareX.addActionListener(listener);
squareY.addActionListener(listener);
squareW.addActionListener(listener);
squareH.addActionListener(listener);
}
}
Update
I need help with this portion of the code still:
squareX = new JTextField("0" + gridPane.x,3); //<----- THIS IS WHERE THE PROBLEM IS!!!!!
squareY = new JTextField("0" + gridPane.y,3);
squareW = new JTextField("0" + gridPane.w,3);
squareH = new JTextField("0" + gridPane.h,3);
It seems that the main errors are coming from when I try to do something like this...
OptionPanel options = new OptionPanel();
options.addActionListener(this);
add(options, BorderLayout.NORTH);
gridPane = new GridPane();
You create the OptionPanel before your create the GridPane, so the gridPane variable is null when your optionPanel tries to access that variable.
Create the gridPane before you create the OptionPanel
Your code should be
gridPane = new GridPane();
OptionPanel options = new OptionPanel();
options.addActionListener(this);
add(options, BorderLayout.NORTH);
gridPane.setBorder(BorderFactory.createLineBorder(Color.white));
add(gridPane);
You're first NullPointerException can be fixed by doing something like...
public Game() {
setLayout(new BorderLayout());
gridPane = new GridPane();
gridPane.setBorder(BorderFactory.createLineBorder(Color.white));
OptionPanel options = new OptionPanel();
options.addActionListener(this);
add(options, BorderLayout.NORTH);
add(gridPane);
drag = new DragPanel(options);
drag.setBorder(BorderFactory.createLineBorder(Color.white));
drag.setBackground(new Color(100, 100, 125));
add(drag, BorderLayout.WEST);
}
You're second NullPointerException is more tricky...
You have a cyclic dependency problem...
Class A is trying to create Class B, which is trying to create class C when class C depends on an instance of B...
To clarify...GridPane has an instance of OptionPane, but OptionPane is depended on the state of GridPane, which is null, because GridPane can't initalise until OptionPane has been initialised...confused yet...
You can solve this by using a lazy loading approach. That is, not try to insitate the OptionPane till you need it...
public class GridPane extends JPanel {
public OptionPanel op;
// Other variables...
// Other methods...
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
// Other paint code...
if (squareOn) {
if (op == null) {
op = new OptionPanel();
}
System.out.println("Square works");
g.setColor(Color.red);
x = Integer.parseInt(op.squareX.getText());
y = Integer.parseInt(op.squareY.getText());
w = Integer.parseInt(op.squareW.getText());
h = Integer.parseInt(op.squareH.getText());
g.fillRect(x, y, w, h);
}
}
}
How ever. I don't think this is going to achieve what you want in the long run, as the state of the OptionPane will be different between the classes...(GridPane and OptionPane won't share the same instance....)
A better solution would be to remove these direct dependencies, so that you can pass some the same reference of some kind of model between GridPane and OptionPane, which would allow it to act as the glue between them...
Related
So I am trying to make a TicTacToe game in Java with JFrame and trying to implement a MouseListener so the player can click on the squares. I found one method on the internet but cant figure out why its not working for me. What I already did is I created a frame and draw the grid and background color. Maybe I missed something? Thanks for your time.
import java.awt.*;
import javax.swing.JFrame;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
public class Main extends JFrame
{
public static JFrame root = new JFrame("TicTacToe");
public static void main(String[] args)
{
int[] board = {
0, 0, 0,
0, 0, 0,
0, 0, 0
};
root.getContentPane().setBackground(new Color(232,209,197));
TicTacToeCanvas Canvas = new TicTacToeCanvas(board);
root.add(Canvas);
root.setSize(915,939);
root.setVisible(true);
root.setResizable(false);
root.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
root.pack();
MouseEventClass mouseEvents = new MouseEventClass(root);
}
}
class MouseEventClass implements MouseListener{
public MouseEventClass(JFrame frame){
frame.addMouseListener(this);
}
#Override
public void mouseExited(MouseEvent e){
}
#Override
public void mouseEntered(MouseEvent e){
}
#Override
public void mousePressed(MouseEvent e){
}
#Override
public void mouseReleased(MouseEvent e){
}
#Override
public void mouseClicked(MouseEvent e){
System.out.println("Click");
}
}
}
I would advise that you add the listener to the components held by the main JPanel so you can get individual clicked components more easily. For example:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.*;
public class TicTacToePanel extends JPanel {
private static final long serialVersionUID = 1L;
private static final String ROW = "row";
private static final String COL = "col";
private static final Color BKGRD1 = new Color(230, 230, 230);
private static final Color BKGRD2 = new Color(180, 180, 180);
private static final Dimension CELL_SIZE = new Dimension(80, 80);
private JPanel[][] panelGrid = new JPanel[3][3];
public TicTacToePanel() {
setLayout(new GridLayout(3, 3, 1, 1));
setBackground(Color.BLACK);
setBorder(BorderFactory.createLineBorder(Color.BLACK));
MyMouse myMouse = new MyMouse();
for (int i = 0; i < panelGrid.length; i++) {
for (int j = 0; j < panelGrid[i].length; j++) {
JPanel cellPanel = new JPanel();
cellPanel.putClientProperty(ROW, i);
cellPanel.putClientProperty(COL, j);
cellPanel.setPreferredSize(CELL_SIZE);
cellPanel.setBackground(BKGRD1);
cellPanel.addMouseListener(myMouse);
add(cellPanel);
panelGrid[i][j] = cellPanel;
}
}
}
class MyMouse extends MouseAdapter {
#Override
public void mousePressed(MouseEvent e) {
JPanel cell = (JPanel) e.getComponent();
if (cell == null) {
return;
}
Color background = cell.getBackground().equals(BKGRD1) ? BKGRD2 : BKGRD1;
cell.setBackground(background);
int row = (int) cell.getClientProperty(ROW);
int col = (int) cell.getClientProperty(COL);
System.out.printf("cell row & column: [%d, %d]%n", row, col);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
TicTacToePanel mainPanel = new TicTacToePanel();
JFrame frame = new JFrame("GUI");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
}
}
Here, I create a 2D array of JPanels:
private JPanel[][] panelGrid = new JPanel[3][3];
and then in the main JPanel's constructor,
create individual "cell" JPanels in a nested for loop, adding them to the main JPanel
Adding my mouse listener to each individual cell.
This way, I can get each individual clicked cell cleanly and easily
public TicTacToePanel() {
// ....
// my mouse listener
MyMouse myMouse = new MyMouse();
// create cells and fill my grid with cells
for (int i = 0; i < panelGrid.length; i++) {
for (int j = 0; j < panelGrid[i].length; j++) {
JPanel cellPanel = new JPanel();
// gives each cell identifying information
cellPanel.putClientProperty(ROW, i);
cellPanel.putClientProperty(COL, j);
cellPanel.setPreferredSize(CELL_SIZE);
cellPanel.setBackground(BKGRD1);
// add the same mouse listener to all cells
cellPanel.addMouseListener(myMouse);
add(cellPanel); // add it to the main JPanel
panelGrid[i][j] = cellPanel; // and to a holding array
}
}
}
The mouse listener is simple:
class MyMouse extends MouseAdapter {
#Override
public void mousePressed(MouseEvent e) {
// get the cell clicked
JPanel cell = (JPanel) e.getComponent();
// make sure it's not null
if (cell == null) {
return;
}
// then do stuff to it
Color background = cell.getBackground().equals(BKGRD1) ? BKGRD2 : BKGRD1;
cell.setBackground(background);
int row = (int) cell.getClientProperty(ROW);
int col = (int) cell.getClientProperty(COL);
System.out.printf("cell row & column: [%d, %d]%n", row, col);
}
}
I am very new to this community. I have tried to get up to speed on all rules before posting this question (as well as researching solutions). I apologize if I offended or broke any rules through ignorance. Please also excuse my awful code, I am still learning. Thank you for understanding!
EDIT: I have added additional information and tried different approaches to this issue I'm having. I have reworked part of the code below.
I am building a simple football game with a game field panel and control panel. The game field displays all of the player and tackles on the GUI. The control panel sets the difficulty of the game, starts the timer, and the type of quarterback. I ran into a road block where I have all of my code to compile correctly, but when calling set methods on the GameField class to update the score, it updates the variable but not the actual score through my JTextArea Score keeper.
I have instantiated the ControlPanel within the GameField class. I've also tested with a System.out.println() and it shows that it is indeed updating the variable. Is updating JTextArea allowed between classes?
GameField.java
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class GameField extends JPanel implements KeyListener {
ControlPanel cp = new ControlPanel();
// Game pieces
private JButton playerIcon = new JButton("RB");
private JButton tackleIcon1 = new JButton("LB");
private JButton tackleIcon2 = new JButton("LB");
private JButton fieldGoal = new JButton("FG");
// Player and Tackle locations
private int playerPositionX = 100;
private int playerPositionY = 500;
private int tackle1PositionX = 1200;
private int tackle1PositionY = 400;
private int tackle2PositionX = 1200;
private int tackle2PositionY = 600;
// Player variable speeds
private int playerSpeed = 20;
public GameField() {
setLayout(null);
setBackground(Color.green);
add(playerIcon);
playerIcon.setBounds(new Rectangle(getPlayerPositionX(), getPlayerPositionY(), 80, 30));
add(tackleIcon1);
tackleIcon1.setBounds(new Rectangle(getTackle1PositionX(), getTackle1PositionY(), 100, 50));
add(tackleIcon2);
tackleIcon2.setBounds(new Rectangle(getTackle2PositionX(), getTackle2PositionY(), 100, 50));
add(fieldGoal);
fieldGoal.setBounds(new Rectangle(1600, 100, 100, 800));
playerIsTackled();
setFocusable(true);
addKeyListener(this);
}
public void playerIsTackled() {
Rectangle playerRect = playerIcon.getBounds();
Rectangle tackle1Rect = tackleIcon1.getBounds();
Rectangle tackle2Rect = tackleIcon2.getBounds();
if (playerRect.intersects(tackle1Rect) || playerRect.intersects(tackle2Rect)) {
setPlayerPositionX(100);
setPlayerPositionY(500);
setTackle1PositionX(1200);
setTackle1PositionY(400);
setTackle2PositionX(1200);
setTackle2PositionY(600);
playerIcon.setBounds(getPlayerPositionX(), getPlayerPositionY(), 80, 30);
tackleIcon1.setBounds(getTackle1PositionX(), getTackle1PositionY(), 100, 50);
tackleIcon2.setBounds(getTackle2PositionX(), getTackle2PositionY(), 100, 50);
cp.setCurrentTackles(cp.getCurrentTackles() + 1);
System.out.println(cp.getCurrentTackles());
}
}
public void playerScored() {
Rectangle playerRect = playerIcon.getBounds();
Rectangle fieldGoalRect = fieldGoal.getBounds();
if (playerRect.intersects(fieldGoalRect)) {
setPlayerPositionX(100);
setPlayerPositionY(500);
setTackle1PositionX(1200);
setTackle1PositionY(400);
setTackle2PositionX(1200);
setTackle2PositionY(600);
playerIcon.setBounds(getPlayerPositionX(), getPlayerPositionY(), 80, 30);
tackleIcon1.setBounds(getTackle1PositionX(), getTackle1PositionY(), 100, 50);
tackleIcon2.setBounds(getTackle2PositionX(), getTackle2PositionY(), 100, 50);
cp.setCurrentScore(cp.getCurrentScore() + 1);
System.out.println(cp.getCurrentScore());
}
}
public void moveToPlayer() {
if (getTackle1PositionX() > getPlayerPositionX()) {
setTackle1PositionX(getTackle1PositionX() - 1);
} else {
setTackle1PositionX(getTackle1PositionX() + 1);
}
if (getTackle1PositionY() > getPlayerPositionY()) {
setTackle1PositionY(getTackle1PositionY() - 1);
} else {
setTackle1PositionY(getTackle1PositionY() + 1);
}
getTackleIcon1().setBounds(getTackle1PositionX(), getTackle1PositionY(), 100, 50);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
requestFocusInWindow();
playerIsTackled();
playerScored();
}
#Override
public void keyTyped(KeyEvent e) {
}
#Override
public void keyPressed(KeyEvent e) {
int k = e.getKeyCode();
if (k == e.VK_LEFT && getPlayerPositionX() > 0) {
setPlayerPositionX(getPlayerPositionX() - getPlayerSpeed());
}
if (k == e.VK_RIGHT && getPlayerPositionX() < 1703) {
setPlayerPositionX(getPlayerPositionX() + getPlayerSpeed());
}
if (k == e.VK_UP && getPlayerPositionY() > 0) {
setPlayerPositionY(getPlayerPositionY() - getPlayerSpeed());
}
if (k == e.VK_DOWN && getPlayerPositionY() < 1089) {
setPlayerPositionY(getPlayerPositionY() + getPlayerSpeed());
}
getPlayerIcon().setBounds(getPlayerPositionX(), getPlayerPositionY(), 80, 30);
}
Below is the ControlPanel.java. In the actionPerformed method, you can see I added a getScore().setText() method for updating the score. It correctly updates the score there if I replace the getCurrentScore() method with any integer.
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.util.Hashtable;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class ControlPanel extends JPanel implements ActionListener, ChangeListener {
private JButton start;
private JButton stop;
private JSlider speed;
private JComboBox playerList;
private Timer tim;
private int delay = 1000;
private int i = 0;
private int currentScore = 0;
private int currentTackles = 0;
private JTextArea timer = new JTextArea("Timer: " + 0, 1, 6);
private JTextArea score = new JTextArea("Field Goals: " + currentScore + " Tackles: " + currentTackles, 1, 16);
private String[] playerStyle = {"Slow Runner", "Running Back", "All Star"};
public ControlPanel() {
super();
setBackground(Color.darkGray);
// Game controls
start = new JButton("Start");
stop = new JButton("Stop");
speed = new JSlider(JSlider.HORIZONTAL, 0, 2, 1);
playerList = new JComboBox(getPlayerStyle());
// Slider label
Hashtable labelTable = new Hashtable();
labelTable.put(new Integer(0), new JLabel("Slow"));
labelTable.put(new Integer(1), new JLabel("Normal"));
labelTable.put(new Integer(2), new JLabel("Fast"));
speed.setLabelTable(labelTable);
speed.setPaintLabels(true);
// Combo box dropdown
playerList.setSelectedIndex(1);
// Timer
tim = new Timer(getDelay(), this);
// Add methods
add(start);
add(stop);
add(timer);
add(speed);
add(score);
add(playerList);
// Event listeners
start.addActionListener(this);
stop.addActionListener(this);
speed.addChangeListener(this);
playerList.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JComboBox cb = (JComboBox) e.getSource();
String playerChoice = (String) cb.getSelectedItem();
playerList.setSelectedItem(playerChoice);
}
});
// Set focus to false on all game controls
start.setFocusable(false);
stop.setFocusable(false);
speed.setFocusable(false);
playerList.setFocusable(false);
}
#Override
public void actionPerformed(ActionEvent event) {
Object obj = event.getSource();
if (obj == getTim()) {
setI(getI() + 1);
getTimer().setText("Timer: " + getI());
getScore().setText("Field Goals: " + getCurrentScore() + " Tackles: " + getCurrentTackles());
}
if (obj == getStop()) {
getTim().stop();
}
if (obj == getStart()) {
getTim().start();
}
}
#Override
public void stateChanged(ChangeEvent e) {
JSlider source = (JSlider) e.getSource();
int currentSpeed = (int) source.getValue();
if (currentSpeed == 0) {
int delaySpeed = getTim().getDelay();
delaySpeed = (int) 2000;
getTim().setDelay(delaySpeed);
}
if (currentSpeed == 1) {
int delaySpeed = getTim().getDelay();
delaySpeed = (int) 1000;
getTim().setDelay(delaySpeed);
}
if (currentSpeed == 2) {
int delaySpeed = getTim().getDelay();
delaySpeed = (int) 500;
getTim().setDelay(delaySpeed);
}
}
MyJPanel.java
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class MyJPanel extends JPanel {
public MyJPanel() {
super();
setBackground(Color.gray);
setLayout(new BorderLayout());
ControlPanel gm = new ControlPanel();
GameField gf = new GameField();
add(gm, "North");
add(gf, "Center");
}
}
Thanks to #D.B. I have gotten my code to run as intended. Because I only intend to have two JPanels (Control Panel and Game Panel), I added the panels to pass as arguments to each other. After this, the code started working as intended. Thank you for pushing me into the right step! It was such a simple mistake. Special thanks to #DaveyDaveDave for motivating me to push harder!
Changes I made to my main JPanel object:
public class MyJPanel extends JPanel {
ControlPanel gm = new ControlPanel();
GameField gf = new GameField();
public MyJPanel() {
super();
setBackground(Color.gray);
setLayout(new BorderLayout());
add(gm, "North");
add(gf, "Center");
gf.setCp(gm);
gm.setGf(gf);
}
}
When the program is running, the button is drawn 10X10.
I changed the button 20X20 by Modify Menu.
However, the button is not visible.
Appears when you move the mouse over the button.
Do not be a repaint.
revalidate also not the same.
package com.test;
import java.awt.CardLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
public class MenuTest extends JFrame {
private Dimension dimen, dimen1;
private int xpos, ypos;
private JButton[][] btn = null;
private JPanel p;
private GridLayout grid;
private CardLayout card;
private int rownum;
private int colnum;
private int mineLevel;
public MenuTest() {
super("GAME");
p = new JPanel();
grid = new GridLayout();
card = new CardLayout();
createMenu();
starting();
}
private void createMenu() {
JMenuBar bar = new JMenuBar();
setJMenuBar(bar);
JMenu filemenu = new JMenu("파일(F)");
filemenu.setMnemonic('F');
JMenuItem startmenu = new JMenuItem("게임 시작(S)");
startmenu.setMnemonic('S');
startmenu.setActionCommand("START");
startmenu.addActionListener(new MenuActionListener());
filemenu.add(startmenu);
JMenuItem minecntmenu = new JMenuItem("변경(M)");
minecntmenu.setMnemonic('M');
minecntmenu.setActionCommand("MODIFY");
minecntmenu.addActionListener(new MenuActionListener());
filemenu.add(minecntmenu);
JMenuItem close = new JMenuItem("닫기(C)");
close.setMnemonic('C');
filemenu.add(close);
bar.add(filemenu); //JMenuBar에 JMenu 부착
//도움말 메뉴 만들기--------------------------------
JMenu helpmenu = new JMenu("도움말(D)");
helpmenu.setMnemonic('D'); //단축키를 Alf + D 로 설정
JMenuItem help = new JMenuItem("Help(H)");
help.setMnemonic('H');
helpmenu.add(help);
bar.add(helpmenu);
}
private class MenuActionListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals("START")) {
JOptionPane.showMessageDialog(null, "게임시작", "게임", JOptionPane.YES_NO_OPTION);
} else if (e.getActionCommand().equals("MODIFY")) {
modify();
JOptionPane.showMessageDialog(null, "변경", "게임", JOptionPane.YES_NO_OPTION);
}
}
}
private void modify() {
btn = null;
setRowColnum(20, 20);
MapInit(20);
LayoutSet(400, 500);
}
private void starting() {
setRowColnum(10, 10);
MapInit(10);
LayoutSet(200, 250);
}
private void setRowColnum(int rownum, int colnum) {
this.rownum = rownum;
this.colnum = colnum;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
MenuTest mt = new MenuTest();
}
public void LayoutSet(int w, int h) {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(w, h);
dimen = Toolkit.getDefaultToolkit().getScreenSize();
dimen1 = this.getSize();
xpos = (int) (dimen.getWidth() / 2 - dimen1.getWidth() / 2);
ypos = (int) (dimen.getHeight() / 2 - dimen1.getHeight() / 2);
this.setLocation(xpos, ypos);
this.setVisible(true);
this.setResizable(false);
}
public void MapInit(int minecnt) {
p.removeAll();
setBtn(rownum, colnum);
card = new CardLayout(5, 5);
this.setLayout(card);
grid = new GridLayout(rownum, colnum, 0, 0);
p = new JPanel(grid);
int action_num = 0;
for (int i = 0; i < btn.length; i++) {
for (int j = 0; j < btn[i].length; j++) {
action_num = (i * 10 + j);
btn[i][j] = new JButton();
p.add(btn[i][j]);
}
}
this.repaint();
this.add("View", p);
}
private void setBtn(int row, int col) {
btn = new JButton[row][col];
}
}
When you add/remove components from a visible GUI the basic code is:
panel.remove(...);
panel.add(...);
...
panel.revalidate();
panel.reapint();
After removing/adding all the components you need to do the revalidate() so the layout manager is invoked and all the components are given a size and location. Then the repaint() makes sure the components are painted.
I have a 2d array of Grids (JPanels) that are added to another JPanel using the GridLayout. That JPanel is added to the JFrame. Whenever a click happens on the JFrame I'm attempting to take the Point of the click and determine if any of those Grids in the 2d array contain that Point.
I'm attempting to do this inside frame.addMouseListener...
I know the frame is registering the mouse clicks. For some reason the Grids don't register that they should be containing that Point. Can anyone explain this? if(theView[i][j].contains(me.getPoint())){ This is the line of code that seems to be failing me.
I originally attempted to have the Grids know when they were clicked on so I wouldn't have to coordinate between the frame and grids, but I couldn't get that to work.
Here's the level designer.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.*;
import javax.swing.*;
public class LevelDesigner extends JPanel implements ButtonListener{
private final int SIZE = 12;
private int [][] thePit;
private Grid [][] theView;
private ButtonPanel bp;
public static int val;
private int rows, cols;
private JPanel gridPanel;
private JFrame frame;
public LevelDesigner(int r, int c){
frame = new JFrame();
int h = 10, w = 10;
setVisible(true);
setLayout(new BorderLayout());
setBackground(Color.BLUE);
rows = r;
cols = c;
thePit = new int[r][c];
theView = new Grid[r][c];
gridPanel = new JPanel();
gridPanel.setVisible(true);
gridPanel.setBackground(Color.BLACK);
gridPanel.setPreferredSize(getMaximumSize());
GridLayout gridLayout = new GridLayout();
gridLayout.setColumns(cols);
gridLayout.setRows(rows);
gridPanel.setLayout(gridLayout);
for(int i = 0; i < r; i++){
for(int j = 0; j < c; j++){
theView[i][j] = new Grid(i, j, SIZE, this);
gridPanel.add(theView[i][j]);
}
}
String test [] = {"0", "1","2","3","4","save"};
bp = new ButtonPanel(test, this);
this.add(bp, BorderLayout.SOUTH);
this.add(gridPanel, BorderLayout.CENTER);
frame.addMouseListener(new MouseAdapter(){
public void mousePressed(MouseEvent me) {
for(int i = 0; i < rows; ++i){
for(int j = 0; j < cols; ++j){
if(theView[i][j].contains(me.getPoint())){
theView[i][j].actionPerformed(null);
return;
}
}
}
}
});
frame.setVisible(true);
frame.setExtendedState(java.awt.Frame.MAXIMIZED_BOTH);
frame.setTitle("Epic Crawl - Main Menu");
frame.pack();
frame.setLocationRelativeTo(null);
frame.repaint();
frame.add(this);
}
public String toString(){
int noRows = thePit.length;
int noColumns = thePit[0].length;
String s="";
for (int r=0;r<noRows;r++){
for (int c=0;c<noColumns;c++){
s=s + thePit[r][c] + " ";
}
s=s+"\n";
}
return(s);
}
public void notify( int i, int j){
thePit[i][j] = val;
}
public void print(){
final JFileChooser fc = new JFileChooser();
fc.setCurrentDirectory(new java.io.File("."));
int returnVal = fc.showSaveDialog( null);
if( returnVal == JFileChooser.APPROVE_OPTION ){
try{
PrintWriter p = new PrintWriter(
new File( fc.getSelectedFile().getName() ) );
System.out.println(" printing");
p.println( this );
p.close();
}
catch( Exception e){
System.out.println("ERROR: file not saved");
}
}
}
public void buttonPressed(String buttonLabel, int id){
if(id == 5)
print();
else
val = id;
}
public void buttonReleased( String buttonLabel, int buttonId ){}
public void buttonClicked( String buttonLabel, int buttonId ){}
public static void main(String arg[]){
LevelDesigner levelDesigner = new LevelDesigner(4, 4);
}
}
And here is the Grid.
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.InputStream;
import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.JPanel;
#SuppressWarnings("serial")
public class Grid extends JPanel implements ActionListener{
LevelDesigner grid;
int myI, myJ;
private String[] imageNames = {"dirt.png", "grass.png", "Door.png", "woodfloor.png", "32x32WoodFloor.png"};
BufferedImage gridImage;
private String imagePath;
public Grid(int i, int j, int size, LevelDesigner m){
imagePath = "";
grid = m;
myI = i;
myJ = j;
setBackground(Color.RED);
this.setBorder(BorderFactory.createLineBorder(Color.black));
this.setVisible(true);
}
#Override
public void actionPerformed(ActionEvent ae){
grid.notify(myI, myJ);
imagePath = "Images/" + imageNames[LevelDesigner.val];
gridImage = null;
InputStream input = this.getClass().getClassLoader().getResourceAsStream(imagePath);
try{
gridImage = ImageIO.read(input);
}catch(Exception e){System.err.println("Failed to load image");}
}
public void paintComponent(Graphics g){
super.paintComponent(g); // Important to call super class method
g.clearRect(0, 0, getWidth(), getHeight()); // Clear the board
g.drawImage(gridImage, 0, 0, getWidth(), getHeight(), null);
}
}
The contains method checks if the Point is within the boundaries of the JPanel but using a coordinate system relative to the JPanel. Instead consider using findComponentAt(Point p).
For example:
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.*;
public class TestMouseListener {
private static final int SIDE_COUNT = 4;
private JPanel mainPanel = new JPanel();
private MyGridCell[][] grid = new MyGridCell[SIDE_COUNT][SIDE_COUNT];
public TestMouseListener() {
mainPanel.setLayout(new GridLayout(SIDE_COUNT, SIDE_COUNT));
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[i].length; j++) {
grid[i][j] = new MyGridCell();
mainPanel.add(grid[i][j].getMainComponent());
}
}
mainPanel.addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
Point p = e.getPoint();
Component c = mainPanel.findComponentAt(p);
for (MyGridCell[] gridRow : grid) {
for (MyGridCell myGridCell : gridRow) {
if (c == myGridCell.getMainComponent()) {
myGridCell.setLabelText("Pressed!");
} else {
myGridCell.setLabelText("");
}
}
}
}
});
}
public Component getMainComponent() {
return mainPanel;
}
private static void createAndShowGui() {
TestMouseListener mainPanel = new TestMouseListener();
JFrame frame = new JFrame("TestMouseListener");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel.getMainComponent());
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
class MyGridCell {
private static final int PREF_W = 200;
private static final int PREF_H = PREF_W;
#SuppressWarnings("serial")
private JPanel mainPanel = new JPanel() {
public Dimension getPreferredSize() {
return MyGridCell.this.getPreferredSize();
};
};
private JLabel label = new JLabel();
public MyGridCell() {
mainPanel.setBorder(BorderFactory.createLineBorder(Color.black));
mainPanel.setLayout(new GridBagLayout());
mainPanel.add(label);
}
public Component getMainComponent() {
return mainPanel;
}
public void setLabelText(String text) {
label.setText(text);
}
public Dimension getPreferredSize() {
return new Dimension(PREF_W, PREF_H);
}
}
Component#contains "Checks whether this component "contains" the specified point, where the point's x and y coordinates are defined to be relative to the coordinate system of this component"
This means that the contains will only return true if the Point is within the bounds of 0 x 0 x width x height.
So if the component is position at 400x200 and is sized at 200x200 (for example). When you click within in, the mouse point will be between 400x200 and 600x400, which is actually out side of the relative position of the component (200x200) - confused yet...
Basically, you either need to convert the click point to a relative coordinate within the context of the component you are checking...
Point p = SwingUtilities.convertPoint(frame, me.getPoint(), theView[i][j])
if (theView[i][j].contains(p)) {...
Or use the components Rectangle bounds...
if (theView[i][j].getBounds().contains(me.getPoint())) {...
So, remember, mouse events are relative to the component that they were generated for
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
java swing background image
drawing your own buffered image on frame
I am trying to add a back ground image to my frame, but nothing that I have done works.
I designed a slot machine consisting of several panels added to the container. Now, I am trying to add a nice background to the frame.
I tried using the paint method. But, since I am already using the paint method to paint the reel images, it is not working on the background.
I also tried adding a JLabel, but when I do it overwrites everything or get overwritten depending on how I call it. Following is my code; any help will be much appreciated:
import javax.swing.event.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import sun.audio.*;
public class SlotMachine extends JFrame {
private Container c = getContentPane();
private ImageIcon handleIcon = new ImageIcon("starWars/slot-handle.png");
private ImageIcon quitIcon = new ImageIcon("starWars/quit2.jpg");
private ImageIcon logoIcon = new ImageIcon("starWars/logo3.jpg");
private ImageIcon BG = new ImageIcon("space.jpg");
private JButton spin = new JButton("Spin", handleIcon);
private JButton quit = new JButton("Quit", quitIcon);
private JLabel logo = new JLabel(logoIcon);
private JLabel bankTotal = new JLabel("Empire Total");
private JLabel bankLabel = new JLabel("$1000.00");
private JLabel playerLabel = new JLabel("$1000.00");
private JLabel playerTotal = new JLabel("Rebellion Total");
private Font newFont = new Font("DialogInput",Font.ITALIC, 25);
private JPanel logoPanel = new JPanel(new BorderLayout());
private JPanel moneyPanel = new JPanel(new GridLayout(1, 3, 5, 5));
private JPanel imagePanel;
private JPanel mainPanel = new JPanel(new BorderLayout());
private JPanel bankPanel = new JPanel(new GridLayout(2, 1, 5, 5));
private JPanel playerPanel = new JPanel(new GridLayout(2, 1, 5, 5));
private JPanel panel = new JPanel(new FlowLayout());
private SlotMachine.ReelPanel reel1 = new SlotMachine.ReelPanel();
private SlotMachine.ReelPanel reel2 = new SlotMachine.ReelPanel();
private SlotMachine.ReelPanel reel3 = new SlotMachine.ReelPanel();
private AudioPlayer audioPlayer = AudioPlayer.player;
private AudioDataStream continuousMusic;
private AudioDataStream winMusic;
private AudioDataStream force;
private AudioDataStream force2;
//private AudioDataStream intro;
private ContinuousAudioDataStream audioLoop;
private static final int DELAY = 1000;
private static final double FUNDS = 1000.00;
private static final float PRICE = 1;
private int timerCounter = 0;
private double bank = FUNDS;
private double playerMoney = 1000.00;
private Timer timer = new Timer(DELAY, new SlotMachine.TimeHandler());
public SlotMachine() {
try {
FileInputStream inputStream = new FileInputStream(new File("cantina4.wav"));
AudioStream audioStream = new AudioStream(inputStream);
AudioData audioData = audioStream.getData();
continuousMusic = new AudioDataStream(audioData);
audioLoop = new ContinuousAudioDataStream(audioData);
inputStream = new FileInputStream(new File("Cheer.wav"));
audioStream = new AudioStream(inputStream);
audioData = audioStream.getData();
winMusic = new AudioDataStream(audioData);
inputStream = new FileInputStream(new File("forceNN.wav"));
audioStream = new AudioStream(inputStream);
audioData = audioStream.getData();
force = new AudioDataStream(audioData);
inputStream = new FileInputStream(new File("force2NN.wav"));
audioStream = new AudioStream(inputStream);
audioData = audioStream.getData();
force2 = new AudioDataStream(audioData);
} catch (Exception e) {
e.printStackTrace();
}
audioPlayer.start(force);
// Set the font
spin.setFont(newFont);
quit.setFont(newFont);
bankLabel.setFont(newFont);
bankTotal.setFont(newFont);
playerLabel.setFont(newFont);
playerTotal.setFont(newFont);
// implements start button
spin.setVerticalTextPosition(SwingConstants.BOTTOM);
spin.setHorizontalTextPosition(SwingConstants.CENTER);
spin.setBackground(Color.GREEN);
spin.setForeground(Color.WHITE);
spin.setPreferredSize(new Dimension(100, 370));
spin.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
audioPlayer.stop(force);
audioPlayer.stop(force2);
timer.start();
reel1.startAnimation();
reel2.startAnimation();
reel3.startAnimation();
spin.setEnabled(false);
audioPlayer.start(audioLoop);
}
});
// implements quit button
quit.setBackground(Color.RED);
quit.setForeground(Color.WHITE);
quit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
spin.setEnabled(true);
reel1.stopAnimation();
reel2.stopAnimation();
reel3.stopAnimation();
timer.stop();
audioPlayer.stop(continuousMusic);
audioPlayer.stop(audioLoop);
audioPlayer.stop(winMusic);
timerCounter = 0;
audioPlayer.stop(force);
audioPlayer.start(force2);
imagePanel.repaint(); // without this call for repaint, if you press quit but then choose to cancel
// the curent image and the next image would sometimes overlap this repaint may change the images but they do not overlap.
if (JOptionPane.showConfirmDialog(SlotMachine.this,
"Are you sure you want to quit?", "Quit Option",
JOptionPane.OK_CANCEL_OPTION) == 0) {
audioPlayer.start(force2);
System.exit(0);
}
}
});
// create image panel
imagePanel = new JPanel(new GridLayout(1, 3, 15, 15));
imagePanel.setBackground(Color.WHITE);
imagePanel.add(reel1);
imagePanel.add(reel2);
imagePanel.add(reel3);
// create a panel to hold bank values
bankTotal.setForeground(Color.WHITE);
bankLabel.setForeground(Color.WHITE);
bankPanel.setBackground(Color.GRAY);
bankPanel.add(bankTotal);
bankPanel.add(bankLabel);
// panel to hold player values
playerTotal.setForeground(Color.WHITE);
playerLabel.setForeground(Color.WHITE);
playerPanel.setBackground(Color.GRAY);
playerPanel.add(playerTotal);
playerPanel.add(playerLabel);
// create a panel to add bank and player panels and quit button
//moneyPanel.setBackground(Color.BLACK);
moneyPanel.add(bankPanel);
moneyPanel.add(playerPanel);
moneyPanel.add(quit);
moneyPanel.setOpaque(false);
// this panel adds the reel panel and spin button
panel.setPreferredSize(new Dimension(650, 350));
//panel.setBackground(Color.BLACK);
panel.add(imagePanel);
panel.add(spin);
panel.setOpaque(false);
// create the logo panel
logoPanel.add(logo);
//logoPanel.setBackground(Color.BLACK);
logoPanel.setOpaque(false);
mainPanel.add(logoPanel, BorderLayout.NORTH);
mainPanel.add(panel, BorderLayout.CENTER);
mainPanel.add(moneyPanel, BorderLayout.SOUTH);
mainPanel.setOpaque(false);
//////////////////////////////////// background ???????????????????
/// I could just set backgroung black but i want to add a image
add(mainPanel, BorderLayout.CENTER);
setTitle("Slot Machine");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
setSize(950, 750);
setResizable(false);
setLocationRelativeTo(null);
}
public static void main(String[] args) {
new SlotMachine();
}
public class ReelPanel extends JPanel {
private final static String IMAGE_NAME = "starWars/icon";
protected ImageIcon images[];
private int currentImage = 0;
private final int ANIMATION_DELAY = 150;
private final int TOTAL_IMAGES = 12;
private int width;
private int height;
private Timer animationTimer = new Timer(ANIMATION_DELAY, new SlotMachine.ReelPanel.TimerHandler());
private int index;
public ReelPanel() {
try {
images = new ImageIcon[TOTAL_IMAGES];
for (int count = 0; count < images.length; count++) {
images[ count] = new ImageIcon(IMAGE_NAME + (count + 1) + ".jpg");
}
width = images[ 1].getIconWidth();
height = images[ 1].getIconHeight();
currentImage = 0;
index = 0;
animationTimer.setInitialDelay(0);
} catch (Exception e) {
e.printStackTrace();
}
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
images[ currentImage].paintIcon(this, g, 0, 0);
if (animationTimer.isRunning()) {
currentImage = (int) (Math.random() * TOTAL_IMAGES);
}
}
public void startAnimation() {
animationTimer.start();
}
public void stopAnimation() {
animationTimer.stop();
}
public int getIndex() {
return index;
}
public Dimension getMinimumSize() {
return getPreferredSize();
}
public Dimension getPreferredSize() {
return new Dimension(width, height);
}
private class TimerHandler implements ActionListener {
public void actionPerformed(ActionEvent actionEvent) {
repaint();
index = currentImage;
}
}
}
private class TimeHandler implements ActionListener {
public void actionPerformed(ActionEvent actionEvent) {
audioPlayer.stop(winMusic);
++timerCounter;
if (timerCounter == 2) {
reel1.stopAnimation();
} else if (timerCounter == 3) {
reel2.stopAnimation();
} else if (timerCounter == 4) {
reel3.stopAnimation();
audioPlayer.stop(continuousMusic);
audioPlayer.stop(audioLoop);
timerCounter = 0;
timer.stop();
spin.setEnabled(true);
if (reel1.getIndex() == reel2.getIndex() && reel1.getIndex() == reel3.getIndex()) {
if (playerMoney > 0) {
playerMoney += bank;
} else {
playerMoney = bank;
}
bank = FUNDS;
winMusic.reset();
audioPlayer.start(winMusic);
} else {
bank += PRICE;
playerMoney -= PRICE;
}
bankLabel.setText("$" + bank + 0);
playerLabel.setText("$" + playerMoney + 0);
if (playerMoney <= 0) {
JOptionPane.showMessageDialog(SlotMachine.this,
"You are out of funds. GAME IS OVER", "Error", JOptionPane.ERROR_MESSAGE);
System.exit(1);
}
}
}
}
}
You can simply override paintComponent for your mainPanel and draw the background image in that method. You should choose the appropriate strategy for painting your image (stretch it, keep aspect ratio, repeat horizontally/vertically) but that should not be too hard.
Here is an example that stretches the image over the content pane.
import java.awt.BorderLayout;
import java.awt.Graphics;
import java.net.MalformedURLException;
import java.net.URL;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class TestBackgroundImage {
private static final String BACKHGROUND_IMAGE_URL = "http://cache2.allpostersimages.com/p/LRG/27/2740/AEPND00Z/affiches/blue-fiber-optic-wires-against-black-background.jpg";
protected void initUI() throws MalformedURLException {
JFrame frame = new JFrame(TestBackgroundImage.class.getSimpleName());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final ImageIcon backgroundImage = new ImageIcon(new URL(BACKHGROUND_IMAGE_URL));
JPanel mainPanel = new JPanel(new BorderLayout()) {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(backgroundImage.getImage(), 0, 0, getWidth(), getHeight(), this);
}
#Override
public Dimension getPreferredSize() {
Dimension size = super.getPreferredSize();
size.width = Math.max(backgroundImage.getIconWidth(), size.width);
size.height = Math.max(backgroundImage.getIconHeight(), size.height);
return size;
}
};
mainPanel.add(new JButton("A button"), BorderLayout.WEST);
frame.add(mainPanel);
frame.setSize(400, 300);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
try {
new TestBackgroundImage().initUI();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
}
Set the layout of your main panel to BorderLayout
Create a JLabel and add it to you main panel
Set the image icon of the label using your background image
Set the layout of the label to what ever you want to use
Continue adding your components to the label as you normally would
An example can be found here