Removed components still having an effect on later draw functions - java

I'm trying to get 2 classes to interact with the same Graphics object but removing a Button component on the 1st class creates an empty space where it used to be after drawRect() is called in the 2nd class.
I have tried a combination of validate(), revalidate() and repaint() in both classes.
1st class:
import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
import testpackage.testing_draw_class;
public class testing_class_draw_main extends Applet implements ActionListener {
Button b;
testing_draw_class test;
Graphics g;
public void init() {
b = new Button("test now!");
add(b);
b.addActionListener(this);
test = new testing_draw_class();
g = getGraphics();
}
public void actionPerformed(ActionEvent e){
remove(b); // removes button
revalidate();
test.paint(g);
}
}
2nd class:
package testpackage;
import java.applet.Applet;
import java.awt.*;
public class testing_draw_class extends Applet {
public void paint(Graphics g){
g.setColor(Color.BLACK);
g.fillRect(0,0,300,300);
}
}
I was expecting a complete black square however there is a gap where the removed button used to be.
Screenshot of problem

Related

How come my code doesn't draw anything when i click my JButton? [duplicate]

This question already has answers here:
Drawing a rectangle that won't disappear in next paint
(2 answers)
Jbutton acction listener
(1 answer)
Closed 4 years ago.
import java.awt.*;
import java.util.*;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class runner
{
public static void main(String args[])
{
JFrame test = new JFrame("Tester");
test.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//end on closing window
test.setVisible(true); //can see
test.setResizable(false); //can't resize
test.getContentPane().add(new JFrameGraphics());//where graphics happen
test.setPreferredSize(new Dimension(500,500));//makes pack useful
test.pack();//sets sizes
}
}
class JFrameGraphics extends JPanel
{
public boolean button = false; //SUPPOSED to make sure button was pressed
public void paint(Graphics g)
{
JButton b1 = new JButton ("Button 1");
add(b1);
b1.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
button = true;
buttonPressed(g); //supposed to draw giant red oval
//System.out.println("Worked"); this worked
}
});
}
public void buttonPressed(Graphics g)
{
if(button = true)
{
g.setColor(Color.RED);
g.fillOval(105,105,200,50);
//System.out.println("This also worked"); This also worked
}
}
}
I've gone through with printlns in the console and can see that the buttton works both when the action listener calls the button pressed method and inside the button pressed method. For some reason i can't get any graphics to show up whenever i have a button
First of all, for a Swing component, you should be overriding the paintComponent method, not the paint method.
What you have in your current paint method belongs in your initial set-up, otherwise you're adding the listener over and over again every time the component paints.
The code you have in your buttonPressed method is what belongs in your paintComponent method.

Java Awt components are displayed but Swing components are not displayed in Applet

I am trying to run a very simple Java applet program.
When I used AWT.Label component, I can see the component through appletviewer. The code I am using is:
import java.applet.Applet;
import java.awt.Graphics;
import javax.swing.*;
import java.awt.*;
public class AppletTest extends Applet
{
Label user = new Label("Username", Label.LEFT);
public void paint(Graphics g)
{
g.drawString("Registration Form", 195, 10);
}
public void init()
{
add(user);
}
}
When I use swing.JLabel component, I cannot see any component on the screen except for Registration form printed on top:
import java.applet.Applet;
import java.awt.Graphics;
import javax.swing.*;
import java.awt.*;
public class AppletTest extends JApplet
{
JLabel user = new JLabel("Username", JLabel.LEFT);
public void paint(Graphics g)
{
g.drawString("Registration Form", 195, 10);
}
public void init()
{
add(user);
}
}
What is the issue?
Because paint is a method in JApplet, when you override it, you need to call super.paint(g) so that the parent component can still do it's painting. Your paint method should look something more like this:
#Override
public void paint(Graphics g) {
super.paint(g);
g.drawString("Registration Form", 195, 10);
}

Using JFrame in java

Here is my code, I am wondering why it prints "test" two times!? every command I add in "paintcomponent" performs 2 times. I would appreciate if you could help me please!?
import java.awt.geom.*;// For Ellipse2D, etc.
import java.util.*;
import javax.swing.*; // For JPanel, etc.
import java.io.*;
import java.awt.*; // For Graphics, etc.
import java.lang.Object;
import java.util.Random;
public class hextopology extends JPanel {
public void paintComponent(Graphics g) {
super.paintComponent(g);
System.out.println("test");
}
public static void main(String[] args) throws Exception{
JFrame f = new JFrame();
f.add(new hextopology());
f.setSize(550,550);
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
When you are doing resizing the window you are actually changing the window's properties, so your view elements should be painted again. That's why paintComponent() is getting called every time and as you have a print statement inside the method, it is printing as expected.
You are calling
f.setSize(550,550);
which is a resize, after the panel is created for the first time.
paintComponent
is called twice, because of this.

Leaving a trace while painting on a transparent JPanel

I am relatively new graphics programmer in Java and here is a simple program I was trying. Here is the full code: broken into 3 classes.
Class 1:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class MyPanelB extends JPanel
{
int x=0;
int y=0;
public void paintComponent(Graphics g)
{
x=x+1;
y=y+1;
setOpaque(false);
//setBackground(Color.cyan);
g.setColor(Color.red);
g.fillRect(x,y,x+1,y+1);
}
}
Class 2:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class MyFrameB implements ActionListener
{
MyPanelB p1;
public void go()
{
JFrame f1= new JFrame();
f1.setLocation(150,50);
f1.setSize(800,700);
f1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel p0= new JPanel();
p0.setBackground(Color.yellow);
p0.setLayout(new BorderLayout());
f1.add(p0);
p1= new MyPanelB();
p0.add(p1);
f1.setVisible(true);
Timer t = new Timer(200,this);
t.start();
}
public void actionPerformed(ActionEvent ev)
{
p1.repaint();
}
}
Class 3(Main Class):
public class MyBMain
{
public static void main(String[] args)
{
MyFrameB m1= new MyFrameB();
m1.go();
}
}
If I comment out the staement
setOpaque(false);
in class 1, I get a trace(of red expanding rectangles) but not a yellow background.
Otherwise I do not get a trace, but I do get a yellow background.
I want both the yellow background and the trace.
Please feel free to modify my code so that I get both a trace and a yellow background.
I provided the full code so one can easily check out the output.
Basically you need to repaint the entire component every time the paintComponent() method is called. This means you need to start from 0 and iterate up to the current value of x.
So your paintComponent() method should look something like:
public void paintComponent(Graphics g)
{
super.paintComponent(g);
x=x+1;
y=y+1;
for (int i = 0; i < x; i++)
{
g.setColor(getForeground());
//g.fillRect(x,y,x+1,y+1);
g.fillRect(i,i,i+1,i+1);
}
}
This means you don't need your panel0. I also change the code for creating panel1:
p1= new MyPanelB();
p1.setForeground(Color.RED);
p1.setBackground(Color.YELLOW);
f1.add(p1);
Even this code I posted for you is not correct. The x/y values should NOT be updated in the paintComponent() method. Try resizing the frame while your code is executing to see why?
Your ActionListener should invoke a method in your panel1 class to update property of the class to tell the paintComponent() how many times to iterate and paint the square when it is invoked. The the paintComponent() method should reference this property in the loop that I created.

Paint from different classes

I'm trying to make a game in Java (school project) and I have the following setup:
A main class, extended with JFrame, a 'Game' class, extended with JPanel.
Now from within this main class, I make calls to a class 'Player' and a class 'Map'.. The class 'Map' exists of two subclasses 'Blocks' and 'Bombs'.
But I'm wondering.. How do I let the paint methods of all this classes paint to the same JPanel (of the class Game)?
I gave every class the method 'public void paint(Graphics g)' and do the painting.. But only the painting of the class 'Game' shows up when i run the program, not the painting from the subclasses.
How do I implement this?
By example, I reduced my code to this:
Main class:
BomberGame game = new BomberGame();
add(game);
setSize(400, 400);
setTitle("Bomber");
setDefaultCloseOperation(EXIT_ON_CLOSE);
this.show();
}
public static void main(String[] args) {
BomberB1 main = new BomberB1();
}
}
Game class:
package bomberb1;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.ArrayList;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
public class BomberGame extends JPanel {
public BomberGame() {;
BomberMap map = new BomberMap(this);
}
public void paint(Graphics g) {
g.drawRect(10, 10, 10, 10);
g.setColor(Color.red);
g.fillRect(10, 10, 10, 10);
}
}
Map class:
package bomberb1;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.*;
import javax.swing.SwingUtilities;
public class BomberMap{
BomberGame game;
public BomberMap(BomberGame game) {
this.game = game;
}
public void paint(Graphics g) {
g.drawRect(30, 30, 20, 20);
}
}
In the Entity class (which could be Map player etc) to be drawn have a draw method that accepts a Graphics object thus allowing it to access the Graphics object of the JPanel and draw to it, something like:
class GamePanel extends JPanel {
Entity e=new Entity;
#Override
protected paintComponent(Graphics g) {
super.paintComponent(g);
e.draw(g);//call draw method for entity and pass graphics object
}
}
class Entity {
//will draw whats necessary to Graphics object
public void draw(Graphics g) {
//draw to the graphics object here
}
}
Other suggestions:
Do not extend JFrame class unnecessarily
override JPanel paintComponent() and not paint() (+1 to trashGod comment)
Swing components should be created and manipulated on Event Dispatch Thread via SwingUtilities.invokeLater(..) block.
UPDATE:
As #GuillaumePolet stated a better game design would be implementing JPanels as parent class for most of the game entities see this similar answer for more.

Categories