当前位置: 首页 > 知识库问答 >
问题:

在JPanel的一侧绘制

辛星宇
2023-03-14

我想编写一个应用程序,让你用鼠标点击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);

  } 
}

当我使用容器时,它可以(在整个框架上)工作。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) {
  }
}

共有1个答案

商辰钊
2023-03-14

让我们看看你的问题:

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

这是因为每当您单击DrawCircle类中的某个位置时,您都忘记调用JGroup#revalize()JGroup#repaint()

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

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

注意,我还更改了e。getX()和e。getY()调用,因为它们位于错误的位置(除非您希望这样)。

这会使你的圆圈出现,但是,你的画圈真的很薄(我将这个图像的JFrame高度改为200,否则它会很高):

红色部分是您的绘图圈面板。

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

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

这将使您的JGroup返回一半大小,宽度高度作为参数传递给构造函数,并且您的类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(新的DrawCircle)时,它(在整个框架上)有效

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

现在,让我们继续讨论如何解决您的问题:

我还对应用程序类做了一些更改(在我的例子中,我将其重命名为CustomPaintingInHalfFrame):

这些变化是:

  • WIDTHHEIGHT属性创建最终常量。
  • 使用BorderLayout布局删除不必要的JGroup,因为JFrame默认已经有这个布局,我只是添加了我们的DrawClass到它。
  • DrawCircle面板绘制边框(因为您不希望在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或类似的东西。按照惯例,类名称应该是名词

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

  •  类似资料:
    • 问题内容: 我正在寻找有关如何在JPanel中绘制文本的最基本描述。我知道那里有十亿个教程,但是没有一个在我身边点击,我有一些具体的问题可能会帮助其他困惑的人。作为设置(测试应用程序),我有一个类,其中包含JLabel,JTextField,JButton和JPanel。该应用程序从一个外部文件中读取整数,并且在按下JButton时应在面板中显示其平均值。我已经整理了所有基础编程(即按钮响应并将平

    • 问题内容: 我如何告诉paint方法仅在JPanel上而不是在整个JFrame上绘制背景。我的JFrame大小大于JPanel。当我尝试为JPanel绘制网格背景时,网格似乎遍及整个JFrame,而不仅仅是JPanel。 以下是部分代码: 问题答案: camickr是正确的。所以: 您需要严格将工程图与不同组件分开。Swing已经在管理子组件,因此绝对不需要在Panel的Frame中实现图形(调用

    • 我已经在JScrollPane中放置了一个JPanel对象,滚动工作就像预期的那样。通过重写paintComponent(),我尝试在JPanel对象中进行自定义绘制。然而,当JPanel对象放置在JScrollPane中时,JPanel不再正确地绘制(而是只显示其背景颜色)。 因为我的应用程序要求JPanel不断更新,所以构造了一个单独的线程,以在特定的时间间隔重新绘制JPanel。 以下代码摘

    • 我试图在JPanel中表示一个给定的数学函数,因为现在我只有轴,但是轴没有绘制,我不知道为什么,顺便说一下,如果我在框架中调用< code>new Axis(),它会绘制。 主要类别 轴类 另一个问题:有可能有多种绘画方法吗?

    • 我有一个程序,有多个层次,在底层我有一个JPanel,我把背景图像放在上面。除此之外,我还有一个JLayeredPane,其中包含一些可拖动的组件。我的问题是,当用户上传了背景图像时,可拖动的组件确实滞后了,我猜这是因为swing在拖动时一直在重新绘制背景图像。我的问题是,如果它无论如何,以确保图像没有重新绘制的所有时间?我在其中绘制图像的代码如下所示:

    • 首先,我要说,我几乎可以保证这个问题是一个副本,但我找不到任何其他适合我的需要/在我的程序中工作的答案。我需要画一个,但我似乎无法画出显示所需的线条。 在我的中添加有什么问题吗?