I am making kind of my paint that creates shapes, it worked fine until I added layers(panel and frame), now the shapes aren't visible on button press I assume it is under the layers?i tried using paintComponent and revalidate etc and still couldn't get it to appear
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Main2 extends JPanel implements ActionListener {
private static Square mySquare;
private static Circle myCircle;
private static Color myColor;
public boolean SquareCheck;
public boolean CircleCheck;
JButton buttonSquare;
JButton buttonCircle;
JFrame frame;
JPanel panel;
public void paint(Graphics g) {
if (SquareCheck) {
g.setColor(myColor);
g.fillRect(mySquare.x, mySquare.y, mySquare.width, mySquare.length);
} else if (CircleCheck) {
g.setColor(myColor);
g.fillOval(myCircle.x, myCircle.y, myCircle.width, myCircle.length);
}
}
public void start() {
frame = new JFrame();
panel = new JPanel();
//setLayout(new BorderLayout());
buttonSquare = new JButton("■");
buttonCircle = new JButton("●");
buttonSquare.setPreferredSize(new Dimension(200, 20));
buttonCircle.setPreferredSize(new Dimension(200, 20));
buttonCircle.addActionListener(this);
buttonSquare.addActionListener(this);
//add(buttonCircle, BorderLayout.NORTH);
//add(buttonSquare, BorderLayout.SOUTH);
JToggleButton red = new JToggleButton();
panel.add(buttonCircle);
panel.add(buttonSquare);
frame.add(panel);
frame.setSize(500, 500);
frame.setVisible(true);
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == buttonSquare) {
SquareCheck = true;
} else if (e.getSource() == buttonCircle) {
CircleCheck = true;
}
repaint();
}
public static void main(String[] args) {
mySquare = new Square(30, 50, 50, 50);
myCircle = new Circle(60, 100, 50, 50);
myColor = Color.red;
Main2 x = new Main2();
x.start();
}
}
Basiclly the buttons changes the boolean then the repaint is called and based on the boolean it draws either a cirlce or a square,the code worked before adding frame and panel
Your paint method is a method of the Main2 class, but you never add a Main2 instance to the JFrame or to any component that goes into the JFrame, and so the Main2 instance will never be displayed, and the Swing painting manager will never call its paint method.
For starters, get rid of this variable, panel = new JPanel(); and every place you use panel, substitute this. This way you'll be working with a correct Main2 instance and adding it to the GUI.
Other issues:
You need to call the super's equivalent painting method in your override on its first line
Override paintComponent, not paint, and yes call super.paintComponenet(g); in this override
You will want to learn and use Java naming conventions. Variable names should all begin with a lower letter while class names with an upper case letter. Learning this and following this will allow us to better understand your code, and would allow you to better understand the code of others.
For safety's sake, add the #Override annotation above any method that you think may be overriding a parent method (such as paint), to make sure that you are doing it correctly.
For example:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
#SuppressWarnings("serial")
public class Main2 extends JPanel implements ActionListener {
private static Square mySquare;
private static Circle myCircle;
private static Color myColor;
private JToggleButton buttonSquare;
private JToggleButton buttonCircle;
JFrame frame;
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (buttonSquare.isSelected()) {
g.setColor(myColor);
g.fillRect(mySquare.x, mySquare.y, mySquare.width, mySquare.length);
}
if (buttonCircle.isSelected()) {
g.setColor(myColor);
g.fillOval(myCircle.x, myCircle.y, myCircle.width, myCircle.length);
}
}
public Main2() {
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
buttonSquare = new JToggleButton("■");
buttonCircle = new JToggleButton("●");
buttonCircle.addActionListener(this);
buttonSquare.addActionListener(this);
this.add(buttonCircle);
this.add(buttonSquare);
frame.add(this);
frame.setSize(500, 500);
frame.setVisible(true);
}
public void actionPerformed(ActionEvent e) {
repaint();
}
public static void main(String[] args) {
mySquare = new Square(30, 50, 50, 50);
myCircle = new Circle(60, 100, 50, 50);
myColor = Color.red;
new Main2();
}
}
class MyShape {
public int x, y, width, length;
public MyShape(int x, int y, int width, int length) {
this.x = x;
this.y = y;
this.width = width;
this.length = length;
}
}
Related
I'm just learning how GUI works and I wanted to write a code where following happens:
firstly we see red rectangle
after a click it changes into a circle in gradient (I picked orange and pink) + the background is black.
The problem is, I don't know how to notify the change when I use repaint(), I tried creating the first picture with another method - fail, maybe I lack some knowledge. Currently we get just the second output that doesn't change after the click.
This is the code at the moment I got stuck:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class SimpleGUI implements ActionListener {
JButton button;
JFrame frame;
public void work() {
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
button = new JButton("Color change");
button.addActionListener(this);
mojpanel panel = new mojpanel();
frame.getContentPane().add(BorderLayout.SOUTH, button);
frame.getContentPane().add(BorderLayout.CENTER, panel);
frame.setSize(300,300);
frame.setVisible(true);
}
public void actionPerformed(ActionEvent event) {
frame.repaint();
}
}
import java.awt.Color;
import java.awt.GradientPaint;
import java.awt.Graphics;
import javax.swing.*;
import java.awt.Graphics2D;
public class mojpanel extends JPanel {
public void paintComponent(Graphics g) {
g.setColor(Color.black);
g.fillRect(0, 0, this.getWidth(), this.getHeight());
GradientPaint gradient = new GradientPaint(70,70, Color.orange, 150,150, Color.pink);
((Graphics2D) g).setPaint(gradient);
g.fillOval(100, 100, 100, 100);
}
}
import javax.swing.JFrame;
public class Test {
public static void main(String[] args) {
SimpleGUI aplGUI = new SimpleGUI();
JFrame frame = new JFrame();
mojpanel panel = new mojpanel();
frame.add(panel);
aplGUI.work();
}
}
import java.awt.*;
public class Painting extends SimpleGUI {
public void paint(Graphics g) {
g.setColor(Color.red);
g.drawRect(100, 100, 100, 100);
g.fillRect(100, 100, 100, 100);
}
}
When you create new classes, you short invest more thought into them. You have two classes which are supposed to be interchangeable, one painting a red rectangle, the other painting a circle with a color gradient, with the ability to switch from the former to the latter.
So when you have one class extending JPanel and the other extending SimpleGUI, there is no way to exchange one for the other. Further, the names mojpanel and Painting do not reflect their purposes.
Besides that, you have it backward. Don’t implement an action that calls repaint(), followed by an attempt to recognize that repaint() has been called, to modify the GUI afterwards. Instead, change the GUI’s state and after the GUI has changed in a way that the visual appearance needs to be updated, call repaint. Note that most properties of the Swing components do already trigger an according repaint automatically when you change them.
You may create two classes extending JComponent having a custom paintComponent method and replace one with the other when the action has been triggered. But there’s a less intrusive way. Let the classes implement Icon and set the icon property of a component, e.g. a JLabel. This is one of the properties that will trigger the painting automatically:
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class SimpleGUI {
static class GradientOval implements Icon {
#Override
public void paintIcon(Component c, Graphics g, int x, int y) {
GradientPaint gradient
= new GradientPaint(70,70, Color.orange, 150,150, Color.pink);
((Graphics2D)g).setPaint(gradient);
g.fillOval(100, 100, 100, 100);
}
#Override
public int getIconWidth() {
return 200;
}
#Override
public int getIconHeight() {
return 200;
}
}
static class RedRectangle implements Icon {
#Override
public void paintIcon(Component c, Graphics g, int x, int y) {
g.setColor(Color.RED);
g.fillRect(100, 100, 100, 100);
}
#Override
public int getIconWidth() {
return 200;
}
#Override
public int getIconHeight() {
return 200;
}
}
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel content = new JLabel(new RedRectangle());
JButton button = new JButton("Change To Circle");
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
content.setIcon(new GradientOval());
}
});
frame.getContentPane().add(BorderLayout.SOUTH, button);
frame.getContentPane().add(BorderLayout.CENTER, content);
frame.setSize(300, 300);
frame.setVisible(true);
}
}
I don’t know which level of Java knowledge you have. The code
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
content.setIcon(new GradientOval());
}
});
creates an instance of an anonymous inner class implementing ActionListener. You can simplify this code using a lambda expression:
button.addActionListener(e -> content.setIcon(new GradientOval()));
To demonstrate the interaction between component properties and repaints, here an approach using a custom component:
import java.awt.*;
import javax.swing.*;
public class SimpleGUI {
static class DualAppearance extends JComponent {
private boolean first = true;
public boolean isFirst() {
return first;
}
public void setFirst(boolean shouldBeFirst) {
if(shouldBeFirst != first) {
first = shouldBeFirst;
repaint();
}
}
public void next() {
if(first) {
first = false;
repaint();
}
}
#Override
protected void paintComponent(Graphics g) {
if(first) {
g.setColor(Color.RED);
g.fillRect(100, 100, 100, 100);
}
else {
GradientPaint gradient
= new GradientPaint(70,70, Color.orange, 150,150, Color.pink);
((Graphics2D)g).setPaint(gradient);
g.fillOval(100, 100, 100, 100);
}
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
#Override
public Dimension getMinimumSize() {
return new Dimension(200, 200);
}
}
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
DualAppearance content = new DualAppearance();
JButton button = new JButton("Change To Second");
button.addActionListener(e -> content.next());
frame.getContentPane().add(BorderLayout.SOUTH, button);
frame.getContentPane().add(BorderLayout.CENTER, content);
frame.setSize(300, 300);
frame.setVisible(true);
}
}
This DualAppearance component follows the usual pattern. When being requested to paint itself, it will always paint itself according to the current state. This may happen multiple times without a state change, due to other reasons, e.g. being requested by the system. When its own state changes and requires a repaint, which only this component can know, it will invoke repaint.
You can easily modify this example code to toggle between both appearances by replacing
JButton button = new JButton("Change To Second");
button.addActionListener(e -> content.next());
with
JButton button = new JButton("Toggle");
button.addActionListener(e -> content.setFirst(!content.isFirst()));
I am currently making a game with a main menu and a world where you actually play.
I have a class called Game, which inherits from JPanel and implements the Runnable, MouseListener, KeyListener and ActionListener interfaces
(only important parts included)
I also have two classes InWorldHandler and OutWorldHandler for handling the mechanics in the world and outside of it respectively.
The Game class:
public class Game extends JPanel implements Runnable, KeyListener, MouseListener, ActionListener
{
protected JFrame frame;
private Timer timer = new Timer(25, this);
private World world;
private Player player = new Player();
private boolean draw;
Game(World world)
{
frame = new JFrame("Minecraft 2D");
this.world = world;
player.enterWorld(world, this);
}
#Override
protected void paintComponent(Graphics g)
{
Graphics2D g2d = (Graphics2D)g;
if(draw)
{
g2d.setColor(new Color(255, 255, 255));
g2d.fillRect(0, 0, frame.getWidth(), frame.getHeight());
draw = false;
//Here, the in-game mechanics should be handled
if(player.inWorld())
{
Chunk chunk = player.getLoadedChunk();
for(int x = 0; x < 16; x++)
{
for(int y = 0; y < 16; y++)
{
Block block = chunk.getBlockAt(x, y);
BufferedImage texture = block.getTexture();
g2d.drawImage(block.getTexture(), x*32, y*32, texture.getWidth()*2, texture.getHeight()*2, null);
}
}
}
//Here, the out-game mechanics should be handled
else
{
}
}
}
#Override
public void actionPerformed(ActionEvent e)
{
this.repaint();
draw = true;
}
#Override
public void run()
{
draw = true;
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.add(this);
frame.setMinimumSize(new Dimension(518, 540));
frame.setResizable(false);
frame.setLocationRelativeTo(null);
frame.addKeyListener(this);
frame.addMouseListener(this);
frame.setFocusable(true);
frame.setVisible(true);
frame.pack();
timer.start();
}
}
Both the other classes have empty bodies currently. I just have no idea how to do that.
I want the InWorldHandler class to draw on the panel when the player is in game, and the OutWorldHandler class when the player is in the main menu, both called in the Game class. How do I do that?
Instead of having a single JPanel, why don't you try with a CardLayout and switch whether to show the InnerWorld or the OuterWorld according to a flag that determines where in the program you're at.
As you're implementing KeyListener, I think that's for you to be able to move your character, please take a look at the accepted answer on this question: Keylistener not working for JPanel and use KeyBindings instead.
Also avoid the use of setMimimum/Maximum/PreferredSize() and override those methods instead: Should I avoid the use of set(Preferred|Maximum|Minimum)Size methods in Java Swing?
Take this code as an example:
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class Game {
private JFrame frame;
private JButton button;
private boolean status;
private JPanel[] cards;
private CardLayout cl;
private JPanel gamePane;
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new Game().createAndShowGUI());
}
private void createAndShowGUI() {
frame = new JFrame(getClass().getSimpleName());
button = new JButton("Switch Worlds");
status = true; //True = Inner / False = Outer
cl = new CardLayout();
gamePane = new JPanel(cl);
cards = new JPanel[2];
cards[0] = new InnerWorld();
cards[1] = new OuterWorld();
gamePane.add(cards[0], "innerWorld");
gamePane.add(cards[1], "outerWorld");
button.addActionListener(e -> {
status = !status;
if (status) {
cl.show(gamePane, "innerWorld");
} else {
cl.show(gamePane, "outerWorld");
}
});
frame.add(gamePane);
frame.add(button, BorderLayout.SOUTH);
frame.pack();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
#SuppressWarnings("serial")
class InnerWorld extends JPanel {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.drawString("Inner World", 50, 50);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
#SuppressWarnings("serial")
class OuterWorld extends JPanel {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.drawString("Outer World", 50, 50);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
I write a program to draw 50 rectangles after clicking OK button. But I don't uderstand why it disappears after resizing window, using scrollbar or clicking on OK again.
Here's my code (I have two classes: drawingPanel and Main)
drawingPanel.java:
import javax.swing.*;
import java.awt.*;
public class drawingPanel extends JPanel
{
public boolean drawIt = false;
public int x = 140,y = 0;
public void paintIt()
{
drawIt = true;
repaint();
}
public void paintComponent(Graphics g)
{
if (drawIt == true)
{
super.paintComponent(g);
for (int i = 1; i <= 50; i++)
{
g.fillRect(x, y, 50, 50);
y += 70;
}
}
}
}
Main.java:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Main extends JFrame
{
private drawingPanel draw = new drawingPanel();
private JPanel controlPanel = new JPanel();
private JButton ok = new JButton("OK");
private JScrollPane scroll = new JScrollPane(draw);
public Main()
{
setSize(500,500);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setTitle("Demo");
setLayout(new BorderLayout());
controlPanel.setLayout(new FlowLayout());
controlPanel.add(ok);
ok.addActionListener(new okListener());
draw.setPreferredSize(new Dimension(100,1000));
add(controlPanel, BorderLayout.NORTH);
add(scroll,BorderLayout.CENTER);
setVisible(true);
}
private class okListener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
draw.paintIt();
}
}
public static void main(String[] args)
{
new Main();
}
}
Please help me, thanks in advance.
Re-initialize x and y fields within your paint component method like so that they won't keep increasing out of view each time the JPanel is drawn:
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g); // move this here
if (drawIt) {
x = 140; // add these guys
y = 0;
for (int i = 1; i <= 50; i++) {
// .... etc....
and things should draw OK.
Other minor issues not related to your question:
The super's painting method should always be called, so pull that out of the if block.
Rename your drawingPanel class to be DrawingPanel so that it conforms to Java conventions.
Better to change if (drawIt == true) { to the more simple if (drawIt) {
Minor quibble: paintComponent should be protected, not public.
I am trying to make the effect of gravity but it just looks like there are growing streaks of circles instead of individual circles moving down. I do not know how to remove the circles I have already drawn. There are no errors in the code btw.
import javax.swing.Timer;
import javax.swing.*;
import java.awt.*;
import java.util.*;
import java.awt.event.*;
import java.awt.geom.Ellipse2D;
public class Tester {
static JFrame frame;
static JPanel panel;
static JButton button;
static ArrayList<Ellipse2D.Double> circles = new ArrayList<Ellipse2D.Double>();
static void init(){
frame = new JFrame();
panel = new JPanel(new BorderLayout());
button = new JButton("South");
panel.add(button, BorderLayout.SOUTH);
frame.add(panel);
frame.setVisible(true);
panel.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500, 500);
frame.setBackground(Color.LIGHT_GRAY);
}
public static void main(String[] args) {
init();
class MeteorMover extends JPanel{
Ellipse2D.Double m;
int x = 40,y=40;
boolean isSettingGravity=true;
public MeteorMover(){
m = new Ellipse2D.Double(x,y,30,30);
}
void createNewMeteor(int n){
repaint();
}
void setGravity(){
isSettingGravity = true;
for (int i=0;i<circles.size();i++){
Ellipse2D.Double m = circles.get(i);
m= new Ellipse2D.Double(m.getX(),m.getY()+1,30,30);
circles.set(i, m);
}
repaint();
}
protected void paintComponent(Graphics g){
Graphics2D g2 = (Graphics2D) g;
g2.setColor(Color.WHITE);
if (isSettingGravity){
for (Ellipse2D.Double c:circles){
g2.draw(c);
}
isSettingGravity = false;
}
else{
m = new Ellipse2D.Double(x,y,30,30);
circles.add(m);
g2.fill(m);
g2.draw(m);
Random r = new Random();
x = r.nextInt(500);
y=r.nextInt(100);
}
}
}
final MeteorMover m = new MeteorMover();
panel.add(m);
panel.repaint();
class TimerListener implements ActionListener{
#Override
public void actionPerformed(ActionEvent arg0) {
m.createNewMeteor(1);
}
}
TimerListener cListener = new TimerListener();
Timer timer = new Timer(1000,cListener);
timer.start();
class TimerListener2 implements ActionListener{
#Override
public void actionPerformed(ActionEvent arg0) {
m.setGravity();
}
}
TimerListener2 gListener = new TimerListener2();
Timer gTimer = new Timer(100,gListener);
gTimer.start();
}
}
call super.paintComponent(g);
protected void paintComponent(Graphics g) {
super.paintComponent(g);
read more about super.paintComponent .
There's no direct way to erase with graphics, you have two options:
If you always know which ellipse you need to erase, AND the ellipses never intersect, then you could keep in memory which is the next ellipse to erase and call g.setColor(bgColor); g.fill(erasedEllipse);
This is option is more reliable, You could keep an ArrayList of ellipses to draw. and you could clear all the pane and repaint all
the ellipses in the ArrayList, and if you want to erase one, you
just call ArrayList.remove(erasedElipseIndex)
Thanks for the help. The objects are all showing now.
But I ran into a new problem. Im trying to use a For loop to draw 10 copys of the same box with a little space in between so they don't just stack in the same position.
But for some reason they keep getting painted on top of eachother and in the center instead of starting at x = 20...
import java.awt.*;
import javax.swing.*;
public class CarWashPanel extends JPanel {
public int i;
public int x = 20;
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.black);
for (i=0; i < 10; i++){
g.fillRoundRect(x, 10, 50, 100, 55, 25);
x = x + 10;
}
}
#Override
public Dimension getPreferredSize() {
return new Dimension(500, 150);
}
}
//
I'm trying to add graphics in my CarWashPanel class to I want to add to my GUI. I've read some tutorials and other questions but I can't figure out what i'm doing wrong.
The buttons and label that i've added to the GUI show up just fine but when I add something to my CarWashPanel it doesn't show up in the GUI.
I feel like I need to tell my GUI to add all elements from the CarWashPanel but I'm not sure how.
public class Main {
public static void main(String[] args) {
GUI g = new GUI();
}
}
import javax.swing.*;
import java.awt.*;
public class GUI extends JFrame {
private JTextField t1 = new JTextField(2);
private JLabel l1 = new JLabel("enter position");
private JButton b1 = new JButton("new customer");
private JButton b2 = new JButton("wash car");
public GUI() {
setDefaultCloseOperation (
JFrame.EXIT_ON_CLOSE );
add(l1);
add(t1);
add(b1);
add(b2);
setTitle("Carwash");
setSize(500, 200);
setVisible(true);
setLayout(new FlowLayout());
add(new CarWashPanel());
}
}
public class Carwash {
private boolean[] positions = new boolean[10];
private int washing = 10;
public void addCar(int p) {
positions[p] = true;
}
public void removeCar(int p) {
positions[p] = false;
}
public boolean[] getPositions() {
return positions;
}
public int getWashing() {
return washing;
}
}
import java.awt.*;
import javax.swing.*;
public class CarWashPanel extends JPanel {
public CarWashPanel(){
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.black);
g.fillRoundRect(150, 50, 100, 100, 50, 25);
}
}
It's very often issue. You are calling setVisible before you are adding your components. Add your components on CarWashPanel, add CarWashPanel on JFrame and then call setVisible. Also, remove this line: setLayout(new FlowLayout()); - FlowLayout is default layout for JPanel (CarWashPanel in your case) and this makes it sufficient.
Your code should look something like this:
import javax.swing.*;
import java.awt.*;
public class Main {
public static void main(String[] args) {
SwingUtilities.invokeLater(GUI::new);
}
public static class GUI extends JFrame {
private JTextField t1 = new JTextField(2);
private JLabel l1 = new JLabel("enter position");
private JButton b1 = new JButton("new customer");
private JButton b2 = new JButton("wash car");
CarWashPanel carWashPanel = new CarWashPanel();
public GUI() {
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
carWashPanel.add(l1);
carWashPanel.add(t1);
carWashPanel.add(b1);
carWashPanel.add(b2);
add(carWashPanel,BorderLayout.CENTER);
setTitle("Carwash");
pack();
setVisible(true);
}
}
public class Carwash {
private boolean[] positions = new boolean[10];
private int washing = 10;
public void addCar(int p) {
positions[p] = true;
}
public void removeCar(int p) {
positions[p] = false;
}
public boolean[] getPositions() {
return positions;
}
public int getWashing() {
return washing;
}
}
public static class CarWashPanel extends JPanel {
public CarWashPanel() {
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.black);
g.fillRoundRect(150, 50, 100, 100, 50, 25);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(500, 200);
}
}
}
Other sidenotes:
Don't call setSize for JFrame, call pack. Rather override getPreferredSize for JPanel and return some dimensions.
Avoid extending your class with JFrame unless you want to define new methods or override existing ones.
If you don't need to add things dynamically the best thing to do is call setVisible(true) after you've added all your components.
However, if you want to add things after the frame is visible you can do so and then call the frame's revalidate() method to cause it to redraw.
Secondly I'd recommend you set the layout before you add any components.