我一直在尝试解决此错误,但我似乎无法弄清楚出了什么问题。我想编写一个程序,提示用户输入x和
中心的y位置和半径。当用户单击“绘图”时
按钮,在组件中绘制一个具有该中心和半径的圆。
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class CircleMakerVeiwer {
public static void main(String[] args) {
// stuff that displays that will help display the circle
JPanel panel = new JPanel();
JPanel pane2 = new JPanel();
JFrame frame = new JFrame();
JButton button = new JButton("Draw Circle");
// the obj that will be drawn
CircleMaker circle = new CircleMaker();
// panel is set to a flowLayout
panel.setLayout(new FlowLayout());
// panel's size is selected
panel.setPreferredSize(new Dimension(800, 800));
// now here's where the fun begins
// labels
JLabel x_cor = new JLabel("X Cordinate");
JLabel y_cor = new JLabel("Y Cordinate");
JLabel rad = new JLabel("Radius");
// JTextFeilds
JTextField x_input = new JTextField(3);
JTextField y_input = new JTextField(3);
// [in surfer dude voice] It's so RADDDD bROOOo
JTextField rad_input = new JTextField(3);
// all de panel adding
panel.add(x_cor);
panel.add(x_input);
panel.add(y_cor);
panel.add(y_input);
panel.add(rad);
panel.add(rad_input);
// time for the action listener
class DrawCircleListener implements ActionListener {
public void actionPerformed(ActionEvent arg0) {
int x, y, r;
System.out.println("action preformed (sort of)");
x = Integer.parseInt(x_input.getText());
y = Integer.parseInt(y_input.getText());
r = Integer.parseInt(rad_input.getText());
circle.setCircle(r, x, y);
}// end of actionPerformed
}// end of DrawCircleListener
DrawCircleListener listener = new DrawCircleListener();
button.addActionListener(listener);
panel.add(button);
panel.add(circle);
frame.setSize(800, 800);
frame.setTitle("Circle Button");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(panel);
frame.setVisible(true);
}// end of main
}// end of CircleMakerVeiwer.java
我还将提供CircleMaker对象,以防万一。
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Ellipse2D;
import javax.swing.JComponent;
/*
* This program will construct a circle it will also
* paint and set the parameters of the circle outside the constructor
*/
public class CircleMaker extends JComponent {
private Ellipse2D.Double c;
private int radius, x_cor, y_cor;
public CircleMaker() {
c= new Ellipse2D.Double();
}
public void setCircle(int r, int x_cordinate, int y_cordinate) {
//Graphics g;
c = new Ellipse2D.Double(x_cordinate - r, y_cordinate - r, r * 2, r * 2);
System.out.println("set circle was called");
//repaint();
}
public void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
g2.draw(c);
}
}
最佳答案
您正在将CircleMaker
添加到使用JPanel
的FlowLayout
中,该preferredSize
支持组件的CircleMaker
,但是preferredSize
的默认0x0
是repaint
,因此该组件实际上是不可见的
调用setCircle
时不调用super.paintComponent
,因此该组件不知道应对其进行更新
您在进行自定义绘画之前未调用getPreferredSize
,从而违反了绘画方法链协定
首先覆盖CircleMaker
的setCircle
方法...
public static class CircleMaker extends JComponent {
//...
@Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
这将为布局管理器提供一些关于您希望组件多大的想法
更新
repaint
方法以调用super.paintComponent
并将paintComponent
添加到您的CircleMaker
方法中 public void setCircle(int r, int x_cordinate, int y_cordinate) {
//Graphics g;
c = new Ellipse2D.Double(x_cordinate - r, y_cordinate - r, r * 2, r * 2);
System.out.println("set circle was called");
repaint();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.draw(c);
}
最后,将
CENTER
的实例添加到框架的BorderLayout
位置,默认情况下使用panel.setPreferredSize(new Dimension(800, 800));
... //panel.add(circle);
frame.setTitle("Circle Button");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(panel, BorderLayout.NORTH);
frame.add(circle);
frame.pack();
frame.setVisible(true);
哦,摆脱