为什么在重绘()之后不会出现方块? [英] Why wont squares show up after repaint()?

查看:104
本文介绍了为什么在重绘()之后不会出现方块?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I posted this question a bit earlier and was told to make it SSCCE so here goes (if I can make any improvements feel free to let me know): I'm wondering why when my button "confirm" is clicked the old squares disappear and the redrawn squares do not appear on my GUI (made with swing). The Squares class draws 200 spaced out squares with an ID (0, 1, 2, or 3 as String) inside obtained from a different class (for the purpose of this question, let's assume it is always 0 and not include that class). For clarification: Squares draws everything perfectly the first time (also retrieves the correct IDs), but I want it to redraw everything once the button is clicked with new IDs. Code for Squares:

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乘20,实际上可能是那个大小,因为它似乎被添加到FlowLayout使用容器中。接下来,您似乎正在绘制超出此组件边界的位置,因此可能永远不会看到图纸。考虑允许Squares对象更大,并确保仅在此组件的范围内绘制。

One major problem: Your Squares JPanels preferred size is only 20 by 20, and will likely actually be that size since it seems to be added to a FlowLayout-using container. Next you seem to be drawing at locations that are well beyond the bounds of this component, and so the drawings likely will never be seen. Consider allowing your Squares objects to be larger, and make sure to only draw within the bounds of this component.

请注意,代码没有意义,包括:

Note also there is code that doesn't make sense, including:

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类(希望你真的没有静态方法) ()

since we don't have your AircraftSeatReservation class (hopefully you don't really have static methods in that class).

我们无法编译或运行您当前的代码。我们不希望看到您的整个程序,而是您应该将代码压缩到仍然编译的最小位,没有与您的问题无关的额外代码,但仍然可以证明您的问题。正如Andrew Thompson所建议的,为了获得更好的帮助,请创建并发布您的最小,完整和可验证的示例简短,自包含,正确的例子

And we can't compile or run your current code. We don't want to see your whole program, but rather you should condense your code into the smallest bit that still compiles, has no extra code that's not relevant to your problem, but still demonstrates your problem. So as Andrew Thompson recommends, for better help, please create and post your Minimal, Complete, and Verifiable example or Short, Self Contained, Correct Example.

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

I would try to OOP-ify your problem as much as possible, to allow you to divide and conquer. This could involve:


  • 创建一个 SeatClass 枚举,一个可能有两个元素, FIRST和COACH。

  • 创建一个非GUI Seat类,包含多个字段,包括:int行,char座位(如A,B,C,D,E,F) ,一个SeatClass字段,用于查看它是否是头等舱座位或教练,以及一个布尔保留字段,仅当座位被保留时才为真。

  • 此类还有一个getId(返回行号和座位字符串的字符串连接的方法。

  • 创建一个非GUI飞机类,一个包含两个座位数组,一个用于SeatClass.FIRST或第一个-class座位,以及一个SeatClass.COACH。

  • 它还有一个行计数字段和一个座位数(列数)字段。

  • 创建所有这些后,然后处理你的GUI类。

  • 我为Seats创建了一个GUI类,也许是GuiSeat,让它包含一个Seat对象,也许它可以扩展JPanel,允许它 要显示它自己从包含的Seat对象获取的id字符串,让它覆盖 getBackground(...),这样它的颜色将取决于座位是保留还是没有。

  • 等.....

  • Creating a SeatClass enum, one with possibly two elements, FIRST and COACH.
  • Creating a non-GUI Seat class, one with several fields including possibly: int row, char seat ( such as A, B, C, D, E, F), a SeatClass field to see if it is a first class seat or coach, and a boolean reserved field that is only true if the seat is reserved.
  • This class would also have a getId() method that returns a String concatenation of the row number and the seat char.
  • Creating a non-GUI Airplane class, one that holds two arrays of Seats, one for SeatClass.FIRST or first-class seats, and one for SeatClass.COACH.
  • It would also have a row count field and a seat count (column count) field.
  • After creating all these, then work on your GUI classes.
  • I'd create a GUI class for Seats, perhaps GuiSeat, have it contain a Seat object, perhaps have it extend JPanel, allow it to display its own id String that it gets from its contained Seat object, have it override getBackground(...) so that it's color will depend on whether the seat is reserved or not.
  • etc.....

这篇关于为什么在重绘()之后不会出现方块?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆