在 Java 中创建一个简单的自定义 JComponent?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23479666/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Creating a simple custom JComponent in Java?
提问by
I want to start building my own customized JComponent's for a project at work. I have a simple example below that should just create a ball on the screen. (I found most of it on the internet) but it does provide a decent starting point. My question is why does this code not show the ball in my form? What have I done wrong?
我想开始为工作中的项目构建我自己的自定义 JComponent。我下面有一个简单的例子,它应该只是在屏幕上创建一个球。(我在互联网上找到了大部分内容)但它确实提供了一个不错的起点。我的问题是为什么这段代码没有在我的表格中显示球?我做错了什么?
Also what would be all of the basic methods that SHOULD be provided for a custom JComponent?
此外,应该为自定义 JComponent 提供的所有基本方法是什么?
Code:
代码:
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);
}
}
Where I could find a list of all of the methods that should be overridden in a JComponent class? (I know there are ones that should always be included in JComponent.)
我在哪里可以找到应该在 JComponent 类中覆盖的所有方法的列表?(我知道有些应该始终包含在 JComponent 中。)
If I make an instance of this component in a class and need to change the color of the circle would I just call there repaint()
method from that class?
如果我在类中创建此组件的实例并需要更改圆圈的颜色,我是否只需repaint()
从该类中调用该方法?
回答by matt forsythe
You are adding the MyBall
to testPane
(which has a GridBagLayout
) without specifying any constraints. (That is, your call to add()
has no second parameter.) The default constraints are most likely not what you want. Try using BorderLayout
for your test pane, as this uses BorderLayout.CENTER
as the default, which is probably reasonable in your case:
您在不指定任何约束的情况下添加MyBall
to testPane
(有一个GridBagLayout
)。(也就是说,您对 的调用add()
没有第二个参数。)默认约束很可能不是您想要的。尝试BorderLayout
用于您的测试窗格,因为它BorderLayout.CENTER
用作默认值,这在您的情况下可能是合理的:
testPane.setLayout(new BorderLayout());
This causes the ball to show up for me.
这导致球出现在我面前。
As for your second question, I think your class is fine as defined. The main method you want to implement is paintComponent()
as you have. Sometimes it becomes necessary to override the get min/max/preferred size
methods, but it really just depends on what you want the component to do. JComponent
is not abstract, so you don't have to override anything if you don't want to. It provides a lotof functionality out of the box such as keyboard focus, pluggable look-and-feel, accessibility, etc. As long as you don't want to change any of that stuff, just leave it as is. Implement paintComponent()
and the various get*Size()
methods and be done with it. (You just kind of have to pick through the methods in the JavaDoc to see what is appropriate to override.)
至于你的第二个问题,我认为你的课没问题。您要实现的主要方法就是paintComponent()
您所拥有的。有时有必要覆盖这些get min/max/preferred size
方法,但这实际上只取决于您希望组件做什么。 JComponent
不是抽象的,所以如果你不想,你不必覆盖任何东西。它提供了许多开箱即用的功能,例如键盘焦点、可插入的外观和感觉、可访问性等。只要您不想更改任何这些东西,就保持原样。实现paintComponent()
和各种get*Size()
方法并用它来完成。(您只需选择 JavaDoc 中的方法即可查看适合覆盖的内容。)
The other option is to extend a subclass of JComponent
, if there as a class that does something similar to what you want to do. For example, JPanel
is often a good starting point for impelmenting your own container.
另一种选择是扩展 的子类JComponent
,如果有一个类做类似于你想做的事情。例如,JPanel
通常是实现您自己的容器的良好起点。
You were probably looking for something more concrete than 'it depends', but right now, if all you want is to draw a ball, then simply override the methods that deal with the rendering of the JComponent
(paintCompentent()
, and the get*Size()
methods).
您可能正在寻找比“视情况而定”更具体的东西,但是现在,如果您只想绘制一个球,那么只需覆盖处理JComponent
(paintCompentent()
和get*Size()
方法)渲染的方法。
As a side note, you really should be using SwingUtilities.invokeLater()
to create your Swing components on the Swing thread. See the section entitled "Swing's Threading Policy" at http://docs.oracle.com/javase/6/docs/api/javax/swing/package-summary.html.
作为旁注,您确实应该使用SwingUtilities.invokeLater()
在 Swing 线程上创建 Swing 组件。请参阅http://docs.oracle.com/javase/6/docs/api/javax/swing/package-summary.html 上标题为“Swing 的线程策略”的部分。
回答by Dmitry Ginzburg
Constructor: we just set location to the points, which are passed throught constuctor parameters. This is the place, in which this component will be located. The same way we set the size (width
x height
).
构造函数:我们只是将位置设置为通过构造函数参数传递的点。这是该组件所在的位置。与我们设置大小 ( width
x height
) 的方式相同。
paintComponent: here we just paint some oval over passed graphics object.
PaintComponent:这里我们只是在传递的图形对象上绘制一些椭圆形。
The other part is just the test, which shows, that the component is correctly created and shown.
另一部分只是测试,它表明组件已正确创建和显示。
回答by rahul pasricha
Made some tweaks around your java class, the only change i did was add your new MyBall directly to the content pane of the JFrame, try to run this and you will see a red circle on your jframe
对 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);
}
}