簡體   English   中英

如何使 JTextField 的數字大於另一個 JTextField 的數字?

[英]How do you make a JTextField's number bigger than another JTextField's number?

我試圖讓我的井字游戲項目的 JTextField 的數字大於另一個 JTextField 的數字,但我不斷收到異常。例如,如果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的空值”。

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();                
        }               
    });

希望它會有所幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM