为什么在重绘()之后不会出现方块?

我稍早发布了这个问题并且被告知要使它成为SSCCE所以这里(如果我可以做任何改进,请随时让我知道):我想知道为什么当我的按钮“确认”被点击时,旧方块消失了重新绘制的方块不会出现在我的GUI上(用swing制作)。 Squares类绘制了200个间隔开的正方形,其中ID(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 squares = new ArrayList(); 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乘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类(希望你在那个类中没有真正的静态方法)。

我们无法编译或运行您当前的代码。 我们不希望看到您的整个程序,而是您应该将代码压缩到仍然编译的最小位,没有与您的问题无关的额外代码,但仍然可以certificate您的问题。 因此,正如Andrew Thompson建议的那样,为了获得更好的帮助,请创建并发布您的Minimal,Complete和Verifiable示例或Short,Self Contained,Correct示例 。


我会尽可能地尝试OOP-ify你的问题,让你分而治之。 这可能涉及:

  • 创建一个SeatClass枚举,一个可能有两个元素,FIRST和COACH。
  • 创建一个非GUI Seat类,其中包含多个字段,包括:int行,char座位(如A,B,C,D,E,F),SeatClass字段,以查看它是否是头等舱座位或教练,以及一个布尔保留字段,仅当座位被保留时才为真。
  • 这个类还有一个getId()方法,它返回行号和seat char的String连接。
  • 创建一个非GUI Airplane类,一个包含两个Seats数组,一个用于SeatClass.FIRST或一等座位,另一个用于SeatClass.COACH。
  • 它还有一个行计数字段和一个座位数(列数)字段。
  • 创建所有这些后,然后处理您的GUI类。
  • 我为Seats创建了一个GUI类,也许是GuiSeat,让它包含一个Seat对象,也许让它扩展JPanel,允许它显示自己的id,它从它包含的Seat对象中获取,让它覆盖getBackground(...)这样它的颜色将取决于座位是否被保留。
  • 等等…..