按下JButton时,JFrame不添加组件

时间:2016-04-25 17:21:21

标签: java swing jframe jpanel jbutton

我的代码基本上是关于拥有一个框架,它有一个按钮。按下按钮可以绘制矩形,从鼠标按下和鼠标释放获取坐标。

现在,如果您删除按钮,代码可以正常工作,这里是代码。

//测试文件

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

我的框架,调用鼠标组件

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

组件类:处理鼠标点击并绘制矩形

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

完美无缺。但是,回到原来的问题,如果我添加一个按钮,然后当按下按钮继续并开始绘制矩形时,它就不起作用。

这是修改后的框架类

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

提前致谢。

1 个答案:

答案 0 :(得分:2)

frame.add(new MouseComponent());   

新创建的组件的大小为(0,0),因此无需绘制任何内容。因此,在将组件添加到可见GUI时需要调用布局管理器。

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

请注意,这仅适用于布局管理器允许您向框架添加多个组件的情况。框架的默认布局管理器是BorderLayout,只有一个组件可以添加到BorderLayout的CENTER中。

所以也许您需要使用以下方式添加按钮:

frame.add(button, BorderLayout.PAGE_START);

阅读How to Use Layout Managers上Swing教程中的部分,了解更多信息和工作示例。

此外,每次进行自定义绘制时,都需要覆盖自定义组件的getPreferredSize()方法,以便布局管理器完成其工作。