我想编写一个应用程序,使您可以在JFrame
的左侧单击鼠标来绘制圆,所有点都在右侧“镜像”。我遇到的第一个问题是,当我尝试在框架中实现此绘制机制时,没有出现圆。
public class Application{
int x,y;
private JPanel container;
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new Application().gui();
}
});
}
public void gui()
{
int height = 250;
int width = 700;
JFrame jframe = new JFrame();
container = new JPanel();
container.setLayout(new BorderLayout());
container.add(new DrawCircle(), BorderLayout.WEST);
container.setVisible(true);
jframe.add(container);
//jframe.add(new DrawCircle());
jframe.setSize(500,700);
jframe.setVisible(true);
jframe.setTitle("Title");
jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jframe.setResizable(false);
}
}
当我使用
container.add(new DrawCircle)
时,它可以(在整个框架上)起作用,但是如果我想添加约束,则不会。这是圈子类:
public class DrawCircle extends JPanel implements MouseListener
{
ArrayList<Point> p = new ArrayList<Point>();
public DrawCircle()
{
addMouseListener(this);
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
for(Point point : p)
{
g.fillOval(point.x,point.y,30,30);
}
}
@Override
public void mouseClicked(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mousePressed(MouseEvent e) {
p.add(new Point(e.getY(), e.getX()));
}
@Override
public void mouseReleased(MouseEvent e) {
}
@Override
public void mouseDragged(MouseEvent e) {
}
@Override
public void mouseMoved(MouseEvent arg0) {
}
}
最佳答案
让我们来解决您的问题:
我遇到的第一个问题是,当我尝试在框架中实现此绘制机制时,没有出现圆。
这是因为每次单击JPanel#revalidate()
类中的某个位置时,您都忘记了调用JPanel#repaint()
和DrawCircle
。
因此,您可以将mousePressed()
方法更改为:
@Override
public void mousePressed(MouseEvent e) {
p.add(new Point(e.getX(), e.getY()));
revalidate();
repaint();
}
请注意,我还更改了
e.getX()
和e.getY()
调用,因为它们放在错误的位置(除非您希望这样)。这将使您的圈子出现,但是您的
DrawCircle
确实很细(我将此图像的JFrame
高度更改为200,否则它会很高):红色部分是您的
DrawCircle
面板。要解决此问题,您需要覆盖其
getPreferredSize()
方法:@Override
public Dimension getPreferredSize() {
return new Dimension(width, height);
}
这将使您的
JPanel
返回一半大小,width
和height
作为参数传递给构造函数,并且您的类DrawCircle
现在应如下所示:class DrawCircle extends JPanel implements MouseListener {
ArrayList<Point> p = new ArrayList<Point>();
int width = 0;
int height = 0;
public DrawCircle(int width, int height) {
this.width = width;
this.height = height;
addMouseListener(this);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(width, height);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
for (Point point : p) {
g.fillOval(point.x, point.y, 30, 30);
}
}
@Override
public void mouseClicked(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mousePressed(MouseEvent e) {
p.add(new Point(e.getX(), e.getY()));
revalidate();
repaint();
}
@Override
public void mouseReleased(MouseEvent e) {
}
}
输出将是这样的:
当我使用container.add(new DrawCircle)时,它可以(在整个框架上)工作
这是因为默认情况下,
BorderLayout
默认情况下将元素放置在CENTER
区域上,如果其余方向(NORTH
,SOUTH
等)没有其他内容,则它将占用整个空间。现在让我们继续解决问题:
我还对
Application
类进行了一些更改(在我的情况下,我将其重命名为CustomPaintingInHalfFrame
):这些更改是:
为
WIDTH
和HEIGHT
属性创建最终常量。用
JPanel
布局删除不必要的BorderLayout
,因为默认情况下JFrame
已经具有此布局,所以我只是在其中添加了DrawClass
。为
DrawCircle
面板绘制边框(因为您不希望按照previous question中的说明在JFrame
的左右两部分之间进行划分),只需删除它即可(建议您离开在进行测试时将其放在此处,以便您知道左侧面板的末端和右侧面板的起始位置。将
WIDTH / 2
和HEIGHT
作为参数传递给DrawCircle
构造函数,以便它可以返回正确的Dimension
。因此,我们的类现在应如下所示:
public class CustomPaintingInHalfFrame {
int x, y;
public static final int WIDTH = 500;
public static final int HEIGHT = 200;
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new CustomPaintingInHalfFrame().gui();
}
});
}
@SuppressWarnings("serial")
public void gui() {
JFrame jframe = new JFrame("Title");
DrawCircle dc = new DrawCircle(WIDTH / 2, HEIGHT);
dc.setBorder(BorderFactory.createLineBorder(Color.RED));
jframe.add(dc, BorderLayout.WEST);
jframe.setSize(WIDTH, HEIGHT);
jframe.setVisible(true);
jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jframe.setResizable(false);
}
}
其他提示
我建议您将
DrawCircle
重命名为Circle
或类似的名称。作为convention,类名称应为名词将
gui()
方法重命名为createGui()
例如,因为方法名称应作为动词作为类名