I'm trying to show a 2D matrix when fill two text fields (rows and columns) but I don't know how to print the 2D matrix when this two text field are filled and the "Draw" button is pushed.
This is my code:
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.io.*;
public class InputOutput extends JFrame{
JTextField mtf;
JTextField ntf;
JButton button;
public InputOutput(){
setLayout (new FlowLayout ());
mtf = new JTextField(10);
ntf = new JTextField(10);
add(mtf);
add(ntf);
button = new JButton("Dibujar");
add(button);
event e = new event();
button.addActionListener(e);
}
public class Cuadricula extends JComponent{
final int height = 30;
final int width = 30;
int posicionx=0;
int posiciony=0;
public Cuadricula(int x,int y){
setBounds(x,y,width+1, height+1);
}
#Override
public void paintComponent (Graphics g){
super.paintComponent(g);
g.drawRect(0,0,width,height);
}
}
public class event implements ActionListener{
public void actionPerformed(ActionEvent e){
String Sm = mtf.getText();
String Sn = ntf.getText();
int m = Integer.parseInt(Sm);
int n = Integer.parseInt(Sn);
Cuadricula casillas[] = new Cuadricula[m*n];
int i,j;
int k = 0;
while (k < m*n){
for(i=0; i < m; i++){
for(j=0; j < n; j++){
casillas[k] = new Cuadricula(i*30,j*30);
k++;
}
}
}
//HERE IS WHAT I DON'T KNOW HOW TO DO
for(int i = 0; i < 16; i++){
gui.getContentPane().add(casillas[i]);
}
}
}
public static void main(String[] args){
InputOutput gui = new InputOutput();
gui.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
gui.setSize(300,150);
gui.setTitle("Writer");
gui.setVisible(true);
gui.getContentPane().setLayout(null);
}
}
Related
I'm in the process of making a memory game with java. I have a class that extends JButton that is used to draw the cards and I have a main runner class. Here is my Card class.
import java.awt.Color;
import java.awt.Dimension;
import javax.swing.*;
public class Card extends JButton {
private String cardValue;
private boolean matched = false;
private int width = 70;
public int x;
public int y;
public Card(int x, int y) {
this.x = x;
this.y = y;
setPreferredSize(new Dimension(x, y));
}
public void drawFaceDown() {
setBackground(new Color(214, 247, 202));
setBorder(BorderFactory.createLineBorder(Color.BLACK, 2));
};
}
and here is my Runner class
import java.util.List;
import java.util.ArrayList;
public class Runner {
public static void main(String[] args) {
List<Card> tiles = new ArrayList<Card>();
int NUM_COLS = 5;
int NUM_ROWS = 4;
for (int i = 0; i < NUM_COLS; i++) {
for (int j = 0; j < NUM_ROWS; j++) {
tiles.add(new Card(i * 78 + 10, j * 78 + 40));
}
}
for (int i = 0; i < tiles.size(); i++) {
tiles.get(i).drawFaceDown();
}
}
}
In the for loop I try to use the drawFaceDown() however nothing is drawn on the graphics panel. Can someone help me with what's going on.
You should add the Cards to a JFrame. Going by your code, GridLayout will be the best for you. Change your Runner class like so. I have scaled the size of buttons a bit.
import java.util.List;
import java.util.ArrayList;
import javax.swing.*;
import java.awt.*;
public class Runner {
public static void main(String[] args) {
List<Card> tiles = new ArrayList<Card>();
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
int NUM_COLS = 5;
int NUM_ROWS = 4;
frame.setLayout(new GridLayout(NUM_ROWS, NUM_COLS));
for (int i = 0; i < NUM_COLS; i++) {
for (int j = 0; j < NUM_ROWS; j++) {
tiles.add(new Card(i * 8 + 10, j * 8 + 40));
}
}
for (int i = 0; i < tiles.size(); i++) {
frame.add(tiles.get(i));
tiles.get(i).drawFaceDown();
}
frame.pack();
frame.setVisible(true);
}
}
Also, read this tutorial.
You should add the button to Panel in order to show it somewhere. Something like:
JFrame f = new JFrame();
f.add(tiles.get(i).drawFaceDown());
In a Java applet, I'm trying to slow down the painting of an image made up of parts, so I wrote a test program to get the basic concept working. I'm using a thread to draw a number of boxes one at a time instead of a timer because I want to be able to click the go button to reset the drawing process at any time.
The problem is, after drawing a box, it moves down a bit and an extra of the label shows up at the top of the screen. When the mouse moves off the button at the bottom, a dummy button also shows up at the top of the screen. The dummy button doesn't respond to clicks (only the real one at the bottom does), it's just there.
I'm still pretty new at this, so any help would be greatly appreciated.
Here's the JApplet class:
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class TestDraw extends JApplet implements ActionListener
{
private DrawPanel panel;
private JLabel lbl1;
JButton go;
Thread t;
public void init()
{
lbl1 = new JLabel("hi");
go = new JButton("GO");
go.addActionListener(this);
panel = new DrawPanel();
getContentPane().setBackground(Color.yellow);
add(lbl1, BorderLayout.NORTH);
add(panel, BorderLayout.CENTER);
add(go, BorderLayout.SOUTH);
}
public void actionPerformed(ActionEvent ae){
// tried adding these. didnt help
//panel.validate();
//panel.repaint();
//validate();
panel.resetBoxes();
repaint();
}
public void start(){
t = new Thread(panel);
t.start();
}
}
Here's the DrawPanel Class:
import java.awt.*;
import java.security.SecureRandom;
import javax.swing.*;
public class DrawPanel extends JPanel implements Runnable
{
private SecureRandom randGen = new SecureRandom();
private Box[] boxes;
private int box2draw = 0;
public DrawPanel()
{
setBackground(Color.WHITE);
boxes = new Box[5];
for (int count = 0; count < boxes.length; count++){
int x = randGen.nextInt(300);
int y = randGen.nextInt(300);
int w = randGen.nextInt(300);
int h = randGen.nextInt(300);
Color color = new Color(randGen.nextInt(256), randGen.nextInt(256), randGen.nextInt(256));
boxes[count] = new Box(x,y,w,h,color);
}
}
public void paintComponent(Graphics g)
{
boxes[box2draw].draw(g);
box2draw++;
}
public void resetBoxes(){
boxes = new Box[5];
for (int count = 0; count < boxes.length; count++){
int x = randGen.nextInt(300);
int y = randGen.nextInt(300);
int w = randGen.nextInt(300);
int h = randGen.nextInt(300);
Color color = new Color(randGen.nextInt(256), randGen.nextInt(256), randGen.nextInt(256));
boxes[count] = new Box(x,y,w,h,color);
box2draw = 0;
}
}
public void run(){
while(true){
try{
Thread.sleep(750);
}
catch(InterruptedException e){
JOptionPane.showMessageDialog(null, "interrupted");
}
repaint();
}
}
}
And finally, the Box class:
import java.awt.Color;
import java.awt.Graphics;
public class Box
{
private int x;
private int y;
private int w;
private int h;
private Color color;
public Box(int x,int y,int w,int h,Color color)
{
// initialise instance variables
this.x = x;
this.y=y;
this.w=w;
this.h = h;
this.color=color;
}
public void draw(Graphics g)
{
g.setColor(color);
g.drawRect( x, y, w, h);
}
}
Thank you for your time!
Problems:
You've got code logic within a painting method -- something that you should never do -- including your incrementing an array index. You don't have full control of when or even if this method is called and so program logic does not belong there, just painting. If you need to increment your array index, do it elsewhere, perhaps within your thread's while (true) loop. Also take care not to have the index go beyond the size of the array.
You never call the super's paintComponent method within your override, and this will prevent the component from doing housekeeping painting, probably your main problem.
If you need to display multiple items, then consider either drawing to a BufferedImage and displaying that within paintComponent, or creating a collection of Shape objects and drawing all of them within paintComponent via a for-loop.
I prefer to use the Swing-safer Swing Timer. While it doesn't matter if only calling repaint() if you want to make any other Swing calls intermittently, it makes life much easier and coding safer.
For example
package foo1;
import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Stroke;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
public class TestDraw2 {
#SuppressWarnings("serial")
private static void createAndShowGui() {
final DrawPanel2 drawPanel = new DrawPanel2();
JButton drawButton = new JButton(new AbstractAction("Draw!") {
#Override
public void actionPerformed(ActionEvent e) {
drawPanel.resetBoxes();
}
});
JPanel btnPanel = new JPanel();
btnPanel.add(drawButton);
JFrame frame = new JFrame("TestDraw2");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(drawPanel);
frame.getContentPane().add(btnPanel, BorderLayout.PAGE_END);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
#SuppressWarnings("serial")
class DrawPanel2 extends JPanel {
private static final int BOX_COUNT = 5;
private static final int TIMER_DELAY = 750;
private static final int PREF_W = 600;
private static final int PREF_H = PREF_W;
private Random randGen = new Random();
private Box[] boxes;
private int box2draw = 0;
public DrawPanel2() {
setBackground(Color.YELLOW);
boxes = new Box[BOX_COUNT];
for (int count = 0; count < boxes.length; count++) {
int x = randGen.nextInt(300);
int y = randGen.nextInt(300);
int w = randGen.nextInt(300);
int h = randGen.nextInt(300);
Color color = new Color(randGen.nextInt(256), randGen.nextInt(256),
randGen.nextInt(256));
boxes[count] = new Box(x, y, w, h, color);
}
}
#Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
for (int i = 0; i < box2draw; i++) {
boxes[i].draw(g);
}
}
public void resetBoxes() {
boxes = new Box[BOX_COUNT];
for (int count = 0; count < boxes.length; count++) {
int x = randGen.nextInt(300);
int y = randGen.nextInt(300);
int w = randGen.nextInt(300);
int h = randGen.nextInt(300);
Color color = new Color(randGen.nextInt(256), randGen.nextInt(256),
randGen.nextInt(256));
boxes[count] = new Box(x, y, w, h, color);
box2draw = 0;
}
repaint();
new Timer(TIMER_DELAY, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
box2draw++;
if (box2draw > BOX_COUNT) {
box2draw = BOX_COUNT;
((Timer) e.getSource()).stop();
}
repaint();
}
}).start();
}
}
I made a game of minesweeper with jbuttons and I have no clue how to access all of the buttons again to reveal the final game after you lose. I set the text by using the setText method with jbuttons but i have no clue how to access them again.This is how I created all of the buttons if it helps:
for(int x = 0; x < rows ;x++)
{
for(int j = 0; j < columns; j++)
{
MineButton button = new MineButton(x,j);
// adds a mouselistener for every button
button.addMouseListener(new MouseHandler());
this.add(button);
}
}
I can change it into an array of jbuttons but I don't think that I can reveal them all through that. Any advice is welcome.
You should create some array, which will be store references to all buttons. Please see my little example, which should help you to understand how it works:
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class MineSweeper {
public static void main(String[] args) {
MainFrame window = new MainFrame();
window.setVisible(true);
}
}
/**
* Main frame. Initialize window and adds panel with buttons and clear button on
* the window.
* */
class MainFrame extends JFrame {
private static final long serialVersionUID = 1L;
private final Board board = new Board(10, 11);
public MainFrame() {
setLocation(400, 400);
setLayout(new GridLayout(2, 1));
add(board);
add(createClearButton());
pack();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
private JButton createClearButton() {
JButton button = new JButton();
button.setText("Clear");
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
board.clear();
}
});
return button;
}
}
/***
* This class contains all buttons on one panel. We initialize all buttons in
* constructor. We can use {#link Board#clear()} method for reveal all buttons.
* */
class Board extends JPanel {
private static final long serialVersionUID = 1L;
private JButton[][] plate;
private int numberOfRows;
private int numberOfColumns;
public Board(int numberOfRows, int numberOfColumns) {
this.numberOfRows = numberOfRows;
this.numberOfColumns = numberOfColumns;
this.plate = new JButton[numberOfColumns][numberOfRows];
setLayout(new GridLayout(numberOfRows, numberOfColumns));
init();
}
private void init() {
for (int x = 0; x < numberOfColumns; x++) {
for (int y = 0; y < numberOfRows; y++) {
JButton button = createNewJButton(x, y);
plate[x][y] = button;
add(button);
}
}
}
private JButton createNewJButton(int x, int y) {
JButton button = new JButton();
button.setText(x + ", " + y);
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JButton button = (JButton) e.getSource();
button.setText("X");
}
});
return button;
}
public void clear() {
for (int x = 0; x < numberOfColumns; x++) {
for (int y = 0; y < numberOfRows; y++) {
plate[x][y].setText(x + ", " + y);
}
}
}
}
I would like to make a graphical representation of the audio signal.
I have a problem with entering data array to the method paint (Graphics g).
Data entered in the method setData(int intValue) works fine.
But if I want to print a data array in the method paint() I have zero values.
Why?
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JPanel;
public class MyPlotter extends JPanel{
int width = 320;
int height = 130;
int frameSize;
int[] data;
public MyPlotter(int fSize){
setSize(width,height);
setPreferredSize(this.getSize());
this.frameSize = fSize;
data = new int[fSize+1];
}
public void setData(int[] intValue){
data = intValue;
// this works fine:
for (int i=0; i<440; i++)
System.out.println("setData "+data[i]);
repaint();
}
public void paint (Graphics g){
// some code:
// g.drawLine(...)
// g.setColor(...)
// etc...
for (int i = 0; i< frameSize-1;i++)
{
//ZERO values:
System.out.println("paint() "+(data[i]));
// g.drawline(...);
}
}
}
Edit:
Array Data is entered from MyPanel.class
import javax.swing.JPanel;
public class MyPanel extends JPanel {
private MyPlotter plotter;
public MyPanel(){
setSize(320,210);
plotter = new MyPlotter(440);
add(this.plotter,0);
}
public void setData(int[] data){
plotter.setData(data);
}
}
data = intValue;
Here you are psssing reference of intValue to data. If you change data intValue array also get changed.
Try this :
data = System.arraycopy( intValue, 0, data, 0, intValue.length);
Instead of :
data = intValue;
I think that possibly the "repaint()" method you called modifies the original array "intValue"
The assignment you have made data = intValue; only makes "data[]" a reference of your original array so as repaint is called seems like the data is reset or the reference is lost.If you want to copy the array you can do any of the following if a & b are two arrays:
b = Arrays.copyOf(a, a.length);
0r
b = new int[a.length];
System.arraycopy(a, 0, b, 0, b.length);
or
b = (int[]) a.clone();
or
int b[] = new int[a.length];
for (int i = 0; i < a.length; i++) {
b[i] = a[i];
}
Your code is OK. The problem is in the main method. Ensure you have added only one plotter to the panel.
public static void main(String[]args){
int[] mass = new int[]{1,2,3,4,5,6,7,8,9,10};
JFrame frame = new JFrame();
MyPanel mp = new MyPanel();
frame.add(mp);
frame.setSize(300, 300);
mp.setData(mass);
frame.setVisible(true);
}
Works well.
I'm sorry to answer my own post, but I changed the program completely.
I do not know if I can remove the code from the first post. So I put in a new post.
I changed a application but still have a problem with entering the array to another method.
Copy arrays by "Arrays.copyOf b = (a, a.length)" and changing the array as static does not fix a problem.
I can't enter array from setSignal() to getSignal() in OscilloscopeController class.
OscilloscopeController.java
import java.util.Arrays;
import java.util.Random;
public class OscilloscopeController {
private static int frameSize = (int) (44100 / 100F);
private int idx, numFramesToSkip = 10;
private static int[] toDraw = new int[frameSize];
private static int[] data = new int[frameSize];
public OscilloscopeController() {
for (int i = 0; i < frameSize; i++) {
toDraw[i] = 0;
data[i] = 0;
}
}
public void setSignal(int in) {
// Because the Model layer is off, I generate a test signal
Random randomGenerator = new Random();
int j = 0;
for (int i = 0; i < 44100; i++) {
int randomInt = randomGenerator.nextInt(32675 * 2) - (32675);
if (i % 4 == 0) {
j = randomInt;
}
in = j;
}
if (idx++ > frameSize * numFramesToSkip)
{
idx = 0;
}
else
{
if (idx < frameSize) {
data[idx] = in;
}
if (idx == frameSize)
{
// HERE IS PROBLEM. I'D LIKE THIS toDraw in getSignal()
toDraw = Arrays.copyOf(data, data.length);
}
}
}
public int[] getSignal() {
// IF UNCOMMENT BELOW WORKS FINE, OTHERWISE ZERO VALUES
/*
Random randomGenerator = new Random();
int j=0;
for (int i = 0; i < 440; i++) {
int randomInt = randomGenerator.nextInt(32675*2)-(32675);
if (i%4==0) j = randomInt;
toDraw[i]=j;
}
*/
for (int i = 0; i < frameSize; i++)
System.out.println("Controller.getSignal() = "+ toDraw[i]);
return toDraw;
}
}
MainPanel contains main method:
import java.awt.*;
import javax.swing.*;
public class MainPanel extends JPanel {
public static void main(String args[]) throws Exception {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new MainPanel());
frame.pack();
frame.setVisible(true);
}
});
}
private final OscilloscopeView oscView = new OscilloscopeView();
private final OscilloscopeController oscController = new OscilloscopeController();
public MainPanel() {
setPreferredSize(new Dimension(400, 200));
// a lot of other components here
oscView.setData(oscController.getSignal());
add(oscView);
}
}
OscilloscopeView.java
import javax.swing.JFrame;
import javax.swing.JPanel;
public class OscilloscopeView extends JPanel {
private OscPlotter plotter = new OscPlotter(441);;
public OscilloscopeView()
{
setSize(320,210);
add(this.plotter);
}
public void setData(int[] data){
plotter.setData(data);
}
}
OscPlotter.java
import java.awt.Color;
import java.awt.Graphics;
import java.util.Arrays;
import javax.swing.JPanel;
public class OscPlotter extends JPanel{
private int width = 320;
private int height = 130;
private float widthC;
private float heightC;
private int sampleSize;
private int frameSize;
private int[] toDraw;
private float x,prevX;
public OscPlotter(int fSize){
setSize(width,height);
setPreferredSize(this.getSize());
this.frameSize = fSize;
this.toDraw = new int[441];
sampleSize = 1;
}
public void setData(int[] data){
toDraw = Arrays.copyOf(data, data.length);
repaint();
}
#Override
public void paintComponent(Graphics g){
widthC = ((float)width/frameSize);
sampleSize = (16 == 16 ? 65536 : 256);
heightC = (((float)height-15)/sampleSize);
g.setColor(Color.black);
g.fillRect(0,0,width,height);
g.setColor(Color.gray);
for (int i = 1; i<height;i+=height/8)
g.drawLine(0,i,width,i);
for (int i = 1; i<width;i+=width/8)
g.drawLine(i,0,i,height);
g.setColor(Color.lightGray);
g.drawLine(0,(int)(height/2),width,(int)((height/2)));
g.setColor(Color.green);
x = 0;
for (int i = 0; i< frameSize-1;i++)
{
prevX = x;
x +=widthC;
// draw the read waveform data
g.drawLine ((int)prevX,(int)((height/2+toDraw[i]*heightC)),(int)x,(int)((height/2+toDraw[i+1]*heightC)));
}
}
}
Im trying to use SwingWorker to update my gui.
The part of my gui that I'm trying to update is a JPanel (gridPanel) with a GridLayout [50][50].
Each grid in the GridLayout has a custom GridGraphic JComponent.
In the doInBackground() of my SwingWorker, I update each GridGraphic which represents some color. Then, I publish it to a List that the process() uses to update the gui. Though, the gui isn't updating.
Is there a way to do this without calling repaint().
How do I fix my SwingWorker so the gui is responsive. What do I want to return in order for the gridPanel, which is a [50][50] GridLayout of GridGraphic components responsive to changes
The SwingWorker is executed in the stepButton.addActionListener(new ActionListener()...............in SlimeGui
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import javax.swing.event.*;
public class SlimeGui extends JFrame{
private JPanel buttonPanel, populationPanel, velocityPanel;
private JPanel gridPanel = new JPanel(new GridLayout(50, 50));
private JButton setupButton, stepButton, goButton;
private JLabel populationNameLabel, velocityNameLabel, populationSliderValueLabel, velocitySliderValueLabel;
private JSlider populationSlider, velocitySlider;
private GridGraphic [] [] gridGraphic;
private GridGraphic test;
private int agents = 125;
private int velocity = 500;
private boolean resetGrid;
public SlimeGui() {
setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
//Set up JButtons
buttonPanel = new JPanel();
setupButton = new JButton("Setup");
stepButton = new JButton("Step");
goButton = new JButton("Go");
buttonPanel.add(setupButton);
buttonPanel.add(stepButton);
buttonPanel.add(goButton);
c.gridx = 0;
c.gridy = 1;
c.gridwidth = 3;
add(buttonPanel, c);
//Set up population JSlider
populationPanel = new JPanel();
populationNameLabel = new JLabel(" Population");
populationSliderValueLabel = new JLabel(Integer.toString(agents));
populationSlider = new JSlider(JSlider.HORIZONTAL,0, 1000, 125);
populationSlider.setMajorTickSpacing(125);
populationSlider.setPaintTicks(true);
populationSlider.addChangeListener(new PopulationSliderListener());
populationPanel.add(populationNameLabel);
populationPanel.add(populationSlider);
populationPanel.add(populationSliderValueLabel);
c.gridx = 0;
c.gridy = 2;
add(populationPanel, c);
//Set up veolicty JSlider
velocityPanel = new JPanel();
velocityNameLabel = new JLabel(" Velocity");
velocitySliderValueLabel = new JLabel(Integer.toString(velocity));
velocitySlider = new JSlider(JSlider.HORIZONTAL,0, 1000, 500);
velocitySlider.setMajorTickSpacing(125);
velocitySlider.setPaintTicks(true);
velocitySlider.addChangeListener(new VelocitySliderListener());
velocityPanel.add(velocityNameLabel);
velocityPanel.add(velocitySlider);
velocityPanel.add(velocitySliderValueLabel);
c.gridx = 0;
c.gridy = 3;
add(velocityPanel, c);
//Set up grid with GridGraphic objects
gridGraphic = new GridGraphic[50][50];
for(int i = 0; i < 50; i++){
for(int j = 0; j < 50; j++){
gridGraphic[i][j] = new GridGraphic();
gridPanel.add(gridGraphic[i][j]);
}
}
c.gridx = 0;
c.gridy = 0;
c.gridwidth = 3;
add(gridPanel, c);
//Set up ActionListener for the 'Setup' JButton
setupButton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
int n1=0;
int n2=0;
//resets the grid so there are no agents
if(resetGrid){
for(int i = 0; i < 50; i++){
for(int j = 0; j < 50; j++){
gridGraphic[i][j].setDefault();
}
}
}
//sets a random number of positions for GridGraphics
for (int numOfAgenets = 0; numOfAgenets < agents; numOfAgenets++){
int lowerB = 0;
int upperB = 50;
n1 = (lowerB + (int)(Math.random()*(upperB-lowerB))); //random number 1
n2 = (lowerB + (int)(Math.random()*(upperB-lowerB))); //random number 2
System.out.println("Choosing random agent "+(numOfAgenets+1)+": "+n1 +" "+n2);
//sets the GridGraphic to an agent if it's available
if (gridGraphic[n1][n2].getIntensity() == 0)
gridGraphic[n1][n2].setAgent();
//if the GridGraphic is already an agent, it continues to search
else if(gridGraphic[n1][n2].getIntensity() == 5){
while(gridGraphic[n1][n2].getIntensity() == 5){
n1 = (lowerB + (int)(Math.random()*(upperB-lowerB)));
n2 = (lowerB + (int)(Math.random()*(upperB-lowerB)));
}
gridGraphic[n1][n2].setAgent();
}
}
repaint();
resetGrid = true;
}
});
//Set up ActionListener for the 'Step' JButton
stepButton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
StepManager step = new StepManager(SlimeGui.this);
step.execute();
//repaint();
}
});
}
class PopulationSliderListener implements ChangeListener{
public void stateChanged(ChangeEvent e){
agents = ((JSlider)e.getSource()).getValue();
populationSliderValueLabel.setText(Integer.toString(agents));
System.out.println("Population of agents: " + agents);
}
}
class VelocitySliderListener implements ChangeListener{
public void stateChanged(ChangeEvent e){
velocity = ((JSlider)e.getSource()).getValue();
velocitySliderValueLabel.setText(Integer.toString(velocity));
System.out.println("Velocity(ms) of agents: " + velocity);
}
}
public Integer getVelocity(){
return velocity;
}
public GridGraphic getGridGraphic(int n1, int n2){
return gridGraphic[n1][n2];
}
public GridGraphic [][] getGridGraphic(){
return gridGraphic;
}
public void setGridGraphicArray(GridGraphic xxx, int n1, int n2 ){
gridGraphic[n1][n2] = xxx;
}
public void setGridPanel(GridGraphic[][] xxx){
for(int i = 0; i < 50; i++){
for(int j = 0; j < 50; j++){
gridPanel.add(xxx[i][j]);
}
}
}
/**
* Create the GUI and show it. For thread safety,
* this method should be invoked from the
* event-dispatching thread.
*/
private static void createAndShowGUI() {
//Create and set up the window.
SlimeGui slime = new SlimeGui();
slime.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Display the window.
slime.pack();
slime.setVisible(true);
slime.setResizable(false);
}
public static void main(String[] args) {
//Schedule a job for the event-dispatching thread:
//creating and showing this application's GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
My SwingWorker
import java.util.List;
import java.awt.*;
import javax.swing.*;
import java.util.concurrent.ExecutionException;
public class StepManager extends SwingWorker<Void, GridGraphic>{
private SlimeGui gui;
public StepManager(SlimeGui sg){
gui=sg;
}
#Override
protected Void doInBackground() throws Exception{
for(int i = 0; i < 50; i++){
for(int j = 0; j < 50; j++){
if(gui.getGridGraphic(i,j).getIntensity()==5){
if (i==0){
gui.getGridGraphic(i,j).setDefault();
gui.getGridGraphic(49,j).setAgent();
}
else{
gui.getGridGraphic(i,j).setDefault();
gui.getGridGraphic(i-1,j).setAgent();
}
}
publish(gui.getGridGraphic(i,j));
}
}
return null;
}
#Override
protected void process(List <GridGraphic> gg){
int k=0;
for ( int i = 0; i < 50; i++ ){
for(int j = 0; j < 50; j++){
gui.setGridGraphicArray(gg.get(k),i,j);
k++;
}
}
gui.setGridPanel(gui.getGridGraphicArray());
System.out.println("process has completed");
}
#Override
protected void done(){
System.out.println("doInBackground has completed");
}
}
My GridGraphic
import java.awt.*;
import javax.swing.*;
public class GridGraphic extends JComponent {
private int intensity = 0;
public GridGraphic() {
//setBorder(BorderFactory.createLineBorder(Color.BLUE));
}
public void paintComponent(Graphics g) {
//paints the GridGraphic black
if (intensity == 0){
super.paintComponent(g);
g.setColor(Color.BLACK);
g.fillRect(0, 0, getWidth(), getHeight());
}
//paints the GridGraphic black with a yellow dot
else if (intensity == 5){
super.paintComponent(g);
g.setColor(Color.BLACK);
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(Color.YELLOW);
g.fillOval(3, 3, getWidth()/2, getHeight()/2);
}
//paints the GridGraphic dark yellow (pheromone)
if (intensity == 2){
super.paintComponent(g);
g.setColor(Color.BLACK.brighter());
g.fillRect(0, 0, getWidth(), getHeight());
}
}
public Dimension getPreferredSize() {
return new Dimension(10, 10);
}
public void setAgent(){
intensity = 5;
}
public void setPheromone1(){
intensity = 2;
}
public void setDefault(){
intensity = 0;
}
public int getIntensity(){
return intensity;
}
}
The line number in the stack trace indicates where the exception occurs. Your gui attribute in StepManager is null. It's never initialized.