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

时间:2014-05-05 18:54:04

标签: java swing paintcomponent jcomponent preferredsize

我想开始为工作中的项目构建自己的自定义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()方法吗?

3 个答案:

答案 0 :(得分:6)

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

testPane.setLayout(new BorderLayout());

这会让球出现在我身上。

关于你的第二个问题,我认为你的班级很好。您要实现的主要方法是paintComponent()。有时候有必要覆盖get min/max/preferred size方法,但它实际上只取决于你希望组件做什么。 JComponent不是抽象的,所以如果你不想,你不必覆盖任何东西。它提供了开箱即用的 lot 功能,例如键盘焦点,可插拔外观,可访问性等。只要您不想更改任何内容,只是保持原样。实施paintComponent()和各种get*Size()方法并完成它。 (您只需要选择JavaDoc中的方法来查看适合覆盖的内容。)

另一个选项是扩展JComponent的子类,如果有一个类与你想做的类似。例如,JPanel通常是推动自己容器的良好起点。

你可能正在寻找比这更具体的东西,它取决于',但是现在,如果你想要的只是画一个球,那么简单地覆盖处理{{{{{ 1}}(JComponentpaintCompentent()方法)。

作为旁注,你真的应该使用get*Size()在Swing线程上创建Swing组件。请参阅标题为" Swing的线程策略"在http://docs.oracle.com/javase/6/docs/api/javax/swing/package-summary.html

答案 1 :(得分:0)

构造函数:我们只是将位置设置为点,这些点通过构造函数参数传递。这是该组件所在的位置。我们设置尺寸的方式相同(width x height)。

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

另一部分只是测试,它表明组件已正确创建并显示。

答案 2 :(得分:0)

对你的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);
    }
}