在Java中创建自定义UI元素

在Java中创建自定义UI元素,java,swing,jframe,jpanel,Java,Swing,Jframe,Jpanel,我想在JFrame上绘制自定义元素 我通过创建一个类UI(扩展JFrame)和一个类组件(扩展JPanel)来尝试它。组件在自身上绘制一些东西,UI只是添加了这个组件。到目前为止,我已经编写了以下代码: 文件UI.java package UIComponent; import javax.swing.JFrame; public class UI extends JFrame { public UI(){ this.setSize(1024,684);

我想在JFrame上绘制自定义元素

我通过创建一个类UI(扩展JFrame)和一个类组件(扩展JPanel)来尝试它。组件在自身上绘制一些东西,UI只是添加了这个组件。到目前为止,我已经编写了以下代码:

文件UI.java

package UIComponent;

import javax.swing.JFrame; 

public class UI extends JFrame {

    public UI(){
        this.setSize(1024,684);
        this.setTitle("This is just a test program."); 
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        this.add(new Component(20,20,20,20)); 
        this.add(new Component(40,30,20,20)); 
    }

}
文件Component.java

package UIComponent;

import java.awt.Color;
import javax.swing.JPanel; 
import java.awt.Graphics; 

public class Component extends JPanel {

    int x, y, w, h; 

    public Component(int x, int y, int w, int h){
        this.x = x; 
        this.y = y; 
        this.w = w; 
        this.h = h; 
    }

    @Override
    public void paintComponent(Graphics g){
        g.setColor(Color.red);
        g.fillRect(this.x, this.y, this.w, this.h);
    }

}

但结果并不是我所接受的。它只画一个矩形

不要扩展JFrame。您没有向框架添加任何新行为

不要调用类组件。已经有一个同名的AWT类,所以您可能会导致Swing停止工作

this.add(new Component(20,20,20,20)); 
this.add(new Component(40,30,20,20)); 
JFrame的默认布局管理器是BorderLayout。默认情况下,在不指定约束的情况下将零部件添加到结构件时,零部件将转到中心。中心只能包含单个零部件,因此只能看到最后添加的零部件

相反,尝试将一个组件添加到BorderLayout.NORTH,将一个组件添加到SOUTH

此外,组件无法正确绘制,因为您需要覆盖自定义组件的
getPreferredSize()
方法,以便布局管理器可以完成其工作:

@Override
public Dimension getPreferredSize()
{
    return new Dimension(w, h);
}
此外,paintComponent()方法应该调用
super.paintcomont()

看看这本书。有关更多信息,请阅读
自定义绘制
布局管理器
部分

此外,矩形的绘制应在x/y位置(0,0)完成,以便整个绘制将适合组件的宽度/高度。如果希望矩形显示在特定位置,则应使用空布局,在这种情况下,您负责设置组件的位置和大小


如果您试图在面板上绘制形状,那么您可能应该使用
Shape
类,而不是创建自定义组件。有关更多想法,请参阅。

不要扩展JFrame。您没有向框架添加任何新行为

不要调用类组件。已经有一个同名的AWT类,所以您可能会导致Swing停止工作

this.add(new Component(20,20,20,20)); 
this.add(new Component(40,30,20,20)); 
JFrame的默认布局管理器是BorderLayout。默认情况下,在不指定约束的情况下将零部件添加到结构件时,零部件将转到中心。中心只能包含单个零部件,因此只能看到最后添加的零部件

相反,尝试将一个组件添加到BorderLayout.NORTH,将一个组件添加到SOUTH

此外,组件无法正确绘制,因为您需要覆盖自定义组件的
getPreferredSize()
方法,以便布局管理器可以完成其工作:

@Override
public Dimension getPreferredSize()
{
    return new Dimension(w, h);
}
此外,paintComponent()方法应该调用
super.paintcomont()

看看这本书。有关更多信息,请阅读
自定义绘制
布局管理器
部分

此外,矩形的绘制应在x/y位置(0,0)完成,以便整个绘制将适合组件的宽度/高度。如果希望矩形显示在特定位置,则应使用空布局,在这种情况下,您负责设置组件的位置和大小


如果您试图在面板上绘制形状,那么您可能应该使用
Shape
类,而不是创建自定义组件。有关更多信息,请参阅。

x/y/w/h值与组件的实际大小没有关系,该值可能为0x0,这意味着您将在组件的可见区域外侧进行绘制

首先重写
getPreferredSize
方法,并返回一个允许绘制可见的区域,如

public Dimension getPreferredSize() {
    return new Dimension(x + w, y + h);
}
比如说

默认情况下,JFrame使用
BorderLayout
,这意味着它将只允许一个组件在其5个可用位置中的任何位置可见

这意味着您的示例将只显示最后添加的组件

根据您想要达到的目的,您可以考虑使用<代码>覆盖布局> /代码>或其他一些布局管理器。

就个人而言,除非您有特殊需要,否则我不会担心绘制的x/y位置,只需从组件的0x0位置绘制,就可以让容器布局管理器处理实际的放置

我想重新考虑一下您的一些命名,因为组件已经存在于API中,可能会引起混淆,并且组件已经有了位置和大小的概念


请记住,零部件在其容器中的位置对零部件图形的开始位置没有影响。也就是说,0x0始终是组件的左上角。

x/y/w/h值与组件的实际大小没有关系,可能是0x0,这意味着您将在组件可见区域的外侧喷漆

首先重写
getPreferredSize
方法,并返回一个允许绘制可见的区域,如

public Dimension getPreferredSize() {
    return new Dimension(x + w, y + h);
}
比如说

默认情况下,JFrame使用
BorderLayout
,这意味着它将只允许一个组件在其5个可用位置中的任何位置可见

这意味着您的示例将只显示最后添加的组件

根据您想要达到的目的,您可以考虑使用<代码>覆盖布局> /代码>或其他一些布局管理器。

就个人而言,除非您有特殊需要,否则我不会担心绘制的x/y位置,只需从组件的0x0位置绘制,就可以让容器布局管理器处理实际的放置

我想重新考虑一下您的一些命名,因为组件已经存在于API中,可能会引起混淆,并且组件已经有了位置和大小的概念

请记住,组件在其容器中的位置没有