Java 使用控件的图形在另一个控件内绘制控件

Java 使用控件的图形在另一个控件内绘制控件,java,swing,user-interface,controls,awt,Java,Swing,User Interface,Controls,Awt,我基本上是试图通过调用第二个组件的画图来在另一个组件中绘制一个JComponent,并将其传递给第一个组件的图形 我正在尝试创建一个GUI编辑器(我知道,这只是一个概念证明,是对轮子的重新发明) 所以我有一个扩展了JPanel的类,我想从VectorControl中绘制组件 到目前为止,我在扩展的JPanel中获得了这种方法: @SuppressWarnings("serial") public class Sketch extends JPanel { private Vector&l

我基本上是试图通过调用第二个组件的画图来在另一个组件中绘制一个JComponent,并将其传递给第一个组件的图形

我正在尝试创建一个GUI编辑器(我知道,这只是一个概念证明,是对轮子的重新发明) 所以我有一个扩展了JPanel的类,我想从VectorControl中绘制组件

到目前为止,我在扩展的JPanel中获得了这种方法:

@SuppressWarnings("serial")
public class Sketch extends JPanel {
    private Vector<JComponent> controls = new Vector<JComponent>();

    public Sketch() {
        super();
        this.setLayout(new BoxLayout(this,BoxLayout.Y_AXIS));
    }

    public void addControl(JComponent c) {
        Dimension d = new Dimension(100,50);
        c.setPreferredSize(d);
        c.setMinimumSize(d);
        c.setMaximumSize(d);
        controls.add(c);
        this.repaint();
        this.revalidate();
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        for(int i=controls.size()-1; i>=0; i--) {
            JComponent c = controls.get(i);
            c.paint(g);
        }       
    }
}
在ToolBoxButtonAction中,基本上我是这样做的:

public void actionPerformed(ActionEvent e) {
    try {
        sketch.addControl(control.newInstance());
    } catch (InstantiationException e1) {
        e1.printStackTrace();
    } catch (IllegalAccessException e1) {
        e1.printStackTrace();
    }
}
但我写这篇文章是因为它不起作用


关于如何实现这一点有什么想法吗?

不久前,我已经为这些任务编写了一个框架。也许您会发现它很有用(该库是开源的):

教程:

Javadoc:

有关最新版本的信息:


不久前,我为此类任务编写了一个框架。也许您会发现它很有用(该库是开源的):

教程:

Javadoc:

有关最新版本的信息:

我基本上是试图通过调用第二个组件的画图来在另一个组件中绘制一个JComponent,并将其传递给第一个组件的图形

仅当零部件尺寸非零时,才能绘制零部件。通常,零部件的尺寸由布局管理器确定

您的基本代码看起来合理,但除非您有代码来确定组件的大小和位置,否则您将看不到任何内容。如果只设置大小,则所有组件都将在彼此的顶部绘制

或者问题可能是您的父面板没有大小,因此它甚至没有绘制。默认的FlowLayout使用子组件的首选大小来确定面板大小。由于不直接向配电盘添加元件,因此没有子元件,因此首选尺寸为0。当你重新发明轮子时,你需要重新发明一切

没有SSCCE,您如何使用此代码的上下文是未知的,我们所能做的只是猜测

编辑:

在出现问题时创建SSCCE,并在尝试使其动态工作之前使用硬编码值使其工作。比如:

import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;

public class Sketch extends JComponent
{
    private Vector<JComponent> controls = new Vector<JComponent>();

    public void addControl(JComponent c)
    {
        c.setSize(100, 50);
        int location = controls.size() * 50;
        c.setLocation(location, location);
        controls.add(c);
        repaint();
    }

    @Override
    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);

        for(int i=controls.size()-1; i>=0; i--)
        {
            JComponent c = controls.get(i);
            Point location = c.getLocation();
            g.translate(location.x, location.y);
            c.paint(g);
            g.translate(-location.x, -location.y);
        }
    }

    private static void createAndShowUI()
    {
        Sketch sketch = new Sketch();
        sketch.addControl( new JButton("button") );
        sketch.addControl( new JTextField(10) );
        sketch.addControl( new JCheckBox("Checkbox") );

        JFrame frame = new JFrame("Sketch");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add( sketch );
        frame.setSize(400, 400);
        frame.setLocationByPlatform( true );
        frame.setVisible( true );
    }

    public static void main(String[] args)
    {
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                createAndShowUI();
            }
        });
    }
}
import java.awt.*;
导入java.awt.event.*;
导入java.util.*;
导入javax.swing.*;
公共类Sketch扩展了JComponent
{
私有向量控件=新向量();
公共控件(JComponent c)
{
c、 设置大小(100,50);
int location=controls.size()*50;
c、 设置位置(位置,位置);
添加(c);
重新油漆();
}
@凌驾
公共组件(图形g)
{
超级组件(g);
对于(int i=controls.size()-1;i>=0;i--)
{
JComponent c=controls.get(i);
点位置=c.getLocation();
g、 翻译(位置x,位置y);
c、 油漆(g);
g、 平移(-location.x,-location.y);
}
}
私有静态void createAndShowUI()
{
草图=新草图();
添加控件(新的JButton(“按钮”));
草图.addControl(新JTextField(10));
sketch.addControl(新的JCheckBox(“复选框”);
JFrame框架=新JFrame(“草图”);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
框架。添加(草图);
框架。设置尺寸(400400);
frame.setLocationByPlatform(真);
frame.setVisible(true);
}
公共静态void main(字符串[]args)
{
invokeLater(新的Runnable()
{
公开募捐
{
createAndShowUI();
}
});
}
}
我基本上是试图通过调用第二个组件的画图来在另一个组件中绘制一个JComponent,并将其传递给第一个组件的图形

仅当零部件尺寸非零时,才能绘制零部件。通常,零部件的尺寸由布局管理器确定

您的基本代码看起来合理,但除非您有代码来确定组件的大小和位置,否则您将看不到任何内容。如果只设置大小,则所有组件都将在彼此的顶部绘制

或者问题可能是您的父面板没有大小,因此它甚至没有绘制。默认的FlowLayout使用子组件的首选大小来确定面板大小。由于不直接向配电盘添加元件,因此没有子元件,因此首选尺寸为0。当你重新发明轮子时,你需要重新发明一切

没有SSCCE,您如何使用此代码的上下文是未知的,我们所能做的只是猜测

编辑:

在出现问题时创建SSCCE,并在尝试使其动态工作之前使用硬编码值使其工作。比如:

import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;

public class Sketch extends JComponent
{
    private Vector<JComponent> controls = new Vector<JComponent>();

    public void addControl(JComponent c)
    {
        c.setSize(100, 50);
        int location = controls.size() * 50;
        c.setLocation(location, location);
        controls.add(c);
        repaint();
    }

    @Override
    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);

        for(int i=controls.size()-1; i>=0; i--)
        {
            JComponent c = controls.get(i);
            Point location = c.getLocation();
            g.translate(location.x, location.y);
            c.paint(g);
            g.translate(-location.x, -location.y);
        }
    }

    private static void createAndShowUI()
    {
        Sketch sketch = new Sketch();
        sketch.addControl( new JButton("button") );
        sketch.addControl( new JTextField(10) );
        sketch.addControl( new JCheckBox("Checkbox") );

        JFrame frame = new JFrame("Sketch");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add( sketch );
        frame.setSize(400, 400);
        frame.setLocationByPlatform( true );
        frame.setVisible( true );
    }

    public static void main(String[] args)
    {
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                createAndShowUI();
            }
        });
    }
}
import java.awt.*;
导入java.awt.event.*;
导入java.util.*;
导入javax.swing.*;
公共类Sketch扩展了JComponent
{
私有向量控件=新向量();
公共控件(JComponent c)
{
c、 设置大小(100,50);
int location=controls.size()*50;
c、 设置位置(位置,位置);
添加(c);
重新油漆();
}
@凌驾
公共组件(图形g)
{
超级组件(g);
对于(int i=controls.size()-1;i>=0;i--)
{
JComponent c=controls.get(i);
点位置=c.getLocation();
g、 翻译(位置x,位置y);
c、 油漆(g);
g、 平移(-location.x,-location.y);
}
}
私有静态void createAndShowUI()
{
草图=新草图();
添加控件(新的JButton(“按钮”));
草图.addControl(新JTextField(10));
sketch.addControl(新的JCheckBox(“复选框”);
JFrame框架=新JFrame(“草图”);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
框架。添加(草图);
框架。设置尺寸(400400);
frame.setLocat