Java - 单击按钮后绘制圆圈
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19367440/
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
Java - draw circle after clicking button
提问by tblizzard
I am trying to draw a circle with the press of a button in java. I put the System.out.println() inside the action method to make sure my code was working. The println shows up but no circle drawing anywhere. Any Suggestions? Thank you
我试图在java中按下一个按钮来画一个圆圈。我将 System.out.println() 放在 action 方法中以确保我的代码正常工作。println 出现但没有在任何地方绘制圆圈。有什么建议?谢谢
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
public class CircleViewer {
public static void main(String[] args)
{
CircleComponent circle = new CircleComponent();
JButton button = new JButton("Draw");
final JPanel panel = new JPanel();
panel.add(button);
JFrame frame = new JFrame();
class addActionListener implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
CircleComponent component = new CircleComponent();
String x = JOptionPane.showInputDialog("X Coordinate", "Enter an x coordinate");
int xCoord = Integer.parseInt(x);
String y = JOptionPane.showInputDialog("Y Coordinate", "Enter a y coordinate");
int yCoord = Integer.parseInt(y);
String width = JOptionPane.showInputDialog("Radius", "Enter the length of the radius");
int radius = Integer.parseInt(width);
component.setLocation(xCoord,yCoord);
component.getWidth(radius);
panel.add(component);
System.out.println("CLICKED!");
}
}
frame.add(panel);
ActionListener action = new addActionListener();
button.addActionListener(action);
frame.setSize(500, 500);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Ellipse2D;
import javax.swing.JButton;
import javax.swing.JFrame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JPanel;
import javax.swing.JOptionPane;
/**
This component lets the user draw a circle by clicking
a button.
*/
public class CircleComponent extends JPanel
{
private int x;
private int y;
private int width;
Ellipse2D.Double circle;
public CircleComponent()
{
circle = new Ellipse2D.Double(x, y, width, width);
}
public Dimension getPreferredSize()
{
return new Dimension(500,500);
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.draw(circle);
}
public int getWidth(int aWidth)
{
width = aWidth;
return width;
}
}
回答by camickr
You need to override the getPreferredSize()
method of you custom component. By default the size is (0, 0) so there is nothing to paint.
您需要覆盖getPreferredSize()
自定义组件的方法。默认情况下,大小是 (0, 0) 所以没有什么可绘制的。
The revalidate() should be done on the panel, not the component.
revalidate() 应该在面板上完成,而不是在组件上。
Your getX() and getY() methods make no sense. If you want to position the component on the panel you should be using the setLocation(...) method of the component.
你的 getX() 和 getY() 方法没有意义。如果你想在面板上定位组件,你应该使用组件的 setLocation(...) 方法。
Edit:
编辑:
There are still lots of probolems. I'll try to explain them and then give a better (still not a great) example of how you might do this.
仍然有很多问题。我将尝试解释它们,然后给出一个更好的(仍然不是一个很好的)示例来说明您如何做到这一点。
circle = new Ellipse2D.Double(x, y, width, width);
When you create the circle shape all the parameters have a value of 0 so there is nothing to paint. You can't just change the values of the variables x, y and width later and expect the circle to reflect those values.
The size of the component is wrong. You can't just make an arbitrary size of 500 x 500. The preferred size should be the size of the circle.
You can't just add the component to the panel because the panel uses a FlowLayout by default. This means the setLocation() method will be ignored. I changed your code to use a null layout. This means that the location you specify will now be used and you must also specify the size of the component.
I changed your code to use an "anonymous inner class" for the ActonListener. This is more common then defining a class in the middle of another class.
创建圆形时,所有参数的值都为 0,因此无需绘制任何内容。您不能只是稍后更改变量 x、y 和 width 的值并期望圆圈反映这些值。
组件的大小错误。您不能随意制作 500 x 500 的任意大小。首选大小应该是圆圈的大小。
您不能只将组件添加到面板,因为面板默认使用 FlowLayout。这意味着 setLocation() 方法将被忽略。我将您的代码更改为使用空布局。这意味着现在将使用您指定的位置,并且您还必须指定组件的大小。
我将您的代码更改为对 ActonListener 使用“匿名内部类”。这比在另一个类的中间定义一个类更常见。
Here is the quick example:
这是快速示例:
import java.awt.event.*;
import java.awt.geom.*;
import javax.swing.*;
import java.awt.*;
public class CircleComponent extends JPanel
{
Ellipse2D.Double circle;
public CircleComponent(int radius)
{
circle = new Ellipse2D.Double(0, 0, radius, radius);
setOpaque(false);
}
public Dimension getPreferredSize()
{
Rectangle bounds = circle.getBounds();
return new Dimension(bounds.width, bounds.height);
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setColor( getForeground() );
g2.fill(circle);
}
/*
public int getWidth(int aWidth)
{
width = aWidth;
return width;
}
*/
public static void main(String[] args)
{
// Create a panel using a null layout so we can add components at random positions
final JPanel center = new JPanel();
center.setLayout(null);
JButton button = new JButton("Draw");
button.addActionListener( new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
String x = JOptionPane.showInputDialog("X Coordinate", "Enter an x coordinate");
int xCoord = Integer.parseInt(x);
String y = JOptionPane.showInputDialog("Y Coordinate", "Enter a y coordinate");
int yCoord = Integer.parseInt(y);
String width = JOptionPane.showInputDialog("Radius", "Enter the length of the radius");
int radius = Integer.parseInt(width);
CircleComponent component = new CircleComponent(radius);
component.setLocation(xCoord,yCoord);
component.setSize(component.getPreferredSize());
center.add(component);
center.repaint();
}
});
JFrame frame = new JFrame();
frame.add(center, BorderLayout.CENTER);
frame.add(button, BorderLayout.NORTH);
frame.setSize(500, 500);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}