我想编写一个应用程序,使您可以在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,否则它会很高):

java - 在JPanel的一侧绘制-LMLPHP

红色部分是您的DrawCircle面板。

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

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


这将使您的JPanel返回一半大小,widthheight作为参数传递给构造函数,并且您的类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) {
    }
}


输出将是这样的:

java - 在JPanel的一侧绘制-LMLPHP


当我使用container.add(new DrawCircle)时,它可以(在整个框架上)工作


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

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

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

这些更改是:


WIDTHHEIGHT属性创建最终常量。
JPanel布局删除不必要的BorderLayout,因为默认情况下JFrame已经具有此布局,所以我只是在其中添加了DrawClass
DrawCircle面板绘制边框(因为您不希望按照previous question中的说明在JFrame的左右两部分之间进行划分),只需删除它即可(建议您离开在进行测试时将其放在此处,以便您知道左侧面板的末端和右侧面板的起始位置。
WIDTH / 2HEIGHT作为参数传递给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()例如,因为方法名称应作为动词作为类名

08-27 20:09