How do you draw a method from a class that extends Jbutton - java

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());

Related

Matriz em um AWT Canvas

I'm making a battleship game using SWING. The program reads a file with the following data: height, length, matrix of positions populated with the number of boats. The problem is the matrix that the mouse captures is inverted in comparison with the one in the file and I don't know what to do. I will appreciate any help.
Below is the code:
Frame:
import Model.ArcMap;
import java.awt.BorderLayout;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JFrame;
public class GameFrame extends JFrame {
private GameCanvas canvas;
// CanvasThread updateScreenThread = new CanvasThread(canvas);
private ArcMap archive;
private int width;
private int hight;
public static final int AREA = 60;
public GameFrame(ArcMap archve) {
this.archive = archve;
this.width = archve.getArcWidth();
this.hight = archive.getArcHeight();
canvas = new GameCanvas(archive);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new BorderLayout());
setTitle("Stellar Battle");
add(BorderLayout.CENTER, canvas);
setResizable(false);
// Define largura e altura da janela principal
setSize(AREA * width, canvas.AREA * hight);
setLocationRelativeTo(null);
// setVisible(true);
// Inicia Thread com timer para redesenhar a tela.
// updateScreenThread.start();
canvas.addMouseListener(new MouseListener() {
#Override
public void mouseReleased(MouseEvent e) {
int x = e.getX();
int y = e.getY();
int x_pos = x / canvas.AREA;
int y_pos = y / canvas.AREA;
System.out.println(canvas.getShot(x_pos, y_pos);
}
#Override
public void mouseClicked(MouseEvent e) {
}
#Override
public void mousePressed(MouseEvent e) {
}
#Override
public void mouseEntered(MouseEvent e) {
}
#Override
public void mouseExited(MouseEvent e) {
}
});
}
}
Canvas:
import Model.ArcMap;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.nio.Buffer;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
public class GameCanvas extends Canvas {
public static final int AREA = 40;
private int margin = 0;
private int rows;
private int cols;
private ArcMap achive;
private int[][] explosionMatrix = new int[rows][cols];
public GameCanvas(ArcMap archive) {
this.achive = archive;
this.rows = archive.getArcHeight();
this.cols = archive.getArcWidth();
explosionMatrix = archive.getArcMatrix();
setSize(AREA * rows, AREA * cols);
}
//#Override
public void paint(Graphics g) {
int lenthI = rows;
int lenthJ = cols;
g.setColor(new Color(131, 209, 232));
g.fillRect(0, 0, cols * AREA, rows * AREA);
g.setColor(Color.white);
for (int i = 0; i < cols ; i++) {
g.drawLine(i * AREA, 0, i * AREA, AREA * rows);
for (int j = 0; j < rows; j++) {
g.drawLine(0, j * AREA, AREA * cols, j * AREA);
}
}
this.oque();
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
System.out.print(explosionMatrix[i][j]);
}
System.out.println("");
}
// Prepare an ImageIcon
ImageIcon icon = new ImageIcon("images/ondas_1.jpg");
ImageIcon iconShot = new ImageIcon("images/explosion.png");
// Prepare an Image object to be used by drawImage()
final Image img = icon.getImage();
final Image imgShot = iconShot.getImage();
this.oque();
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
g.drawImage(img, i * AREA, j * AREA, AREA, AREA, null);
if (explosionMatrix[i][j] == 1) {
g.drawImage(imgShot, i * AREA, j * AREA, AREA, AREA, null);
}
}
}
this.oque();
}
public void setShot(int x, int y) {
explosionMatrix[x][y] = 1;
}
public int getShot(int x, int y) {
return explosionMatrix[x][y];
}
public int getRows() {
return rows;
}
public void setRows(int rows) {
this.rows = rows;
}
public int getCols() {
return cols;
}
public void setCols(int cols) {
this.cols = cols;
}
public int[][] getExplosionMatrix() {
return explosionMatrix;
}
public void setExplosionMatrix(int[][] explosionMatrix) {
this.explosionMatrix = explosionMatrix;
}
public void oque() {
System.out.println("");
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
System.out.print(explosionMatrix[i][j]);
}
System.out.println("");
}
}
}

Drawing a game board in java

I am referencing this link, however this won't ultimately fix my problem (i.e I run my program from someone else's computer). How to deal with "java.lang.OutOfMemoryError: Java heap space" error (64MB heap size). Right now, I have a game board that has 10x10 squares, but I need to increase this to 100x100, but when I do, I get this error. What is the best way to increase my game board size while avoiding this error? Current output is below, Code should compile and run. Thanks!
GameBoard Class:
import java.awt.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
import javax.swing.border.*;
public class GameBoard {
private final JPanel board = new JPanel(new BorderLayout(3, 3));
private JButton[][] c1squares = new JButton[10][10];
private JPanel c1Board, c2Board;
private final JLabel messagec1 = new JLabel("Player 1 Board");
JToolBar tool = new JToolBar();
Insets Margin = new Insets(0,0,0,0);
int squares = 10;
int space = 100;
ImageIcon icon = new ImageIcon(new BufferedImage(space, space, BufferedImage.TYPE_INT_ARGB));
GameBoard() {
initializeGui();
}
public final void initializeGui() {
board.setBorder(new EmptyBorder(5, 5, 5, 5));
tool.setFloatable(false);
board.add(tool, BorderLayout.PAGE_START);
tool.add(messagec1);
c1Board = new JPanel(new GridLayout(0, 10));
c1Board.setBorder(new LineBorder(Color.BLACK));
board.add(c1Board);
for (int i = 1; i < c1squares.length; i++) {
for (int j = 0; j < c1squares[i].length; j++) {
JButton b = new JButton();
b.setMargin(Margin);
b.setIcon(icon);
if ((j % 2 == 1 && i % 2 == 1) || (j % 2 == 0 && i % 2 == 0)) {
b.setBackground(Color.WHITE);
} else {
b.setBackground(Color.BLACK);
}
c1squares[j][i] = b;
}
}
for (int i = 1; i < squares; i++) {
for (int j = 0; j < squares; j++) {
c1Board.add(c1squares[j][i]);
}
}
public final JComponent getGui() {
return board;
}
public final JComponent getGui2() {
return board2;
}
}
BattleShipFinal Class:
import java.awt.Dimension;
import java.awt.Toolkit;
import javax.swing.JFrame;
public class BattleshipFinal {
public static void main(String[] args) {
GameBoard gb = new GameBoard();
JFrame frame = new JFrame("Battleship - Server");
frame.add(gb.getGui());
frame.setLocationByPlatform(true);
frame.setMinimumSize(frame.getSize());
frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);
frame.setPreferredSize(new Dimension(900,900));
frame.setMinimumSize(new Dimension(900,900));
frame.setLocation(50,50);
frame.pack();
frame.setVisible(true);
}
}
In case you are curious, and to illustrate what people said in the comments, you could have a custom JPanel painting the squares.
If you ever need to respond to mouse events, add a MouseListener to your panel, which will take care of the selected square (haven't added that part, but the selected field inside the Square class is a hint).
I removed stuff from your code, just to demonstrate this painting part.
GameBoard :
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
public class GameBoard {
private JPanel board;
private final Square[][] c1squares = new Square[10][10];
GameBoard() {
initializeGui();
}
public final void initializeGui() {
for (int i = 0; i < c1squares.length; i++) {
for (int j = 0; j < c1squares[i].length; j++) {
Square square = new Square();
if ((j % 2 == 1 && i % 2 == 1) || (j % 2 == 0 && i % 2 == 0)) {
square.setBackground(Color.WHITE);
} else {
square.setBackground(Color.BLACK);
}
c1squares[i][j] = square;
}
}
board = new BoardPanel(c1squares);
board.setBorder(new EmptyBorder(5, 5, 5, 5));
}
public final JComponent getGui() {
return board;
}
private class BoardPanel extends JPanel {
Square[][] squares;
public BoardPanel(final Square[][] squares) {
this.squares = squares;
}
#Override
public void paintComponent(final Graphics g) {
super.paintComponent(g);
int width = getWidth();
int height = getHeight();
for (int i = 0; i < squares.length; i++) {
for (int j = 0; j < squares[i].length; j++) {
Square currentSquare = squares[i][j];
System.out.println("Managing square " + i + " " + j);
g.setColor(currentSquare.getBackground());
g.fillRect(i * width / squares.length, j * height / squares.length, width / squares.length,
height / squares.length);
}
}
}
}
private class Square {
boolean isSelected;
Color background;
public boolean isSelected() {
return isSelected;
}
public void setSelected(final boolean isSelected) {
this.isSelected = isSelected;
}
public Color getBackground() {
return background;
}
public void setBackground(final Color background) {
this.background = background;
}
}
}
BattleshipFinal :
import java.awt.Dimension;
import javax.swing.JComponent;
import javax.swing.JFrame;
public class BattleshipFinal {
public static void main(final String[] args) {
GameBoard gb = new GameBoard();
JFrame frame = new JFrame("Battleship - Server");
JComponent board = gb.getGui();
frame.add(board);
frame.setLocationByPlatform(true);
//frame.setMinimumSize(frame.getSize());
frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);
//frame.setPreferredSize(new Dimension(100, 100));
board.setMinimumSize(new Dimension(100, 100));
board.setPreferredSize(new Dimension(100, 100));
frame.setMinimumSize(new Dimension(100, 100));
frame.setLocation(50, 50);
frame.pack();
frame.setVisible(true);
}
}
Okay, I figured out the solution for this. Here is the output:
The way I fixed this was by changing these lines of code:
private JButton[][] c1squares = new JButton[100][100];
int squares = 100;
int space = 1000;
c1Board = new JPanel(new GridLayout(0, 100));

Game of Life - Java, doesn't work (not showing cells)

Currently I'm working on an assignment about creating a version of "Game of Life". However my cells won't appear.
This is my Cell Class:
class Cell{
boolean alive; //true if cell is alive, false if cell is dead
int numNeighbors; //number of alive neightboring cells
//change alive/dead state of the cell
void setAlive(boolean state){
alive = state;
}
//return alive/dead state of the cell
boolean isAlive(){
return alive;
}
//set numNeightbors of the cell to n
void setNumNeighbors(int n){
numNeighbors = n;
}
//take the cell to the next generation
void update(){
if(numNeighbors <2 || numNeighbors >3){
alive = false;
} else if((numNeighbors == 2 || numNeighbors == 3) && alive == true){
alive = true;
} else if(numNeighbors == 3 && alive == false){
alive = true;
}
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor( Color.blue );
g.setOpaque(true);
for(int i = 0; i < row; i++){
for(int j = 0; j < col; j++){
if(grid[i][j].isAlive()){
g.setColor( Color.BLACK);
} else {
g.setColor ( Color.WHITE);
g.fillRect(50, 50, 50*i, 50*j);
}
}
}
}
And this is my GameOfLife Class
<pre>import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import java.io.*;
public class GameOfLife implements MouseListener{
Cell[][] grid; //contain grid of cells
String birthFilename = "birth.txt"; //text file where initial generation is stored
int row; //number of rows
int col; //number of columns
ActionListener actionListener = new ActionListener(){
javax.swing.Timer timer = new javax.swing.Timer(500, this); //new timer
#Override
public void actionPerformed(ActionEvent event){
}
};
public void buildIt() {
int width = 600;
int height = 600;
JFrame frame = new JFrame("Game of Life");
readInitial();
//adds button interface
JPanel buttonbar = new JPanel();
frame.add(buttonbar, BorderLayout.SOUTH);
JButton start = new JButton("Start");
JButton stop = new JButton("Stop");
JButton nextg = new JButton("Next Generation");
buttonbar.add(nextg);
buttonbar.add(start);
buttonbar.add(stop);
JPanel panel = new JPanel();
frame.add(panel);
panel.setPreferredSize(new Dimension(width, height));
panel.setLayout(new GridLayout(row, col, 4, 4));
frame.pack();
frame.setBackground(Color.WHITE);
frame.setVisible(true);
}
public void mousePressed( MouseEvent e) {
//add code to update x and y
}
public void mouseReleased( MouseEvent e) { }
public void mouseClicked( MouseEvent e) { }
public void mouseEntered( MouseEvent e) { }
public void mouseExited( MouseEvent e) { }
//calculate number of living neightbors of each cell and sets numNeighbors
//Does not update dead/live state of cells
void calculateNumNeighbors(){
int numNeighbors = 0;
for(int i = 1; i < row + 1; i++){
for(int j = 1; j < col + 1; j++){
for(int k = -1; k < 2; k++){
for(int m = -1; m < 2; m++){
if(grid[i+k][j+m].isAlive() && !(k == 0 && m == 0)){
numNeighbors++;
}
}
}
grid[i][j].setNumNeighbors(numNeighbors);
}
}
}
//create grid and read initial generation from file
void readInitial(){
try{
grid = new Cell[row + 2][col + 2]; //empty neighbors at corners, so + 2
File file = new File(birthFilename);
Scanner scanner = new Scanner( file );
row = scanner.nextInt();
col = scanner.nextInt();
for(int i = 0; i < row + 2; i++){
for (int j = 0; j < col + 2; j++){
grid[i][j] = new Cell();
}
}
for(int i = 1; i < row + 1; i++){
for (int j = 1; j < col + 1; j++){
if(scanner.next().equals(".")){
grid[i][j].setAlive(false);
} else if(scanner.next().equals("*")){
grid[i][j].setAlive(true);
}
}
}
for(int i = 0; i < row + 2; i++){
grid[0][i].setAlive(false);
grid[row+2][i].setAlive(false);
}
for(int j = 0; j < col + 2; j++){
grid[j][0].setAlive(false);
grid[j][col+2].setAlive(false);
}
} catch(FileNotFoundException e) {
grid = new Cell[12][12];
row = 10;
col = 10;
for(int i = 0; i < 12; i++){
for (int j = 0; j < 12; j++){
grid[i][j] = new Cell();
grid[i][j].setAlive(false);
}
}
}
}
//update grid to the next generation, using the values of numNeightbors in the cells
void nextGeneration(){
for(int i = 1; i < row + 1; i++){
for (int j = 1; j < col + 1; j++){
grid[i][j].update();
}
}
}
public static void main(String[] arg) {
(new GameOfLife()).buildIt();
}
I hope anyone can help me out to make this program work.
I don't see why anything should draw. You've got a Cell class that yes has a paintComponent method, but this method is meaningless since it's not part of a Swing component. Your JPanel, where you should do drawing -- does nothing. You've other problems with the Cell class too in that it appears to be trying to draw the whole grid and not just a single cell.
Get rid of Cell's paintComponent method
Instead give it a public void draw(Graphics g) method that allows it to draw itself.
Create a JPanel that holds a grid of cells
Have this JPanel do the drawing in its paintComponent override. It will call the draw(g) method of all the Cells that it holds within a for loop.
Always place an #Override annotation above any overridden method. If you had done this, above your paintComponent, the compiler would have warned you that something was wrong.
For example: here's a small program that does not do the Game of Life, but shows an example of a JPanel holding and displaying a grid of non-component cells. By "non-component" the SimpleCell class does not extend from a Swing component, does not have any Swing methods, but as suggested above, does have a draw(...) method and can use this to draw itself. It also has a public boolean contains(Point p) method that the main program can use in its MouseListener to decide if it's been clicked:
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.*;
#SuppressWarnings("serial")
public class SimpleCellGrid extends JPanel {
private static final int ROWS = 40;
private static final int COLS = 40;
private static final int CELL_WIDTH = 10;
private static final int PREF_W = CELL_WIDTH * COLS;
private static final int PREF_H = CELL_WIDTH * ROWS;
private SimpleCell[][] cellGrid = new SimpleCell[ROWS][COLS];
public SimpleCellGrid() {
MyMouse myMouse = new MyMouse();
addMouseListener(myMouse);
for (int row = 0; row < cellGrid.length; row++) {
for (int col = 0; col < cellGrid[row].length; col++) {
int x = col * CELL_WIDTH;
int y = row * CELL_WIDTH;
cellGrid[row][col] = new SimpleCell(x, y, CELL_WIDTH);
}
}
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
for (SimpleCell[] cellRow : cellGrid) {
for (SimpleCell simpleCell : cellRow) {
simpleCell.draw(g2);
}
}
}
#Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
private class MyMouse extends MouseAdapter {
#Override
public void mousePressed(MouseEvent e) {
for (SimpleCell[] cellRow : cellGrid) {
for (SimpleCell simpleCell : cellRow) {
if (simpleCell.contains(e.getPoint())) {
simpleCell.setAlive(!simpleCell.isAlive());
}
}
}
repaint();
}
}
private static void createAndShowGui() {
JFrame frame = new JFrame("SimpleCellGrid");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new SimpleCellGrid());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
public class SimpleCell {
private static final Color CELL_COLOR = Color.RED;
private boolean alive = false;
private int x;
private int y;
private int width;
private Rectangle rectangle;
public SimpleCell(int x, int y, int width) {
this.x = x;
this.y = y;
this.width = width;
rectangle = new Rectangle(x, y, width, width);
}
public boolean isAlive() {
return alive;
}
public void setAlive(boolean alive) {
this.alive = alive;
}
public void draw(Graphics2D g2) {
if (alive) {
g2.setColor(CELL_COLOR);
g2.fill(rectangle);
}
}
public boolean contains(Point p) {
return rectangle.contains(p);
}
#Override
public String toString() {
return "SimpleCell [alive=" + alive + ", x=" + x + ", y=" + y + ", width=" + width + ", rectangle=" + rectangle
+ "]";
}
}

How can I show a 2D matrix when push a button?

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);
}
}

Zero values in the array in the method paint

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)));
}
}
}

Categories