Почему вложенные компоненты не отрисовываются. Вопрос по компоновке swing java
Есть вот такой вот код:
MainFrame.java:
package org.example;
import javax.swing.*;
public class MainFrame extends JFrame {
private MainFrame(){
super("Example");
setLayout(null);
setContentPane(new MyPanel());
pack();
setLocationRelativeTo(null);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setResizable(false);
setVisible(true);
}
public static void main(String[] args) {
new MainFrame();
}
}
MyPanel.java:
package org.example;
import javax.swing.*;
import java.awt.*;
public class MyPanel extends JPanel {
public MyPanel(){
setLayout(null);
setPreferredSize(new Dimension(300,300));
MyComponent c = new MyComponent(new Rectangle(
20,
20,
100,
100
));
add(c);
}
}
MyComponent.java:
package org.example;
import javax.swing.*;
import java.awt.*;
public class MyComponent extends JPanel {
public MyComponent(Rectangle bounds){
setPreferredSize(bounds.getSize());
setLocation(bounds.getLocation());
}
@Override
public void paint(Graphics g) {
super.paint(g);
g.setColor(Color.RED);
g.fillRect(getX(), getY(), getPreferredSize().width, getPreferredSize().height);
}
}
Почему дочерний элемент MyPanel - MyComponent не отображается? Если я уберу строчку setLayout(null) в конструкторе MyPanel, то компонент отобразится по середине экрана на высоте 20. Но мне нужно абсолютное позиционирование элементов в JPanel. Я нашёл такое решение - переопределить в MyPanel метод paint(Graphics g), где я вручную дам этот Graphics каждому компоненту и он сам себя отрисует:
@Override
public void paint(Graphics g) {
super.paint(g);
for(Component c : getComponents())
c.paint(g);
}
Но тут есть две проблемы:
- так как этот
Graphics, который мы передаем в дочерние элементы, принадлежит родителю, то элементы должны сами себя отрисовать у родителя, для этого им нужно знать свои координаты у родителя, так же это должны учитывать все дочерние элементы этих дочерних, то есть если вMyComponentеще будут вложенности, то они должны будут учитывать своё положение как на прародителе так и на родителе, то есть с добавлением вложености тянутся все эти абсолютные координаты - Мы просто отрисовываем их, их фактический bounds не там, то есть если я прикручу к
MyComponentMouseListener, то он не будет работать, когда я тыкаю по компоненту, который всего лишь насильно графически изображён И из-за этих двух проблем мне это решение не подходит, так как я собираюсь делать больше вложенностей и прикручивать к нимMouseListenerПомогите реализовать так чтоб каждый компонентMyPanelотрисовывался в координатах, которые ему заданы с помощью методаsetLocation(Point p), то есть в нём вызывался методpaint(Graphics g)(или жеpaintComponent(Graphics g)), а в нём ужеGraphicsбыл с относительным позиционированием - относительно начала bounds'а самого компонента, ну и так как bounds правильный, то иMouseListenerбудет работать