I'm trying to display 15 images on JButton and I tried to run it; however, I got this error message:
Exception in thread "main"java.lang.NullPointerException at
javax.swing.ImageIcon.<init>(ImageIcon.java:217).
All the images are stored in same folder for GUIClass class.
Here is my code:
private JFrame frame = new JFrame(); // Create frame
private JButton[][]grid; // Name the grid of buttons
public GUIClass(int width, int length){
frame.setLayout(new GridLayout(width,length));
grid = new JButton[width][length];
for(int y = 0; y < length; y++){
for(int x = 0; x < width; x++){
grid[x][y] = new JButton(new ImageIcon(this.getClass().getResource(x + ".png")) );
frame.add(grid[x][y]);// Adds button to grid
}
}
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
public static void main(String[]args){
new SupplyHouseTest(16,16);// Makes new ButtonGrid with 2 parameters
}
I tried new ImageIcon(this.getClass().getResource(Integer.toString(x) + ".png")) but I still get the same error.
All the images are stored in Source Package.
Related
I am attempting to use Java Swing to create a Grid that allows me to access specific panels if I need to. The frame pulls up but there are no panels. I would like some advice on how to make the panels display in the frame while still allowing me to access the specific panel through the two dimensional array.
x=0;
y=0;
z=0;
JPanel[][] coordinate = new JPanel[5][5];
JFrame frame = new JFrame();
JPanel panel = new JPanel();
frame.setSize(550,550);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.setResizable(false);
panel.setBackground(Color.WHITE);
panel.setLayout(new GridLayout(5,5));
for(int i = 0; i<25; i++) {
if(z == 5) {
z = 0;
x = 0;
y++;
}
coordinate[x][y] = new JPanel();
coordinate[x][y].setBorder(BorderFactory.createLineBorder(Color.BLACK, 10));
panel.add(coordinate[x][y]);
z++;
x++;
}
frame.add(panel);
I made a class which takes as parameters 2 dimentions ( n,m ) and a matrix ( mat ). This class makes a JFrame,fills it with buttons colored white(for 1's) or black( for 0's).
The issue is, the matrix being sent is continually changing and i want the button colors to update. If i set the mainframe game = new mainframe(n,m,mat) inside the loop im changing the matrix in,it continually spawns JFrame windows.
I read some stuff on this site that using repaint() or revalidate() could do something like this. I tried putting it in various segments of code but had no luck with it.
The main class is just a loop which calls "mainframe" and updates a matrix in a loop. Here is the class which makes the actual GUI work:
package game;
import java.awt.Color;
public class mainframe extends Jframe {
public mainframe(int n,int m,int mat[][]){
JButton[] buttons = new JButton[n*m];
setSize(600,400);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
setLayout(new GridLayout(n,m));
for(int i = 0; i<n*m;i++) {
buttons[i] = new JButton();
}
int counter = 0;
for(int j=0;j<n;j++){
for(int k=0;k<m;k++){
if(mat[j][k]==0){
buttons[counter].setBackground(Color.BLACK);
}
add(buttons[counter]);
counter++;
}
}
}
}
Put the setVisible(true); or revalidate(); after you added your components. Better work with the frame content pane.
import javax.swing.*;
import java.awt.*;
class Scratch {
public static void main(String[] args) throws InterruptedException {
JFrame jFrame = new JFrame();
jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jFrame.setSize(600, 400);
jFrame.setVisible(true);
for (int i = 5; i < 10; ++i) {
jFrame.setContentPane(createPanel(i, i, new int[i][i]));
jFrame.revalidate();
Thread.sleep(1000);
}
}
public static JPanel createPanel(int n, int m, int[][] mat) {
JButton[] buttons = new JButton[n * m];
JPanel jPanel = new JPanel();
jPanel.setLayout(new GridLayout(n, m));
for (int i = 0; i < n * m; i++) {
buttons[i] = new JButton();
}
for (int j = 0; j < n; j++) {
for (int k = 0; k < m; k++) {
int index = k + k * j;
if (mat[j][k] == 0) {
buttons[index].setBackground(Color.BLACK);
}
jPanel.add(buttons[index]);
}
}
return jPanel;
}
}
I need to use Custom Locations for my JFrame components, I have tried looking in Java's Document about Using the insets object for making a custom location but i dont really understand that well...
if you got any ways to add components in custom locations or a good tutorial/web/other that i can easily learn how to use custom locations.
if you haven't tried null layout, then check out this code, may be of help
public static void main(String[] args) {
SwingUtilities.invokeLater(NullLayout::new);
}
NullLayout() {
JFrame frame = new JFrame("Basket Game");
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
for (int i = 0; i < 4; i++) {
JPanel strip = new JPanel();
strip.setMaximumSize(new Dimension(Integer.MAX_VALUE, 50));
strip.setBorder(BorderFactory.createTitledBorder("Strip " + i));
strip.add(new JLabel("Strip " + i));
mainPanel.add(strip);
}
JPanel gamearea = new JPanel();
gamearea.setLayout(null);
mainPanel.add(gamearea);
for (int i = 0; i < 5; i++) {
int x = i * 100, y = i * 100;
JPanel basket = new JPanel();
basket.setSize(200, 50);
basket.setLocation(x, y);
basket.setBackground(Color.YELLOW);
basket.add(new JLabel("x = " + x + ", y = " + y));
gamearea.add(basket);
}
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(mainPanel);
frame.pack();
frame.setResizable(false);
frame.setSize(600, 600);
frame.setVisible(true);
}
}
private static void initGUI(char[][] code){
int width = (int) (code[0].length * new JLabel().getFont().getSize2D());
int height = (int) (code.length * new JLabel().getFont().getSize2D()) + 200;
gridgui = new JLabel[code.length][code[0].length];
for(int x = 0; x < code.length; ++x){
for(int y = 0; y < code[0].length; ++y){
gridgui[x][y] = new JLabel();
gridgui[x][y].setText(""+code[x][y]);
gridgui[x][y].setBackground(Color.WHITE);
gridgui[x][y].setOpaque(true);
}
}
listModel = new DefaultListModel<Integer>();
listModel.addElement(5);
//Create the list and put it in a scroll pane.
stacklist = new JList<Integer>(listModel);
JScrollPane listScrollPane = new JScrollPane(stacklist);
listScrollPane.getViewport().setView(stacklist);
frame = new JFrame("Befunge 93! Wow!");
gridpanel = new JPanel();
gridpanel.setLayout(new GridLayout(gridgui.length, gridgui[0].length));
gridpanel.setPreferredSize(new Dimension(width, height));
for(int x = 0; x < gridgui.length; ++x){
for(int y = 0; y < gridgui[0].length; ++y){
gridpanel.add(gridgui[x][y]);
}
}
stackpanel = new JPanel();
stackpanel.setLayout(new GridLayout(100, height));
stackpanel.setPreferredSize(new Dimension(width, height));
stackpanel.add(listScrollPane);
JPanel container = new JPanel();
container.setLayout(new BoxLayout(container, BoxLayout.X_AXIS));
container.add(gridpanel);
container.add(stackpanel);
frame.add(container);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
I would have put less and more compact code, but I honestly have no clue where the problem could be.
The issue is that the items in the JList stacklist don't show up. It just looks like this:
(source: mediafire.com)
(with the arrow pointing to the JList)
I've been troubleshooting this for hours and I fear it's something painfully obvious that will cause my to quit programming forever.
I think you need to understand how GridLayout works...
stackpanel.setLayout(new GridLayout(100, height));
Basic says, create me a grid which has 100 rows and height number of columns...This is reserving space for each cell...
If I change it to...
stackpanel.setLayout(new GridLayout(code.length, 1));
I get...
But I'm only guess at what it is you're trying to achieve...
You should also avoid using setPreferredSize where you can
The problem is when I set the background color of the square JPanel as square.setBackground(colors[j]) the square draws only the first color of the list of colors without displaying the other 3. This is my code:
import java.awt.*;
import java.util.*;
import javax.swing.*;
import java.awt.*;
#SuppressWarnings({ "unused", "serial" })
public class RegionPartition extends JFrame
{
JLayeredPane layeredPane;
JPanel regionBoard;
JLabel regionPiece;
private static int DELAY = 200;
private Color[] colors = new Color[]{Color.PINK, Color.GREEN, Color.BLACK, Color.RED};
public RegionPartition()
{
Dimension boardSize = new Dimension(500, 500);
// Use a Layered Pane for this this application
layeredPane = new JLayeredPane();
getContentPane().add(layeredPane);
layeredPane.setPreferredSize(boardSize);
regionBoard = new JPanel();
layeredPane.add(regionBoard, JLayeredPane.DEFAULT_LAYER);
regionBoard.setLayout( new GridLayout(4, 4) );
regionBoard.setPreferredSize( boardSize );
regionBoard.setBounds(0, 0, boardSize.width, boardSize.height);
Random random = new Random();
for (int i = 0; i < 16; i++) {
JPanel square = new JPanel(new BorderLayout());
square.setBorder(BorderFactory.createLineBorder(Color.black));
regionBoard.add( square );
square.setBackground(Color.green);
int j=0;
square.setBackground(colors[j]);
j++;
}
}
{
JPanel panel = new JPanel()
{
Clients[] c = new Clients[128];
Random random = new Random();
private final int SIZE = 450;
private int DELAY = 9999999;
public void paintComponent (Graphics g)
{
super.paintComponent(g);
for (int i=0; i<c.length; i++)
{
int x = ( int ) ( random.nextFloat() * SIZE ) + 10;
int y = ( int ) ( random.nextFloat() * SIZE ) + 10;
g.drawOval( x, y, 10, 10 );
g.fillOval(x, y, 10, 10);
}
for (int j=0; j<DELAY; j++)
{
repaint();
}
}
};
panel.setOpaque(false);
//Set the glass pane in the JFrame
setGlassPane(panel);
//Display the panel
panel.setVisible(true);
}
public static void main(String[] args)
{
JFrame frame = new RegionPartition();
frame.setDefaultCloseOperation(DISPOSE_ON_CLOSE );
frame.pack();
frame.setResizable(true);
frame.setLocationRelativeTo( null );
frame.setVisible(true);
}
protected void paintComponent(Graphics g)
{
// TODO Auto-generated method stub
}
}
That is because you are always setting j to 0 on each iteration:
int j=0;
square.setBackground(colors[j]);
j++;
you may want to change j for an i or do a nested loop, that depends on what you really want to do here.
If you want to make all 16 squares have all four colors in a grid like manner, you might want to change your loop to something like:
for (int i = 0; i < 16; i++) {
JPanel square = new JPanel(new GridLayout(2,2));
square.setBorder(BorderFactory.createLineBorder(Color.black));
regionBoard.add( square );
for(int j=0; j<4; ++j){
JPanel insideSquare = new JPanel();
insideSquare.setBackground(colors[j]);
square.add(insideSquare);
}
}
Because you only have 4 colors in your color array, but your loop index exceeds this, you could use:
square.setBackground(colors[ i % colors.length]);
to alternate the colors of your squares.
You are instantiating int j within the scope of your for loop, so its value is not preserved across multiple iterations. You should declare it at a point in your code to allow it scope over your entire for loop.
int j = 0;
<for loop>
square.setBackground(colors[j]);
j++;
<end for>
However, your j is serving the purpose of i in this situation, where i is sufficient as an array index. It would be more correct to remove j entirely and instead do the following:
square.setBackground(colors[i]);