当前位置: 首页 > 面试题库 >

为什么repaint()之后不会显示正方形?

董畅
2023-03-14
问题内容

我早些时候发布了这个问题,并被告知将其设为SSCCE(如果我可以进行任何改进,随时告诉我):我想知道为什么当单击我的按钮“确认”时,旧方块消失了,重新绘制的方块不会出现在我的GUI(使用摆动制作)上。Squares类绘制200个间隔开的正方形,其中的ID(从String,0、1、2或3作为字符串)从另一个类获得(出于这个问题的目的,我们假设它始终为0,不包括该类)。为了澄清:Squares第一次可以完美地绘制所有内容(还可以检索正确的ID),但是我希望它在单击带有新ID的按钮后能够重新绘制所有内容。正方形代码:

import javax.swing.*;
import java.awt.*;
import java.awt.geom.*;
import java.util.ArrayList;

public class Squares extends JPanel{

private ArrayList<Rectangle> squares = new ArrayList<Rectangle>();
private String stringID = "0";

public void addSquare(int x, int y, int width, int height, int ID) {
      Rectangle rect = new Rectangle(x, y, width, height);
      squares.add(rect);
      stringID = Integer.toString(ID);
      if(ID == 0){
          stringID = "";
      }
}

   @Override
   protected void paintComponent(Graphics g) {

  super.paintComponent(g);
  Graphics2D g2 = (Graphics2D) g;
  FontMetrics fm = g2.getFontMetrics();
  int fontAscent = fm.getAscent();
  g2.setClip(new Rectangle(0,0,Integer.MAX_VALUE,Integer.MAX_VALUE));
  for (Rectangle rect : squares) {
     g2.drawString(stringID, rect.x + 7, rect.y + 2 + fontAscent);
     g2.draw(rect);
  }
 }
}

GUI代码:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class GUIReserver extends JFrame implements Runnable{

private int myID;
private JButton confirm = new JButton("Check Availability and Confirm Reservation");    
private JFrame GUI = new JFrame();
private Squares square;

public GUIReserver(int i) {
    this.myID = i;
}

@Override
public void run() {
    int rows = 50;
    int seatsInRow = 4;
    confirm.addActionListener(new ActionListener() {
        @Override
         public void actionPerformed(ActionEvent evt) {
                GUI.getContentPane().remove(square);
                square = new Squares();
                int spaceNum = 0;
                int rowNum = 0;
                int offsetX = 200;
                int offsetY = 0;
                for(int i = 0; i < rows * seatsInRow; i++){
                    square.addSquare(rowNum * 31 + offsetX,spaceNum * 21 + 50 + offsetY,20,20, 0); //normally the 4th parameter here would retrieve the ID from the main class
                    rowNum++;
                    if(rowNum == 10){
                        rowNum = 0;
                        spaceNum++;
                    }
                    if(spaceNum == 2){
                        spaceNum = 3;
                        rowNum = 0;
                    }
                    if(spaceNum == 5){
                        spaceNum = 0;
                        offsetY += 140;
                    }
                }
                GUI.getContentPane().add(square); //this does not show up at all (could be that it wasn't drawn, could be that it is out of view etc...)
                GUI.repaint(); //the line in question
         }          
    });
    GUI.setLayout(new FlowLayout());
    GUI.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    GUI.setLocation(0,0);
    GUI.setExtendedState(JFrame.MAXIMIZED_BOTH);
    square = new Squares();
    int spaceNum = 0;
    int rowNum = 0;
    int offsetX = 200;
    int offsetY = 0;
    for(int i = 0; i < rows * seatsInRow; i++){
        square.addSquare(rowNum * 31 + offsetX,spaceNum * 21 + 50 + offsetY,20,20, 0); //normally the 4th parameter here would retrieve the ID from the main class
        rowNum++;
        if(rowNum == 10){
            rowNum = 0;
            spaceNum++;
        }
        if(spaceNum == 2){
            spaceNum = 3;
            rowNum = 0;
        }
        if(spaceNum == 5){
            spaceNum = 0;
            offsetY += 140;
        }
    }
    GUI.getContentPane().add(square); //this shows up the way I wish
    GUI.add(confirm);
    GUI.pack();
    GUI.setVisible(true);
}
}

主要代码

public class AircraftSeatReservation {

static AircraftSeatReservation me = new AircraftSeatReservation();
private final int rows = 50;
private final int seatsInRow = 4;
private int seatsAvailable = rows * seatsInRow;
private Thread t3;

public static void main(String[] args) {
    GUIReserver GR1 = new GUIReserver(3);
    me.t3 = new Thread(GR1);
    me.t3.start();
}
}

问题答案:

一个主要问题:Squares JPanels的首选大小仅为20 x
20,实际上可能是该大小,因为它似乎已添加到使用FlowLayout的容器中。接下来,您似乎在远远超出此组件范围的位置进行绘制,因此可能永远看不到这些图形。考虑允许Squares对象更大,并确保仅在此组件的边界内绘制。

注意,还有一些没有意义的代码,包括:

private int myID;
private JTextField row, column, instru draft saved // ???
package question2;ction1, instruction2, seatLabel, rowLabel; // ???

我猜是

private int myID;
private JTextField row, column, instruction1, instruction2, seatLabel, rowLabel;

这不会为我们编译

int rows = AircraftSeatReservation.getRows();
int seatsInRow = AircraftSeatReservation.getSeatsInRow(); // and shouldn't this take an int row parameter?

因为我们没有您的AircraftSeatReservation类(希望您在该类中确实没有静态方法)。

而且我们无法编译或运行您的当前代码。我们不希望看到您的整个程序,而是您应该将代码压缩为仍可编译的最小位,没有与您的问题无关的多余代码,但仍然可以演示您的问题。因此,如安德鲁·汤普森(Andrew
Thompson)所建议,为了获得更好的帮助,请创建并发布您的“
最小,完整且可验证”示例或“
简短,自包含,正确的示例”。

我将尝试尽可能地OOP化您的问题,以便您分而治之。这可能涉及:

  • 创建一个SeatClass枚举,其中一个可能包含两个元素:FIRST和COACH。
  • 创建一个非GUI Seat类,其中包含多个字段,可能包括:int行,char座位(例如A,B,C,D,E,F),SeatClass字段,以查看它是头等舱座位还是教练,以及一个布尔值保留字段,仅当保留座位时才为true。
  • 此类还将具有getId()方法,该方法返回行号和位子char的String串联。
  • 创建一个非GUI Airplane类,其中一个类包含两个席位数组,一个用于SeatClass.FIRST或头等舱座位,一个用于SeatClass.COACH。
  • 它还将具有一个行数字段和一个座位数(列数)字段。
  • 创建所有这些之后,然后在您的GUI类上工作。
  • 我将为Seats创建一个GUI类,也许是GuiSeat,使其包含一个Seat对象,或者使其扩展JPanel,使其显示从包含的Seat对象获取的自己的id字符串,对其进行覆盖getBackground(...)以使其具有颜色将取决于座位是否预留。
  • 等等.....


 类似资料:
  • 问题内容: 我想在地图上显示许多不同的标签,所以我在面板中使用空布局,并为每个标签调用setLocation。但是由于某种原因,标签没有显示。如果删除pan.setLayout(null),则标签将出现在面板的顶部中央。为什么null布局不能与setPosition一起使用? 问题答案: 这是绝对定位(或布局)的问题。它要求您设置所有组件的大小,否则它们将保留为默认的零大小,并且不会显示。这就是为

  • 我在中使用带有4.1版本模拟器的android最新版本sdk。一切都很好。但是在我的中,对于任何应用程序的每次运行,我都会得到以下语句。 即使在Hello world应用程序中,我也得到相同的logcat输出。我没有在我的应用程序中使用多线程。有人能告诉我为什么在我的logcat中得到这些日志。 这是我的密码 在我的异步任务中,我从服务器获取JSONArray,解析它并列出。

  • 我试图使一个客户端-服务器包成一个应用程序。因此,当应用程序打开时,服务器会自动进入待机/监听模式。问题是当运行服务器套接字时,它直到之后才显示gui。我希望gui和服务器套接字同时发生。 我已经注释掉了代码行,它按照预期工作,直到 我读过关于线程来解决这个问题的文章,但是我看到的例子都没有给出足够清晰的答案。我对python和编程还是相当陌生的。谢啦

  • 我使用以下代码进行我的主要活动: 用户应该能够在对话框中输入值,并且名称将显示在创建的行程列表中。但是,当列表中只有一个值时,似乎存在一个bug,因为该项未显示。我花了好几个小时都弄不明白。 公共类TripsData{

  • 我使用fiddler监控一个简单的html内容从一个PHP文件运行在localhost。但是每当我按f5刷新页面(浏览器)时,在fiddler中有时整个web会话的字体变成蓝色,即当它实际显示内容(html)时,相反的情况发生在web会话是灰色的时候,它不显示html内容。 注意:始终显示请求/响应标题,这仅用于内容。我还尝试了点技巧(“:80”)并从localhost切换到127.0。0.1.

  • 我用的是Android Studio。我编辑了logcat消息,以便只记录要显示的应用程序。但在运行时,我发现logact显示了我的日志和系统日志,如下例所示: 请告诉我为什么logcat仍然显示系统日志