java - 为什么 repaint() 后方 block 不显示?

标签 java swing graphics2d

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

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 所建议的那样,为了获得更好的帮助,请创建并发布您的 Minimal, Complete, and Verifiable exampleShort, Self Contained, Correct Example .


我会尽可能地尝试对您的问题进行面向对象编程,让您分而治之。这可能涉及:

  • 创建一个 SeatClass 枚举,其中可能包含两个元素:FIRST 和 COACH。
  • 创建一个非 GUI 座位类,其中包含多个字段,可能包括:int row、char seat(例如 A、B、C、D、E、F),一个 SeatClass 字段以查看它是否是头等舱座位或车厢,以及一个 boolean 型预留字段,该字段仅在座位已预留时为真。
  • 此类还有一个 getId() 方法,该方法返回行号和座位字符的字符串串联。
  • 创建一个非 GUI 飞机类,一个包含两个座位阵列,一个用于 SeatClass.FIRST 或头等舱座位,一个用于 SeatClass.COACH。
  • 它还有一个行数字段和一个座位数(列数)字段。
  • 创建所有这些之后,然后处理您的 GUI 类。
  • 我会为 Seats 创建一个 GUI 类,也许是 GuiSeat,让它包含一个 Seat 对象,也许让它扩展 JPanel,允许它显示它自己的 id 字符串,它从它包含的 Seat 对象中获取,让它覆盖 getBackground(...) 这样它的颜色将取决于座位是否已预订。
  • 等.....

关于java - 为什么 repaint() 后方 block 不显示?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33222183/

相关文章:

java - 图像正在横向绘制到屏幕(Java BufferedImage、WritableRaster)

java - 使用 Graphics2D 多次处理图像

java - 将 R 函数作为 Java 方法参数传递

java - JCombobox键盘输入速度

java - Netbeans 无法显示设计按钮

java - 如何在 Swing 延迟几秒后处理帧?

java - 在 Selenium 中避免 NoSuchElementException 的最佳方法是什么?

java - 为什么将静态方法视为方法?

java - 要通过 Maven 包含在 Eclipse 中的 Tomcat 库

java - 为什么这个图像在 Java 中缩小后看起来很糟糕?