João Marques
João Marques

Reputation: 141

Add a JComponent via Child to Parent

enter image description here

I want to accomplish something very similar to the image a Rectangle whit a Selector Line.

Basically, I have a Rectangle and I want to have a selector line all around it. For that, I wanted to create an additional JComponent.

At the moment I can only draw the Rectangle. How could I get the parentPanel JPanel inside the Rectangle class, so that I could add the selector?

public class TestPanel extends JFrame {

    public class Rectangle extends JComponent {

        public Rectangle(){
            setBounds(x1, y1, x2, y2);

            JPanel Selector = new JPanel();
            //Adds Selector to parentPanel within Rectangle
            //setBounds(x1-1, y1-1, x2+1, y2+1)
            //!Problem parent is initially null! cant even a use property
            //Life hacks?
        }
        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.drawRect(0, 0, getWidth(), getHeight());
        }
    }

    public TestPanel() {
        Rectangle Rectangle = new Rectangle();
        JPanel parentFrame = new JPanel();
        parentFrame.add(Rectangle);

        setSize(200, 200);
        setVisible(true);
    }

    public static void main(String[] args) {
        new TestPanel();
    }
}

If I try to add the selector inside the rectangle, it will get out of the drawing area. If I resize the drawing area, it won't be scalable for later development.

If possible I would avoid dual binding like:

public TestPanel() {
            Rectangle Rectangle = new Rectangle();
            JPanel parentPanel = new JPanel();
            parentPanel.add(Rectangle);
            Rectangle.addParent(parentPanel)
            ...
        }

Upvotes: 0

Views: 96

Answers (1)

Hovercraft Full Of Eels
Hovercraft Full Of Eels

Reputation: 285403

Again, I'm not 100% clear on what you're trying to achieve. If what you wish to create is a user-created dashed line, one that can change with mouse press/drag/release, then you don't need to create a new component but rather use a MouseAdapter as a MouseListener and MouseMotionListener, all to help you create the Rectangle, and then simply draw the Rectangle with a dashed line using an appropriate Stroke, as per this answer.

For example, something like would create a dashed line that is user-selectable:

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Stroke;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.*;

public class SelectorPanel extends JPanel {
    private static final int PREF_W = 800;
    private static final int PREF_H = 650;
    private static final Stroke DASHED_STROKE = new BasicStroke(2, BasicStroke.CAP_BUTT,
            BasicStroke.JOIN_BEVEL, 0, new float[] { 5 }, 0);
    private static final Color DASHED_COLOR = Color.LIGHT_GRAY;
    private Rectangle rectangle = null;

    public SelectorPanel() {
        MyMouse myMouse = new MyMouse();
        addMouseListener(myMouse);
        addMouseMotionListener(myMouse);
    }

    private class MyMouse extends MouseAdapter {
        private Point p1 = null;

        @Override
        public void mousePressed(MouseEvent e) {
            p1 = e.getPoint();
            rectangle = null;
        }

        @Override
        public void mouseDragged(MouseEvent e) {
            if (p1 != null) {
                createRectangle(e);
            }
        }

        @Override
        public void mouseReleased(MouseEvent e) {
            if (p1 != null) {
                createRectangle(e);
                p1 = null;
            }
        }

        private void createRectangle(MouseEvent e) {
            Point p2 = e.getPoint();
            int x = Math.min(p1.x, p2.x);
            int y = Math.min(p1.y, p2.y);
            int width = Math.abs(p1.x - p2.x);
            int height = Math.abs(p1.y - p2.y);
            rectangle = new Rectangle(x, y, width, height);
            repaint();
        }

    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        if (rectangle != null) {
            Graphics2D g2 = (Graphics2D) g.create();
            g2.setColor(DASHED_COLOR);
            g2.setStroke(DASHED_STROKE);
            g2.draw(rectangle);
            g2.dispose();
        }
    }

    @Override
    public Dimension getPreferredSize() {
        if (isPreferredSizeSet()) {
            return super.getPreferredSize();
        }
        return new Dimension(PREF_W, PREF_H);
    }

    private static void createAndShowGui() {
        SelectorPanel mainPanel = new SelectorPanel();

        JFrame frame = new JFrame("SelectorPanel");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }
}

Upvotes: 1

Related Questions