Calling a paint or render method from another class - Java - java

I did allot of research for this problem but couldn't find anything that would help me out.
When I run this app, the only thing I will see is an empty JFrame, the expected output is a JFrame with a black rectangle. This is my code, there are two classes.
public class Test {
public static void main(String[] args) {
Test test = new Test("Frame");
test.setFrame();
Window win = new Window(ObjectId.Window, 10, 10, 10, 10);
win.repaint();
}
private String title;
public Test(String title) {
this.title = title;
}
private void setFrame() {
JFrame frame = new JFrame(title);
frame.setSize(800, 600);
frame.setResizable(false);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
And my second class:
public class Window extends Component {
private ObjectId id;
private int x, y;
private int width, height;
public Window(ObjectId id, int x, int y, int width, int height) {
this.id = id;
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
public void paintComponent(Graphics g) {
g.setColor(Color.black);
g.fillRect(x, y, width, height);
}
Thanks

You didn't add win to the frame ('s contentPane). And you should extend JPanel in the Window-class, not Component.
So if you move Window win = new Window(ObjectId.Window, 10, 10, 10, 10) into the setFrame() method (you don't need the win.repaint()) and call frame.getContentPane().add(win) (or something similar) it will work.

Related

The paint function is not called in Java Swing

My purpose - to create a board with lines, using Java Swing.
After I made a board and added color to it, I tried to produce lines. To do this, I inherit from JPanel and added paintComponent method. But when I run the application, the method is not called.
I added default constructor with super();
I also added to the called constructor super();
I still cannot make the paint method or the paintComponent method to get run;
I tried all of the following posts:
Java Swing paint() not working
Insert Button in JPanel
public class Main {
public static void main(String[] args) {
Board board = new Board(295, 295, "Go board");
}
}
import java.awt.*;
import javax.swing.*;
public class Board extends JPanel{
private int width;
private int height;
private String title;
private JFrame JFrame;
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public JFrame getJFrame() {
return JFrame;
}
public void setJFrame(JFrame JFrame) {
this.JFrame = JFrame;
}
public Board(int width, int height, String title){
super();
this.width = width;
this.height = height;
this.title = title;
this.initBoard();
}
public Board(){
super();
}
public void initBoard(){
JFrame f = new JFrame(this.getTitle());
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().setBackground(Color.getHSBColor(25, 75, 47));
f.setSize(this.getWidth(), this.getHeight());
f.setLocation(550, 25);
f.setVisible(true);
this.setJFrame(f);
}
public void paint(Graphics g) {
g.drawLine(10, 10, 250, 10);
System.out.println("Test paint");
}
public void paintComponent(Graphics g) {
g.drawLine(10, 10, 250, 10);
System.out.println("Test paintComponent");
}
}
You never have called your initBoard which contains JFrame (which is bad design). Also you must add your panel to that frame with jframe.add(this);
It would be better to have your frame alone, and add your component to it like this
public static void main(){
JFrame f=new JFrame();
///set all the dimensions and other stuff of the frame
f.setLayout(new BorderLayout);
f.add(new Board(295, 295, "Go board"),BorderLayour.CENTER);
f.setVisible();
}

JFrame drawing two to three items when only one is included in my Squares arraylist

Title. I have created a Square class that defines what a square is, and lets me create a square with certain parameters. Whenever I add one square to the squares arraylist, it ends up drawing two to three. Why does it do this? I've even made it print the number of arraylist items (squares.size()) into the console, and it says only one. Also, the background turns grey whenever I draw a square. How can I fix that?
Edit: It also seems to randomly draw the squares again - or at least print the messages in the console whenever I move the window around, however it doesn't always happen.
My square class (getters + setters not included):
public class Square {
public static ArrayList<Square> squares = new ArrayList<Square>();
public int x, y, width, height;
public Color color;
public Square(int x, int y, int width, int height, Color color) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.color = color;
}
}
My main class:
public class Main {
public static String name = "Project";
#SuppressWarnings("unused")
public static void main(String args[]) {
MessageUtils.sendConsole(name + " started.");
Square.squares.add(new Square(50, 50, 150, 150, Color.black));
Frame frame = new Frame();
}
}
And my frame class:
public class Frame extends JFrame {
public Frame() {
super(Main.name);
getContentPane().setBackground(Color.BLACK);
setResizable(false);
setSize(new Dimension(600, 600));
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
MessageUtils.sendConsole("Frame setup.");
}
#Override
public void paint(Graphics g) {
int count = 1;
for (Square s : Square.squares) {
g.drawRect(s.getX(), s.getY(), s.getWidth(), s.getHeight());
g.setColor(s.getColor());
g.fillRect(s.getX(), s.getY(), s.getWidth(), s.getHeight());
MessageUtils.sendConsole("Square #" + count + " drawn.");
count++;
}
}
}

(Javax swing) repaint() sometimes not calling paintComponent()

I tried to find a question that answers my problem but could not find any since the questions asked are about that repaint() is never called
My problem is that when i start the application it either works without problems, or that only paintComponent() is not called (there are no errors)
My code:
GamePanel.java:
public class GamePanel extends JPanel implements KeyListener, ActionListener {
private static final long serialVersionUID = 1819637299730865623L;
private Timer time;
private long oldTime;
private int Width;
private int Height;
public GamePanel(int Width, int Height) {
this.Width = Width;
this.Height = Height;
addKeyListener(this);
setFocusable(true);
setFocusTraversalKeysEnabled(true);
oldTime = System.nanoTime();
setup();
System.console().printf("Begin!");
time = new Timer(0,this);
time.start();
}
#Override
public void actionPerformed(ActionEvent e) {
update(((float)(System.nanoTime() - oldTime)) / (float)1000000000);
System.console().printf("Running!");
oldTime = System.nanoTime();
repaint();
time.start();
}
float x = 0;
float del;
#Override
public void paintComponent(Graphics g) {
System.console().printf("Drawing!");
g.setColor(new Color(0,0,0));
g.fillRect(0, 0, Width, Height);
g.setColor(new Color(0,0,255));
g.fillOval((int)x-40,60,80,80);
g.setColor(new Color(255,255,255));
g.drawString(Float.toString(1 / del), Width / 2, Height / 2);
g.dispose();
}
public void update(float delta) {
x += delta * 50;
del = delta;
}
public void setup() {
}
Renderer.java (this is created in the main function)
public class Renderer {
int Height, Width;
JFrame obj;
GamePanel pan;
public Renderer(int Width, int Height, int StartposX, int StartposY, String title) {
obj = new JFrame();
this.Height = Height;
this.Width = Width;
obj.setBounds(StartposX,StartposY,Width,Height);
obj.setTitle(title);
obj.setResizable(false);
obj.setVisible(true);
obj.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pan = new GamePanel(Width,Height);
obj.add(pan);
}
}
To fix the problem all that one has to do is:
remove
g.dispose();
add
super.paintComponent(g);
at paintComponent()
and add
obj.setVisible(true);
after obj.add(pan);
I run your whole code adding a main() method in the Renderer.java to be able to test it.
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new Renderer(300, 300, 10, 10, "Testing Renderer");
}
});
}
You code program runs fine if I removed all the System.console().printf codes.

Issue in Painting JComponents added to JComponent

I have an Issue painting jcomponent
//class where the rectangle should drawed
public class Board extends JComponent
{
private Case[][] cases= new Case[10][10];
public Plateau() {
super();
this.setLayout(new GridLayout(10,10));
this.setSize(getPreferredSize());
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
if ((i + j) % 2 == 0) {
cases[i][j] = new WhiteCase(j * Case.LONGUEUR, i * Case.LONGUEUR, Case.LONGUEUR, Case.LONGUEUR);
} else {
cases[i][j] = new BlackCase(j * Case.LONGUEUR, i * Case.LONGUEUR, Case.LONGUEUR, Case.LONGUEUR);
}
add(cases[i][j]);
}
}
repaint();
}
public Dimension getPreferredSize() {
return new Dimension(600, 600);
}
}
//class Base for rectangle
public abstract class Case extends JComponent {
protected static final int LONGUEUR=60;
protected int x,y,width,height;
protected abstract void paintComponent(Graphics g);
public Dimension getPreferredSize() { return new Dimension(LONGUEUR, LONGUEUR);
}
}
///black Case
public class BlackCase extends Case
{
private Piece piece;
private static final long serialVersionUID = 1L;
public CaseNoire(int x, int y,int width,int height)
{
this.x=x;
this.y=y;
this.width = width;
this.height= height;
}
public Dimension getPreferredSize() {
return new Dimension(LONGUEUR, LONGUEUR);
}
#Override
protected void paintComponent(Graphics g)
{
g.setColor(Color.darkGray);
g.fillRect(x, y,width,height);
}
}
public class CaseWhite extends Case {
/**
*
*/
private static final long serialVersionUID = 1L;
public CaseBlanche(int x, int y,int width,int height)
{
this.x=x;
this.y=y;
this.width = width;
this.height= height;
}
#Override
public void paintComponent(Graphics g)
{
g.setColor(Color.white);
g.fillRect(x, y,width,height);
g.setColor(Color.BLACK);
g.drawString("X= "+x , 10, 10);
}
public Dimension getPreferredSize() {
return new Dimension(LONGUEUR, LONGUEUR);
}
}
//Main class
public class CheckersGame extends JFrame {
private static final long serialVersionUID = 1L;
public static void main(String[] args )
{
CheckersGame checkers= new CheckersGame();
}
public CheckersGame()
{
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setTitle("Jeu de Dames");
JPanel panelPrincipalDame = new JPanel(new GridBagLayout());
Board board = new Board();
GridBagConstraints c = new GridBagConstraints();
c.fill= GridBagConstraints.NONE;
c.gridx =0;
c.gridy = 0 ;
c.gridheight= 2;
c.gridwidth= 2;
panelPrincipalDame.add(plateau,c);
setSize(800, 700);
setContentPane(panelPrincipalDame);
![//setVisible(true);][1]
setResizable(false);
}
}
The result of this code is ( Note X+ 0 etc.. is just for debug purpose )
But what I want is this
Please why I get only one rectangle?
So much for listening to my suggestion to NOT create "CaseNoire" and "CaseBlanch" classes I gave in your last question: paintComponent does not paint correctly from two weeks ago. These classes are not needed. What happens if you ever want to give the user the flexibility to choose the colors of the squares. Your game logic should never be based on the class name or anything like that. So get rid of the classes and use the built in Swing features to color the background of the component.
I think the problem is because you created variables "x, y, width, height" in the Case class. I believe these variables already defined in the Component class, to represent the size/location of the component.
Get rid of the variables, you don't need to manage the size/location of each component because the GridLayout will do this for you.
Again, look at the example code I gave you that shows how to create a "ChessBoard".
I resolved it I just set the X=0 and Y= 0 in the paintComponent()
protected void paintComponent(Graphics g)
{
g.setColor(Color.darkGray);
g.fillRect(0, 0,width,height);
}

Drawing from one panel class to another panel class.

I have two classes. The first class is called Fishy1, and the second class is called Fishy2. This is the code for my first class:
import java.awt.Graphics;
import javax.swing.JPanel;
public class Fishy1 extends JPanel {
Fishy1 fishy1 = new Fishy1();
/* Graphics goes here */
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawOval(50, 50, 50, 50);
}
}
As you can see, the code basically draws an oval in fishy1. And here is the code for my second class:
import java.awt.Graphics;
import javax.swing.JPanel;
public class Fishy2 extends JPanel {
Fishy2 fishy2 = new Fishy2();
}
As you can see, in the second class, there is no paintComponet method to draw to fishy2. So, my question is, is there a way to draw to the second class using the paintComponent method in the first class? If there's no way to do it, please let me know. Thank you.
To achieve graphics replication between 2 swing classes at same time
public class Fishs extends JPanel {
//Static list, all fishes panel will display the same objects at same positions
private static List<OvalObj> lstOvalObjects;
public Fishs() {
//if the list is null just initialize it.
lstOvalObjects = lstOvalObjects == null? new ArrayList():lstOvalObjects;
}
/* Graphics goes here */
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
lstOvalObjects.forEach(ovalObject -> g.drawOval(ovalObject.getX(), ovalObject.getY(), ovalObject.getWidth(), ovalObject.getHeight()));
}
public static List<OvalObj> getLstOvalObjects() {
return lstOvalObjects;
}
public static void setLstOvalObjects(List<OvalObj> lstOvalObjects) {
Fishs.lstOvalObjects = lstOvalObjects;
}
}
The oval object:
public class OvalObj{
private int x,y,width,height;
public OvalObj(int x, int y, int width, int height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
}
Implementation:
//First Frame
JFrame frame1 = new JFrame();
frame1.setLayout(new BorderLayout());
//First Fish Panel that will go to frame1
Fishs fish1 = new Fishs();
fish1.setVisible(true);
frame1.add(fish1, BorderLayout.CENTER);
frame1.pack();
frame1.setVisible(true);
//Second Frame
JFrame frame2 = new JFrame();
//Second Fish Panel that will go to frame2
Fishs fish2 = new Fishs();
fish2.setVisible(true);
frame2.setLayout(new BorderLayout());
frame2.add(fish2, BorderLayout.CENTER);
frame2.pack();
frame2.setVisible(true);
/// you can add many objects to draw as you like in a static way anywhere in your code, they will render in every fish panel at same time
Fishs.getLstOvalObjects().add(new OvalObj(0, 0, 50, 50));
Fishs.getLstOvalObjects().add(new OvalObj(20, 20, 50, 50));

Categories

Resources