【问题标题】:Add a JComponent via Child to Parent通过 Child 将 JComponent 添加到 Parent
【发布时间】:2019-06-13 02:24:05
【问题描述】:

我想完成与带有选择线的矩形图像非常相似的东西。

基本上,我有一个矩形,我想在它周围有一条选择线。 为此,我想创建一个额外的 JComponent。

目前我只能绘制矩形。如何在 Rectangle 类中获取 parentPanel JPanel,以便添加选择器?

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();
    }
}

如果我尝试在矩形内添加选择器,它将脱离绘图区域。如果我调整绘图区域的大小,它将无法为以后的开发进行扩展。

如果可能,我会避免双重绑定,例如:

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

【问题讨论】:

  • 考虑详细说明您的目标和实现目标的问题,并提出一个具体且可回答的问题。请查看How to Ask 了解更多现场最佳实践。另外,考虑告诉当前代码做什么是您不希望的,以及它不做什么是您当前希望它做的。我无法强调细节对于帮助我们理解您的代码和问题的重要性。
  • 您能否进一步澄清一下,我错过了什么?问题、解释或代码是否清晰?
  • 也许是我,但我不知道你在问什么,你需要什么帮助。 “让父母在矩形内”是什么意思?比如什么家长?此外,您想要实现什么样的用户体验,因为您可能正在处理这个错误,详细信息将帮助我们更好地理解事情。
  • 在我提供的图片中,有一个正方形。就像在油漆中一样。我想要完成的是一种在正方形周围制作虚线的方法。
  • 这似乎是一个纯粹的绘画问题,似乎不涉及创建新组件,但同样,它并不完全清楚。你为什么要创建一个新组件来做到这一点?这个“选择器”应该做什么?

标签: java swing jpanel jcomponent


【解决方案1】:

再说一次,我不是 100% 清楚您要达到的目标。如果您要创建的是用户创建的虚线,可以通过鼠标按下/拖动/释放来更改,那么您不需要创建新组件,而是使用 MouseAdapter 作为 MouseListener 和 MouseMotionListener,所有帮助您创建矩形,然后根据this answer 使用适当的笔划用虚线简单地绘制矩形。

例如,类似的东西会创建一条用户可选择的虚线:

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());
    }
}

【讨论】:

  • 代码非常好,但不是我想要的。我用你的例子试图解释得更好,看看是否更清楚?
  • @Joao,那么您将需要修改此代码或编写自己的代码,以便鼠标按下方法检查按下是否在现有行附近
猜你喜欢
  • 1970-01-01
  • 2019-01-09
  • 2021-01-09
  • 2018-03-12
  • 1970-01-01
  • 2013-05-03
  • 1970-01-01
  • 2021-12-06
  • 1970-01-01
相关资源
最近更新 更多