I need to create an object of a subclass in the subclass itself but outside of all the methods of the subclass.
In the code below, I want to create an object of ODrawPanel at the specified location (commented part in the code) but when I do this, I get a StackOverflowError. However, I can create the object ODrawPanel inside the display() method with no problem but in that case I cannot use it in the other methods. I need to do some drawing on the panel and the panel must be available anywhere in the code.
How can I make the panel object available anywhere in the code?
Thanks for helping.
package odrawpanel;
import java.awt.*;
import javax.swing.*;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentAdapter;
public class ODrawPanel extends JPanel
{
private Point p1 = new Point(100, 300);
private Point p2 = new Point(380, 300);
// Either
// JPanel panel = new ODrawPanel(); I want to create the object of the subclass here.
// or
// ODrawPanel panel = new ODrawPanel();
@Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
g.setColor(Color.BLUE);
g.drawLine(p1.x, p1.y, p2.x, p2.y);
}
public void display()
{
JPanel panel = new ODrawPanel();
JFrame f = new JFrame();
panel.setBounds(40, 40, 400, 400);
panel.setBackground(Color.white);
f.add(panel);
f.setSize(800,600);
f.setLayout(null);
f.setLocationRelativeTo(null);
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.addComponentListener(new ComponentAdapter()
{
@Override
public void componentResized(ComponentEvent e)
{
panel.setSize(f.getWidth()-100,f.getHeight()-100);
}
});
}
public static void main(String args[])
{
EventQueue.invokeLater(new Runnable()
{
@Override
public void run()
{
new ODrawPanel().display();
}
});
}
}
CodePudding user response:
I would create different classes for the main(), the JFrame, the JPanel.
In Main: new JFrame();
In JFrame: add(new JPanel()); ...
In JPanel: Do not create JPanels here. ...
CodePudding user response:
You may declare a JPanel
supplier with lazy initialization as a field of the class:
private Point p1 = new Point(100, 300);
private Point p2 = new Point(380, 300);
private final Supplier<JPanel> panelSupplier = new Supplier<>() {
private JPanel panel;
@Override
public JPanel get() {
if (panel == null) {
panel = new ODrawPanel();
}
return panel;
}
};
... and then use it all over the class by .get()
ting the value from the supplier (the first time you use it, the ODrawPanel
will be created but it won't cause an overflow since you're not recursively initializing it:
public void display() {
JPanel panel = panelSupplier.get(); //the first time you call get() it will create the panel, the next times it will reuse it
JFrame f = new JFrame();
panel.setBounds(40, 40, 400, 400);
//...rest of the code