简体   繁体   English

按下JButton时,JFrame不添加组件

[英]JFrame does not add component when JButton is pressed

My code is basically about having a frame and it has a button. 我的代码基本上是关于具有框架和按钮的。 You press the button you can draw rectangles, getting coordinates from the mouse press and the mouse release. 按下按钮可以绘制矩形,并通过单击鼠标和释放鼠标来获取坐标。

Now, if you remove the button the code works perfectly, here is the code. 现在,如果您删除按钮,则代码可以正常工作,下面是代码。

//testing file //测试文件

package ActionTest;    
import java.awt.*;
import javax.swing.*;    

public class MouseTest
{
   public static void main(String[] args)
   {
      EventQueue.invokeLater(new Runnable()
         {
            public void run()
            {
               JFrame frame = new MouseFrame();
               frame.setTitle("MouseTest");
               frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
               frame.setVisible(true);
               frame.setSize(500,500);
            }
         });
   }
}

My frame, calls on the mouse component 我的框架,调用鼠标组件

package ActionTest;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;

public class MouseFrame extends JFrame
{           
   public MouseFrame()
   {       
      add(new MouseComponent());                   
   }
}

The component class: handles mouse clicks and drawing the rectangle 组件类:处理鼠标单击并绘制矩形

package ActionTest;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.util.*;
import javax.swing.*;
public class MouseComponent extends JComponent
{    
   Point first;
   Point second;
   private ArrayList<Rectangle2D> rectangles;

   public MouseComponent()
   {
      rectangles = new ArrayList<>();//contains rectangles
      addMouseListener(new MouseHandler());
   }
   //paint method of the component, simply re-paint the array
   public void paintComponent(Graphics g)
   {
      Graphics2D g2 = (Graphics2D) g;
      for (Rectangle2D r : rectangles)
         g2.draw(r);
   }


   /**
    * creates a rectangle and adds it to the rectangles ArrayList
    * then repaint the component
    * inside some operations to deal with rectangle drawing nothing to do with the issue
    * @param p1: first coordinates
    * @param p2: second coordinates
    */
   public void addRec(Point2D p1, Point2D p2)
   {
       double w, h, x, y;
       double x1 = p1.getX();
       double y1 = p1.getY();
       double x2 = p2.getX();
       double y2 = p2.getY();
       if(x1 <= x2){
           x = x1;
           w = x2-x1;        
       }
       else{
           x = x2;
           w = x1-x2;           
       }
       if (y1 <= y2){
           y = y1;
           h = y2-y1;           
       }
       else{
           y = y2;
           h = y1-y2;           
       }
      rectangles.add(new Rectangle2D.Double(x, y, w, h));
      repaint();
   }


   //records mouse click and mose release
   //you press the mouse that is the 1st coordinates
   //you release it that is the 2nd coordinates
   //pass both to the addRec method
   private class MouseHandler extends MouseAdapter
   {
      @Override
      public void mousePressed(MouseEvent event)
      {          
          first = event.getPoint();
      }
      @Override
      public void mouseReleased(MouseEvent event)
      {
          second = event.getPoint();          
          addRec(first, second);
      }
   }
}

It works perfectly. 它运作完美。 However, going back to the original problem, if I add a button, and then when the button pressed go ahead and begin drawing rectangles it doesn't work. 但是,回到原来的问题,如果我添加一个按钮,然后在按下按钮时继续并开始绘制矩形,则无法正常工作。

Here is the modified frame class 这是修改后的框架类

package ActionTest;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;

public class MouseFrame extends JFrame
{    
   private JPanel buttonPanel;
   public MouseFrame()
   {       

       JFrame frame = this;
       buttonPanel = new JPanel();
       JButton rec = new JButton("Rectangle");
       rec.addActionListener(new ActionListener(){        
           public void actionPerformed(ActionEvent event)
           {         
               System.out.println("pressed");                   
               frame.add(new MouseComponent());                
           }});
       buttonPanel.add(rec);
       add(buttonPanel);            
   }
}

Thanks in advance. 提前致谢。

frame.add(new MouseComponent());   

The size of a newly created component is (0, 0) so there is nothing to paint. 新创建的组件的大小为(0,0),因此无需绘制任何内容。 So you need to invoke the layout manager when you add a component to a visible GUI. 因此,当您将组件添加到可见的GUI时,您需要调用布局管理器。

frame.add(new MouseComponent());   
frame.revalidate();
frame.repaint();

Note this will only work if the layout manager allows you to add multiple components to the frame. 请注意,这仅在布局管理器允许您向框架中添加多个组件时才有效。 The default layout manager for a frame is the BorderLayout and only a single components can be added to the CENTER of the BorderLayout. 框架的默认布局管理器是BorderLayout,并且只能将单个组件添加到BorderLayout的CENTER。

So maybe you need to add the button using: 因此,也许您需要使用以下命令添加按钮:

frame.add(button, BorderLayout.PAGE_START);

Read the section from the Swing tutorial on How to Use Layout Managers for more information and working examples. 阅读Swing教程中有关如何使用布局管理器的部分, 获取更多信息和工作示例。

Also, any time you do custom painting you need to override the getPreferredSize() method of the custom component so the layout managers can do their job. 另外, getPreferredSize()进行自定义绘制时,都需要覆盖自定义组件的getPreferredSize()方法,以便布局管理器可以执行其工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM