有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

按下JButton时,javajframe不会添加组件

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

现在,如果你移除这个按钮,代码可以正常工作,下面是代码

//测试文件

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

component类:处理鼠标单击和绘制矩形

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

它工作得很好。然而,回到原来的问题,如果我添加一个按钮,然后当按下按钮时,继续绘制矩形,它就不起作用了

下面是修改后的frame类

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) 个答案

  1. # 1 楼答案

    frame.add(new MouseComponent());   
    

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

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

    注意:仅当布局管理器允许您向框架添加多个组件时,此操作才有效。框架的默认布局管理器是BorderLayout,只能将单个构件添加到BorderLayout的中心

    因此,您可能需要使用以下方法添加按钮:

    frame.add(button, BorderLayout.PAGE_START);
    

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

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