用Java创建自定义UI元素

时间:2013-11-13 19:59:28

标签: java swing jframe jpanel

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

我通过创建类UI(扩展JFrame)和类Component(扩展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)); 
    }

}

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

}

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

3 个答案:

答案 0 :(得分:2)

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

不要调用您的类Component。该名称已经有一个AWT类,因此您可能会导致Swing停止工作。

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

JFrame的默认布局管理器是BorderLayout。默认情况下,当您向框架添加组件而未指定约束时,它们将转到CENTER。 CENTER只能包含一个组件,因此您只能看到添加的最后一个组件。

而是尝试将一个组件添加到BorderLayout.NORTH,将一个组件添加到SOUTH。

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

@Override
public Dimension getPreferredSize()
{
    return new Dimension(w, h);
}

此外,paintComponent()方法应调用super.paintComonent()

查看Swing tutorial。您应该阅读Custom PaintingLayout Managers上的相关部分以获取更多信息。

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

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

答案 1 :(得分:2)

x / y / w / h值与组件的实际大小无关,可能是0x0,这意味着您将在组件的可见区域外侧绘画。

首先覆盖getPreferredSize方法,然后返回一个允许绘画可见的区域,类似....

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

例如。

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

这意味着您的示例将仅显示添加的最后一个组件。

根据您打算实现的目标,您可以考虑使用OverlayLayout或其他布局管理器。

就个人而言,除非你有特殊需要,否则我不会担心绘画的x / y位置,只需从组件的0x0位置进行绘制,允许容器布局管理器处理实际的位置。

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

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

答案 2 :(得分:0)

只需添加一个LayoutManager就可以给出你正在寻找的两个矩形

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 GridLayout(1, 2));  // I used a simple grid layout.
        this.add(new Component(20,20,20,20)); 
        this.add(new Component(40,30,20,20)); 
   }

   public static void main(String[] args){
       SwingUtlities.invokeLater(new Runnable(){
           public void run(){
               new UI();
           }
       });
   }

}