在JPanel的一侧绘制 [英] Draw on one side of a JPanel

查看:71
本文介绍了在JPanel的一侧绘制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想编写一个应用程序,使您可以通过单击JFrame左侧的鼠标来绘制圆,所有点都在右侧镜像".我遇到的第一个问题是,当我尝试在框架中实现此绘制机制时,没有出现圆.

I want to program an application that lets you draw circles with a mouse click on the left side of a JFrame, and all the points are getting "mirrored" to the right side. The first problem I encountered was that when I try to implement this draw-mechanic in my frame, no circles appear.

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)时,它可以(在整个框架上)起作用,但是如果我想添加约束,则不会.

It works (on the whole frame) when I use container.add(new DrawCircle) but if I want to add constraints, it doesn't.

这是圈子类别:

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) {
  }
}

推荐答案

让我们来解决您的问题:

Let's go through your problems:

我遇到的第一个问题是,当我尝试在框架中实现此绘制机制时,没有圆圈出现.

The first problem I encountered was that when I try to implement this draw-mechanic in my frame, no circles appear.

这是因为您忘记调用

This is because you forgot to call JPanel#revalidate() and JPanel#repaint() whenever you click somewhere in the DrawCircle class.

因此,您可以将mousePressed()方法更改为:

So, you could change your mousePressed() method to:

@Override
public void mousePressed(MouseEvent e) {
    p.add(new Point(e.getX(), e.getY()));
    revalidate();
    repaint();
}

请注意,我还更改了e.getX()e.getY()调用,因为它们放置在错误的位置(除非您这样想).

Note that I also changed the e.getX() and e.getY() calls, because they were on the wrong places (unless you want them that way).

这将使您的圆圈出现,但是您的DrawCircle确实很细(我将此图像的JFrame的高度更改为200,否则它会很高):

That will make your circles to appear, but, your DrawCircle is really thin (I changed the height of your JFrame to 200 for this image, otherwise it would be really tall):

红色部分是您的DrawCircle面板.

要解决此问题,您需要覆盖其getPreferredSize()方法:

To fix this you need to override its getPreferredSize() method:

@Override
public Dimension getPreferredSize() {
    return new Dimension(width, height);
}

这将使您的JPanel返回一半大小,widthheight作为参数传递给构造函数,并且您的类DrawCircle现在应如下所示:

That will make your JPanel to return half the size, width and height were passed as parameters to the constructor, and your class DrawCircle should now look like this:

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)时,它可以(在整个框架上)工作

It works (on the whole frame) when I use container.add(new DrawCircle)

这是因为默认情况下BorderLayout默认情况下会将元素放置在CENTER区域上,并且如果其余方向(NORTHSOUTH等)没有其他内容,则它将占用整个空间

That's because by default BorderLayout places by default the elements on the CENTER region, and if you have nothing else in the rest of orientations (NORTH, SOUTH, etc) it will take the whole space.

现在让我们继续解决问题:

Now let's continue with how to solve your problem:

我还对Application类进行了一些更改(在我的情况下,我将其重命名为CustomPaintingInHalfFrame):

I also made some changes to the Application class (which in my case I renamed to CustomPaintingInHalfFrame):

这些更改是:

  • Create final constants for the WIDTH and HEIGHT attributes.
  • Removal of unnecessary JPanel with BorderLayout layout, as JFrame already has this layout by default, I simply added our DrawClass to it.
  • Drawing of a border for the DrawCircle panel (as you don't want a division between both (left and right) parts of your JFrame as stated in your previous question you can simply remove it (I recommend you to leave it there while you're testing so you know where left panel ends and right panel starts.
  • Passing WIDTH / 2 and HEIGHT as parameters for DrawCircle constructor, so it can return the correct Dimension.

因此,我们的类现在应如下所示:

So, our class should now look like this:

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);

    }
}


其他提示

  1. 我建议您将DrawCircle重命名为Circle或类似的名称.作为常规名称应是名词

  1. I recommend you to rename your DrawCircle to Circle or something like that. As a convention, Classes names should be nouns

gui()方法重命名为createGui(),例如,因为作为类名,方法名称应为动词

Rename gui() method to createGui() for example because, as Classes names, method names should be verbs

这篇关于在JPanel的一侧绘制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆