0

我想在 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)); 
    }

}

文件组件.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);
    }

}

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

4

3 回答 3

2

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

不要调用你的类组件。已经有一个同名的 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 教程。您应该阅读关于Custom PaintingLayout Managers了解更多信息的部分。

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

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

于 2013-11-13T20:04:54.040 回答
2

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

首先覆盖该getPreferredSize方法并返回一个允许您绘画可见的区域,例如....

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

例如。

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

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

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

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

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

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

于 2013-11-13T20:05:30.107 回答
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();
           }
       });
   }

}

于 2013-11-13T20:07:09.877 回答