I have a problem with my project, my project is draw lines (likes paint in windows). I want to draw more one line with mouseDragged,mousePressed and mouseReleased. But when I run to test, it showed a lot of errors, here my code
package image;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Point;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class paint extends JFrame{
private Point points[] = new Point[10000];
private Point pointends[] = new Point[10000];
private int pointCount = 0;
public paint()
{
panel paint2 = new panel();
add(paint2,BorderLayout.CENTER);
}
private class panel extends JPanel
{
public panel()
{
setBackground(Color.BLUE);
MouseHandler handler = new MouseHandler();
this.addMouseMotionListener(handler);
this.addMouseListener(handler);
}
#Override
protected void paintComponent(Graphics g)
{
// TODO Auto-generated method stub
super.paintComponent(g);
for(int i = 0;i < pointCount;i++)
{
g.setColor(Color.RED);
g.drawLine(points[pointCount].x, points[pointCount].y, pointends[pointCount].x, pointends[pointCount].y);
}
}
}
private class MouseHandler extends MouseAdapter
{
#Override
public void mouseDragged(MouseEvent e)
{
// TODO Auto-generated method stub
pointends[ pointCount ] = e.getPoint();
repaint();
}
#Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
super.mousePressed(e);
if(pointCount < points.length)
{
points[ pointCount ] = e.getPoint();
}
}
#Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
super.mouseReleased(e);
pointends[pointCount]=e.getPoint();
repaint();
pointCount++;
}
}
}
and here's my void main
package image;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import java.awt.BorderLayout;
public class test
{
public static void main(String[] args) {
paint paint1 = new paint();
/*paintP.add(paint1, BorderLayout.CENTER);
paintP.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
paintP.setSize(400,400);
paintP.setVisible(true);*/
paint1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
paint1.setSize(400,400);
paint1.setVisible(true);
}
}
In your paintComponentmethod, change the line
g.drawLine(points[pointCount].x, points[pointCount].y, pointends[pointCount].x, pointends[pointCount].y);
to this:
g.drawLine(points[i].x, points[i].y, pointends[i].x, pointends[i].y);
This will get rid of the NullPointerException and the lines will be drawn correctly once you release the mouse button. (Before, you were not only trying to paint the same line in each iteration of the loop, but also a line that did not exist yet, thus the NullPointerException.)
There's another problem: In your releaseMouse and mouseDragged methods, you are setting the end points for the line at index pointCount, but you are drawing only up to pointCount - 1. You have to increment the pointCount counter when you start drawing the lines, otherwise the new line will only be drawn when the mouse is released. One way to fix this would be to change your mouse listener to this:
private class MouseHandler extends MouseAdapter {
public void mouseDragged(MouseEvent e) {
pointends[ pointCount - 1 ] = e.getPoint(); // note the "- 1"
repaint();
}
public void mousePressed(MouseEvent e) {
if(pointCount < points.length) {
points[ pointCount ] = e.getPoint();
pointends[ pointCount ] = e.getPoint(); // add end point
pointCount++;
repaint();
}
}
public void mouseReleased(MouseEvent e) { // do nothing
}
}
You may try this:
public class myDrawLine extends JPanel {
private static final long serialVersionUID = 1L;
// These ArrayList will save all Points of Pressed and Released
ArrayList<Point> pointStart = new ArrayList<Point>();
ArrayList<Point> pointEnd = new ArrayList<Point>();
// These single Points will save the point of Dragged
Point startSinglePoint = new Point();
Point endSinglePoint = new Point();
public void paint(Graphics g) {
super.paint(g);
g.drawLine(startSinglePoint.x, startSinglePoint.y, endSinglePoint.x,
endSinglePoint.y);
for (int i = 0; i < pointStart.size() && i < pointEnd.size(); i++) {
g.drawLine(pointStart.get(i).x, pointStart.get(i).y,
pointEnd.get(i).x, pointEnd.get(i).y);
}// end for
}// end paint
{// start Block of Listeners
addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
startSinglePoint = e.getPoint(); // used to the draw line when
// you drag
pointStart.add(e.getPoint()); // used to save all drew lines
}// end mousePressed
public void mouseReleased(MouseEvent e) {
pointEnd.add(e.getPoint()); // used to save all drew lines
repaint();
}// end mouseReleased
});// end addMouseListener
addMouseMotionListener(new MouseAdapter() {
public void mouseDragged(MouseEvent e) {
endSinglePoint = e.getPoint(); // used to draw the line when you
// drag
repaint();
}// end mouseDragged
});// end addMouseMotionListener
}// end Block of Listeners
}// end Class
and the main method:
public static void main(String[] args){
JFrame frame = new JFrame("Draw Line");
frame.setSize(300, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
myDrawLine draw = new myDrawLine();
frame.getContentPane().add(draw);
}//end main
Related
so I have a question, lets say I create a rectangle in Java using the paint method, after a 100 ms delay I do super.paint(g), this clears the rectangle previously shown, is there a way to make it re appear?
Thanks!
An example of what I'm talking about is down below, what this program is meant to do is whenever I hold down mouse button 1, it creates a rectangle that goes down and than disapears after mouse button 1 is off. The problem is whenever I hold down mouse button 1 again, the rectangle doesn't appear.
First class:
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import javax.swing.JFrame;
import javax.swing.Timer;
public class RecoilHelper extends JFrame {
static Timer rs;
static int recoil = 540;
static boolean clearRectangle = false;
/**
* Launch the application.
*/
public static void main(String[] args) {
JNativehookRecoilHelp.main(null);
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
RecoilHelper frame = new RecoilHelper();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public RecoilHelper() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
setBounds(0, 0, 1920, 1080);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setUndecorated(true);
setBackground(new Color(1.0f,1.0f,1.0f,0.0f));
setAlwaysOnTop(true);
rs = new Timer(10,(ActionEvent e)->{
repaint();
recoil += 12;
if (recoil>600) {
rs.stop();
}
});
}
public void paint(Graphics g) {
Rectangle r = new Rectangle(960, recoil, 4, 4);
System.out.println(recoil);
super.paintComponents(g);
g.fillRect(
(int)r.getX(),
(int)r.getY(),
(int)r.getWidth(),
(int)r.getHeight()
);
if (clearRectangle) {
super.paint(g);
}
}
}
Second class(tracks mouse button 1 events using JNativehook):
import java.util.logging.Level;
import java.util.logging.LogManager;
import java.util.logging.Logger;
import org.jnativehook.GlobalScreen;
import org.jnativehook.NativeHookException;
import org.jnativehook.mouse.NativeMouseEvent;
import org.jnativehook.mouse.NativeMouseInputListener;
public class JNativehookRecoilHelp implements NativeMouseInputListener {
#Override
public void nativeMouseClicked(NativeMouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void nativeMousePressed(NativeMouseEvent arg0) {
// TODO Auto-generated method stub
System.out.println("Pressed");
RecoilHelper.recoil = 540;
RecoilHelper.rs.start();
}
#Override
public void nativeMouseReleased(NativeMouseEvent arg0) {
// TODO Auto-generated method stub
System.out.println("Released");
RecoilHelper.clearRectangle=true;
}
#Override
public void nativeMouseDragged(NativeMouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void nativeMouseMoved(NativeMouseEvent arg0) {
// TODO Auto-generated method stub
}
public static void main(String[] args) {
GlobalScreen.addNativeMouseListener(new JNativehookRecoilHelp());
LogManager.getLogManager().reset();
// Get the logger for "org.jnativehook" and set the level to off.
Logger logger = Logger.getLogger(GlobalScreen.class.getPackage().getName());
logger.setLevel(Level.OFF);
try {
GlobalScreen.registerNativeHook();
}
catch (NativeHookException ex) {
System.exit(1);
}
}
}
Currently you are attempting to override the paint method of the JFrame, this presents two issues, this first is that a JFrame is a heavyweight component (it has a title bar and a number of associated things that you need to consider) so you may have endless issues, the second issue is that you need to override the paintComponent method of the component that you wish to perform custom painting on.
The solution here is to instead place a JPanel inside the JFrame, and override the paintComponent method of the JPanel.
Below is a working example that creates a new rectangle and adds it to the frame every half second but also keeps the existing rectangles by adding them to a list and drawing each one in the list every time it is repainted.
The main class is simple, and simply adds our CustomJpanel to the JFrame:
public class PaintExample extends JFrame
{
private CustomJPanel customJpanel;
public PaintExample()
{
//Create and add the custom panel to the JFrame
setPreferredSize(new Dimension(400, 300));
customJpanel = new CustomJPanel();
getContentPane().add(customJpanel, java.awt.BorderLayout.CENTER);
pack();
}
public static void main(String args[])
{
//Show the JFrame:
java.awt.EventQueue.invokeLater(new Runnable()
{
public void run()
{
new PaintExample().setVisible(true);
}
});
}
}
And the custom panel class that does our painting:
public class CustomJPanel extends JPanel
{
int x = 0;
int y = 0;
boolean clearRectangle = true;
//This is a list that we use to keep track of all the rectangles to draw/update
ArrayList<Rectangle> rectangleList = new ArrayList<>();
//Start a timer when the panel is created that will update the rectangle location every half second (500ms).
//In your case you would use your recoil timer instead
public CustomJPanel(){
//Create event action
ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
add a new rectangle in a different location
x+= 5;
y+= 5;
rectangleList.add(new Rectangle(x,y,10,10));
//Update the panel
repaint();
}
};
//Create and start a repeating event
Timer timer = new Timer(500, taskPerformer);
timer.setRepeats(true);
timer.start();
}
//Here is where it all happens:
#Override
protected void paintComponent(Graphics g)
{
//Call super first to perform normal component painting
super.paintComponent(g);
//Now do your custom painting
if (clearRectangle)
{
//Draw each rectangle in the list
for (Iterator<Rectangle> iterator = rectangleList.iterator(); iterator.hasNext();)
{
Rectangle r = iterator.next();
g.drawRect(r.x, r.y, r.width, r.height);
}
}
}
}
And the window looks like this after a couple so seconds, note how it keeps all previous rectangles:
I've created my own extended JPanel to able the user to sign on it, after that save the signature and delete from the panel:
public class PanelParaFirmar extends JPanel
{
private MouseHandler mouseHandler = new MouseHandler();
private int index = 0;
private Point[] arr = new Point[100000];
public PanelParaFirmar()
{
this.setBackground(Color.WHITE);
this.addMouseListener(mouseHandler);
this.addMouseMotionListener(mouseHandler);
}
protected void paintComponent(Graphics g)
{
this.paintComponents(g);
for (int i = 0; i < index - 1; i++)
g.drawLine(arr[i].x, arr[i].y, arr[i + 1].x, arr[i + 1].y);
}
private class MouseHandler extends MouseAdapter {
#Override
public void mousePressed(MouseEvent e) {
arr[index] = new Point(e.getX(), e.getY());
index++;
repaint();
}
#Override
public void mouseReleased(MouseEvent e) {
arr = new Point[100000];
index = 0;
}
#Override
public void mouseDragged(MouseEvent e) {
//updateUI();
//save();
arr[index] = new Point(e.getX(), e.getY());
index++;
repaint();
}
public void mouseExited(MouseEvent e) {}
public void mouseClicked(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {}
public void mouseMoved(MouseEvent e) {}
}
};
Before click on it all it's right:
But when I started to sign, it repaints the rootPane:
How can I paint just the line?
In addition to the fact that you should override paintComponent and not paintComponents , and call its super implementation, here is how you could manage multiple lines for one signature .
Create a list of lines ( a line is nothing else than a list of Point) to represent the signature.
When the mouse is pressed, add a new line to the list, and add the current point to this line.
When the mouse is dragged, add the current point to the current line.
Finally, your paint method will paint each line one after the other, without making junctions between them :
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class PanelParaFirmar extends JPanel {
private final MouseHandler mouseHandler = new MouseHandler();
private final List<List<Point>> lines = new ArrayList<>();
private List<Point> currentLine;
public static void main(final String[] args) {
JFrame fr = new JFrame();
fr.setSize(400, 200);
fr.getContentPane().add(new PanelParaFirmar());
fr.setVisible(true);
}
public PanelParaFirmar() {
this.setBackground(Color.WHITE);
this.addMouseListener(mouseHandler);
this.addMouseMotionListener(mouseHandler);
}
protected void paintComponent(final Graphics g) {
super.paintComponent(g);
for (List<Point> line : lines) {
for (int i = 0; i < line.size() - 1; i++) {
Point thisPoint = line.get(i);
Point nextPoint = line.get(i + 1);
g.drawLine(thisPoint.x, thisPoint.y, nextPoint.x, nextPoint.y);
}
}
}
private class MouseHandler extends MouseAdapter {
#Override
public void mousePressed(final MouseEvent e) {
currentLine = new ArrayList<Point>();
currentLine.add(new Point(e.getX(), e.getY()));
lines.add(currentLine);
repaint();
}
#Override
public void mouseDragged(final MouseEvent e) {
Point p = new Point(e.getX(), e.getY());
currentLine.add(p);
repaint();
}
}
}
Also note that since you are using a MouseAdapter , you don't have to implement the methods you don't need (like mouseClicked).
So i have been trying to learn swing and trying to make a painting program.
The problem ive been having is that if you move your mouse to fast it doesnt fill the gaps (Run code if you dont undetstand)
Im thinking it might be where its filling up the arraylist.
So i was woundering how i can fix this, Thanks!
My code:
import javax.swing.*;
import java.util.ArrayList;
import java.awt.event.MouseMotionAdapter;
import java.awt.event.MouseAdapter;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
public class Window extends JPanel implements MouseListener{
//new array list
private ArrayList<Point> dots;
static JFrame frame;
Font f;
static int Dx1=0, Dx2=0, Dy1=0, Dy2=0; //fill void dots
static int v=0;
static int posX = 250;
static int posY = 250;
static double winX=0;
static double winY=0;
public Window() {
dots = new ArrayList<Point>();
frame = new JFrame();
f = new Font("Calibri", Font.BOLD, 30);
this.setBackground(Color.white);
frame.add(this);
frame.setResizable(true);
frame.setVisible(true);
frame.setSize(500, 500);
frame.setTitle("Minigameshuehu");
frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);
// MOVE BALL DEPENDING ON "Dragging"
this.addMouseListener(this);
this.addMouseListener(new MouseAdapter() {
});
this.addMouseMotionListener(new MouseMotionAdapter() {
#Override
public void mouseDragged(MouseEvent e) {
dots.add(new Point(e.getX(), e.getY())); // adding pos to to array to make dots
repaint();
}
#Override
public void mouseMoved(MouseEvent e) {
posX = e.getX() - 3;
posY = e.getY() - 3;
repaint();
}
}
);
//End of moving ball
}
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setColor(new Color(0,0,0));
g2.fillOval(posX, posY, 6, 6);
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setColor(Color.black);
for (Point point : dots) {
g2.fillOval(point.x-3, point.y-3, 6, 6);
}
}
public static void main(String[] args) throws InterruptedException {
Window applikation = new Window();
}
#Override
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseExited(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mousePressed(MouseEvent e) {
// posX=(e.getX()-25);
// posY=(e.getY()-25);
// TODO Auto-generated method stub
}
#Override
public void mouseReleased(MouseEvent arg0) {
v=0;
// TODO Auto-generated method stub
}
}
if you move your mouse to fast it doesnt fill the gaps
That is correct, a MouseEvent is not generated for every pixel, so you can't just draw an oval for every point generated.
Instead, you need to draw a line between two points in your ArrayList.
for (int i = 0; i < dots.size() - 1; i++)
{
Point p1 = dots.get(i);
Point p2 = dots.get(i + 1);
g2.drawLine(...);
}
You will also want to change the size of the line drawn by using something like:
g2.setStroke(new BasicStroke(15, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
This will draw a line with a rounded edge so it looks like the end of an oval.
I've created a basic Java program that creates a rectangle on startup and every time it is clicked, the rectangle grows and changes to a different (random) color. here's my code:
package rectPAK;
import javax.swing.JFrame;
public class DisplayRect {
public static void main(String[] args) {
JFrame window = new JFrame();
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setBounds(0,0,1000,1000);
window.getContentPane().add(new MyCanvas());
window.setVisible(true);
}
}
and then myCanvas is this:
package rectPAK;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.util.Random;
import javax.swing.JComponent;
public class MyCanvas extends JComponent{
int W = 100;
int H = 100;
int r;
int g;
int b;
int trans;
int maxRandNum = 255;
int xPoint;
int yPoint;
public MyCanvas() {
this.addMouseListener(m);
this.addMouseMotionListener(ml);
}
Random rand = new Random();
MouseListener m = new MouseListener() {
#Override
public void mouseClicked(MouseEvent e) {
W = W + 20;
H = H + 20;
r = rand.nextInt(maxRandNum);
g = rand.nextInt(maxRandNum);
b = rand.nextInt(maxRandNum);
trans = rand.nextInt(maxRandNum);
repaint();
}
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
public void mousePressed(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
};
MouseMotionListener ml = new MouseMotionListener() {
#Override
public void mouseDragged(MouseEvent e) {
Point p = e.getLocationOnScreen();
xPoint = p.x;
yPoint = p.y;
repaint();
}
#Override
public void mouseMoved(MouseEvent e) {
// TODO Auto-generated method stub
}
};
public void paint(Graphics gr) {
gr.setColor(Color.BLACK);
gr.drawRect(xPoint, yPoint, W, H);
gr.setColor(new Color(r,g,b,trans));
gr.fillRect(xPoint, yPoint, W, H);
}
}
now my question is this: how do i make it so that when i right-click on the rectangle, it reverts to the previous size and color? i Know it's a lot to ask, but i cant find anything about it...
Thanks a lot.
Use a set of "previous" variables (eg previousX, previousY, previousR, etc) to store the old info before every update, and create a right click event to call a method like your paint method to set the object's variables to previousX, previousY, etc.
Every time you generate a random number, store it as the previous instance. This way you will be able to go back one step. If you want to go back all the way to the first one, then you should store each created rectangle's parameters in an stack of sorts, where you could pop out each previous stage.
Once that is done you should create a method for handling right clicks, and in that method, you should set the rectangles parameters to the previous value.
Anybody know how can I repaint in a clone JPanel. Im using CLONE, so I can REPAINT() one, and the other will do the same automatically.
My code only paints the original JPanel if I move the mouse in the original or in the clone panel,
but If I move the mouse in the clone panel, this jpanel doesn't paint.
Thanks in advance
CODE:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class ProcessorClone {
public static void main(String[] args) {
JFrame aWindow = new JFrame();
aWindow.setBounds(300, 200, 300, 100);
aWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Container content = aWindow.getContentP
aWindow.setVisible(true);
CardViewer panel02=new CardViewer();
CardViewer panel01= (CardViewer) panel02.clone();
aWindow.setLayout(new BorderLayout());
aWindow.add(panel01,BorderLayout.NORTH);
aWindow.add(panel02,BorderLayout.SOUTH);
panel01.setBackground(Color.RED);
panel02.setBackground(Color.blue);
panel01.repaint();
panel02.repaint();
panel01.validate();
panel02.validate();
}
}
class CardViewer extends JPanel implements MouseListener,MouseMotionListener, Cloneable {
/**
*
*/
private static final long serialVersionUID = 1L;
private JPanel mContentPaneBorder;
private JPanel mContentPane;
private JButton FileButton=new JButton("AAA");
private Point p;
public CardViewer(){
super();
this.add(FileButton);
addMouseListener(this);
addMouseMotionListener(this);
}
#Override
public void mouseClicked(MouseEvent arg0) {
System.out.println("mouseClicked");
}
#Override
public void mouseEntered(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mouseExited(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mousePressed(MouseEvent arg0) {
System.out.println("mousePressed");
p = null;
repaint();
}
#Override
public void mouseReleased(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mouseDragged(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mouseMoved(MouseEvent e) {
System.out.println("mouseMoved");
p = e.getPoint();
this.repaint();
this.validate();
}
public void paint(Graphics g) {
System.out.println( g.getClass() );
if (p != null) {
Dimension d = getSize();
int xc = d.width / 2;
int yc = d.height / 2;
g.drawLine(p.x, p.y, p.x, p.y);
this.setBackground(Color.pink);
}
}
public Object clone () {
// First make exact bitwise copy
CardViewer copy = null;
try {
copy = (CardViewer)super.clone();
} catch (CloneNotSupportedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return copy;
}
}
.clone() does not return a mirror of the JPanel but returns a copy of the object, so you really have 2 separate JPanel objects so actions in one will not automatically reflect in the other.
You could override all the actions in a component that inherits from JPanel with a reference to a .cloned() JPanel object and then route all methods to the other JPanel after calling super()