如何使一个 JTextField 的数字比另一个 JTextField 的数字大?



我正试图为我的Tic-Tac-Toe项目获得一个JTextField的编号大于另一个JTxtField的编号,但我一直遇到异常。。例如,如果gridSizeField的数字是6,那么playersField的数字就不会是5。我希望它是6或更大。

这是我迄今为止所有的代码:

import java.awt.Color;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.Graphics;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.PlainDocument;
/**
* A class that shows the xy coordinates near the mouse cursor.
*/
class AlsXYMouseLabelComponent extends JComponent {

public int x;
public int y;
/**
* Uses the xy coordinates to update the mouse cursor label.
*/
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
String coordinates = x + ", " + y; // Get the cordinates of the mouse
g.setColor(Color.red);
g.drawString(coordinates, x, y); // Display the coordinates of the mouse
}

}
/**
* The class that has tools that can be used for <code>JTextField</code>s.
*/
class JTextFieldTool {

/**
* Make a JTextField only accept numbers
* @param textField1 The JTextField that will only accept numbers
* @param textField2 The JTextField that the will always be greater than the first JTextField
* @param limit The amount of digits that the JTextField can have
*/
public static void setAcceptNumberOnly(JTextField textField1, int limit) {

textField1.setDocument(new JTextFieldTool.JTextDocLimit(limit));
textField1.select(textField1.getText().length(), 0);
textField1.addKeyListener(new KeyAdapter() {

private JTextField obj = textField1;

@Override
public void keyTyped(KeyEvent event) {

char c = event.getKeyChar();

/**
* If the character that the user tries to type in a character that is not a digit, don't put the character in the JTextField
*/
if (!Character.isDigit(c) || c == KeyEvent.VK_BACK_SPACE || c == KeyEvent.VK_DELETE)
event.consume();

}

@Override
public void keyReleased(KeyEvent event) {

char c = event.getKeyChar();

if (Character.isDigit(c) || c == KeyEvent.VK_BACK_SPACE || c == KeyEvent.VK_DELETE || c == KeyEvent.VK_LEFT || c == KeyEvent.VK_RIGHT) {

String textStr = this.obj.getText().replace(",", "");

if (textStr.isEmpty())
textStr = "0";

int selectionStart = this.obj.getSelectionStart();
int lengthToEnd = this.obj.getText().length() - selectionStart; 
int newSelectionStart = this.obj.getText().length() - lengthToEnd;
this.obj.select(newSelectionStart, 0);

}

}

});

}

/**
* Makes a JTextField accept numbers that are less than another JTextField.
* @param textField1 The first JTextField which is less than the other second one.
* @param textField2 The second JTextField which is always greater than the first one.
*/
public static void makeThisTextFieldLesser(JTextField textField1, JTextField textField2) {

textField1.addKeyListener(new KeyAdapter() {

@Override
public void keyTyped(KeyEvent event) {

char c = event.getKeyChar();
String label = textField2.getText();

/**
* If the user tries to enter a number in the first text field that is greater than or equal to the second text field, don't put the number in
*/
if (c >= textField2.getText().charAt(0) || label.isEmpty())
textField2.setText("3");
event.consume();

}   

});

}

public static class JTextDocLimit extends PlainDocument {

private int limit;

public JTextDocLimit(int limit) {
this.limit = limit;
}

@Override
public void insertString(int offset, String str, AttributeSet attr) throws BadLocationException {

if (str == null)
return;

if ((getLength() + str.length()) <= limit) 
super.insertString(offset, str, attr);

}

}
}
class Canvas extends JComponent {

/**
* Draws the grid that the players are going to use for their Tic Tac Toe game.
* @param g the <code>Graphics</code> object that is used to draw the lines of the grid
*/
public static void drawGrid(Graphics g) {

g.drawOval(10, 10, 10, 10); 

}

/**
* Displays the grid that was drawn in the <code>drawGrid</code> method.
*/
@Override
public void paint(Graphics g) {         
super.paint(g);
drawGrid(g);
}

}

public class TicTacToe implements ActionListener {

/**
* Global variables used so that they are in the scope of the actionPerformed method or other variables
*/
private static JPanel panel;
private static JFrame frame;
private static JTextField gridSizeField;


/**
* Create a GUI that will let the user customize options for the game, and display the grid using lines in the Graphics2D class
*/
public static void main(String[] args) {

panel = new JPanel();
frame = new JFrame();
frame.setSize(1365, 767);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle("Tic Tac Toe");
frame.setCursor(new Cursor(Cursor.CROSSHAIR_CURSOR));
frame.setVisible(true);
frame.add(panel);

panel.setLayout(null);

AlsXYMouseLabelComponent alsXYMouseLabel = new AlsXYMouseLabelComponent();

/**
* Add the component to the DRAG_LAYER of the layered pane (JLayeredPane)
*/
JLayeredPane layeredPane = frame.getRootPane().getLayeredPane();
layeredPane.add(alsXYMouseLabel, JLayeredPane.DRAG_LAYER);
alsXYMouseLabel.setBounds(0, 0, frame.getWidth(), frame.getHeight());
/**
* Add a mouse motion listener, and update the crosshair mouse cursor with the xy coordinates as the user moves the mouse
*/
frame.addMouseMotionListener(new MouseMotionAdapter() {

/**
* Detects when the mouse moved and what the mouse's coordinates are.
* @param event the event that happens when the mouse is moving.
*/
@Override
public void mouseMoved(MouseEvent event) {      
alsXYMouseLabel.x = event.getX();
alsXYMouseLabel.y = event.getY();
alsXYMouseLabel.repaint();
}

});

JLabel title = new JLabel("Tic Tac Toe");
title.setBounds(500, 100, 550, 45);
title.setFont(new Font("Verdana", Font.PLAIN, 50));
panel.add(title);

JLabel playersLabel = new JLabel("Number of Players: ");
playersLabel.setBounds(280, 335, 285, 25);
playersLabel.setFont(new Font("Verdana", Font.PLAIN, 20));
panel.add(playersLabel);

JTextField playersField = new JTextField();
playersField.setBounds(480, 335, 30, 25);
playersField.setText("1"); // Make the players field already have an integer so that the program won't throw a NumberFormatException
playersField.setFont(new Font("Verdana", Font.PLAIN, 20));
playersField.setHorizontalAlignment(JTextField.CENTER);
JTextFieldTool.setAcceptNumberOnly(playersField, 1); // Make the players field accept only numbers that have one digit
JTextFieldTool.makeThisTextFieldLesser(playersField, gridSizeField); // Make the players field less than the grid size field
panel.add(playersField);

JLabel computersLabel = new JLabel("How Many Computers Are Included?");
computersLabel.setBounds(280, 365, 575, 25);
computersLabel.setFont(new Font("Verdana", Font.PLAIN, 20));
panel.add(computersLabel);

JTextField computersField = new JTextField();
computersField.setBounds(655, 365, 30, 25);
computersField.setText("1");
computersField.setFont(new Font("Verdana", Font.PLAIN, 20));
computersField.setHorizontalAlignment(JTextField.CENTER);
JTextFieldTool.setAcceptNumberOnly(computersField, 1);
panel.add(computersField);

JLabel gridSizeLabel = new JLabel("Grid Size: ");
gridSizeLabel.setBounds(720, 335, 220, 25);
gridSizeLabel.setFont(new Font("Verdana", Font.PLAIN, 20));
panel.add(gridSizeLabel);

JTextField gridSizeField = new JTextField();
gridSizeField.setBounds(830, 335, 30, 25);
gridSizeField.setText("3");
gridSizeField.setFont(new Font("Verdana", Font.PLAIN, 20));
gridSizeField.setHorizontalAlignment(JTextField.CENTER);
JTextFieldTool.setAcceptNumberOnly(gridSizeField, 1); // Make the grid size field accept only numbers that have one digit
panel.add(gridSizeField);

JButton playButton = new JButton("Let's Play!");
playButton.setBounds(530, 480, 220, 25);
playButton.setFont(new Font("Verdana", Font.PLAIN, 20));
playButton.addActionListener(new TicTacToe());
panel.add(playButton);

}

/**
* Removes all of the components of the panel when the Play <code>JButton</code> is clicked and replaces it with the canvas that the Tic Tac Toe grid will be drawn on.
* @param event the event that happens when the Play button is clicked
*/
@Override
public void actionPerformed(ActionEvent event) {

Component[] components = panel.getComponents();

/**
* Loop through all of the components in the panel and remove them
*/
for (Component component : components)
panel.remove(component);

panel.revalidate();
panel.repaint();

frame.getContentPane().add(new Canvas()); // Add the canvas to the frame so that the lines drawn in the paint() method can be visible

}

/**
* Displays the player's symbol when they click on a square in the grid.
* @param event the event that happens when a square in the grid is clicked
*/
public void mouseClicked(MouseEvent event) {

}

}

如果你有什么建议,我会很高兴的。

NPE的原因是"在该方法调用中传递的gridSizeField的null值";。

JTextFieldTool.makeThisTextFieldLesser(playersField, gridSizeField); 

与其调用方法makeThisTextFieldLesser((,不如在实例化gridSizeField之后添加KeyListener可以避免NPE。只是稍微修改了一下代码。

playersField.addKeyListener(new KeyAdapter() {            
@Override
public void keyTyped(KeyEvent event) {                
if (gridSizeField.getText().isEmpty() || event.getKeyChar() < gridSizeField.getText().charAt(0))
event.consume();                
}               
});

希望能有所帮助。

最新更新