用Java创建一个简单的自定义JComponent



我想开始为工作中的项目构建我自己的定制JComponent。下面我有一个简单的例子,应该在屏幕上创建一个球。(我在网上找到了大部分)但它确实提供了一个不错的起点。我的问题是为什么这个代码不显示球在我的形式?我做错了什么?

还有,应该为自定义JComponent提供哪些基本方法?

代码:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.GridBagLayout;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class testBall {
    public static void main(String[] args) {
        new testBall();
    }
    public testBall() {
        JPanel testPane = new JPanel();
        testPane.setBackground(Color.white);
        testPane.setLayout(new GridBagLayout());
        testPane.add(new MyBall(30,30,10));
        JFrame frame = new JFrame("Testing");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLayout(new BorderLayout());
        frame.add(testPane);
        frame.pack();
        frame.setSize(500, 300); 
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}
class MyBall extends JComponent
{
    private static final long serialVersionUID = 1L;
    public MyBall() { }
    public MyBall(int x, int y, int diameter)
    {
        super();
        this.setLocation(x, y);
        this.setSize(diameter, diameter);
    }
    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        g.setColor(Color.red);
        g.fillOval(0, 0, 100, 100);
    }
}

在哪里我可以找到一个列表的所有方法,应该在一个JComponent类重写?(我知道总有一些应该包含在JComponent中。)

如果我在一个类中创建了这个组件的实例,并且需要改变圆圈的颜色,我会从那个类中调用repaint()方法吗?

您正在将MyBall添加到testPane(其中具有GridBagLayout),而没有指定任何约束。(也就是说,对add()的调用没有第二个参数。)默认约束很可能不是您想要的。尝试在测试窗格中使用BorderLayout,因为它使用BorderLayout.CENTER作为默认值,这在您的情况下可能是合理的:

testPane.setLayout(new BorderLayout());

这使得球为我显示。

关于你的第二个问题,我认为你的类很好。你想要实现的主要方法是paintComponent()。有时需要重写get min/max/preferred size方法,但这实际上取决于您希望组件做什么。JComponent不是抽象的,所以你不必覆盖任何东西,如果你不想。它提供了大量开箱即用的功能,如键盘焦点、可插拔的外观和感觉、可访问性等。只要你不想改变这些东西,就保持原样。实现paintComponent()和各种get*Size()方法并完成它。(您只需要在JavaDoc中挑选方法,看看哪些适合重写。)

另一个选择是扩展JComponent的子类,如果有一个类做类似于你想做的事情。例如,JPanel通常是实现自己的容器的一个很好的起点。

你可能在寻找比"视情况而定"更具体的东西,但是现在,如果你想要画一个球,那么只需覆盖处理JComponent (paintCompentent()get*Size()方法)渲染的方法。

作为旁注,您确实应该使用SwingUtilities.invokeLater()在Swing线程上创建您的Swing组件。

请参阅http://docs.oracle.com/javase/6/docs/api/javax/swing/package-summary.html的"Swing的线程策略"一节。

对java类做了一些调整,我所做的唯一改变是将新的MyBall直接添加到JFrame的内容窗格中,试着运行这个,你会在JFrame

上看到一个红色圆圈
public class TestBall {
    public static void main(String[] args) {
        new TestBall();
    }
    public TestBall() {
        JFrame frame = new JFrame("Testing");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLayout(new BorderLayout());
        frame.getContentPane().add(new MyBall(30,30,10));
        frame.pack();
        frame.setSize(500, 300);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}
class MyBall extends JComponent
{
    private static final long serialVersionUID = 1L;
    public MyBall() { }
    public MyBall(int x, int y, int diameter)
    {
        super();
        this.setLocation(x, y);
        this.setSize(diameter, diameter);
    }
    @Override
    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        g.setColor(Color.red);
        g.fillOval(0, 0, 100, 100);
    }
}

构造函数:我们只是将位置设置为通过构造函数参数传递的点。这就是这个组件的位置。同样的方法我们设置大小(width x height)

paintComponent:这里我们只是在传递的图形对象上画一个椭圆形。

另一部分只是测试,它显示组件是否被正确创建和显示。

最新更新