代码之家  ›  专栏  ›  技术社区  ›  evading

未正确清除JFormattedTextField

  •  2
  • evading  · 技术社区  · 14 年前

    我正在做这个作业,做一个程序,解决数独。我有一个带有SudokuTextBox扩展JFormattedTextField网格的面板。我有一个MaskFormatter,所以它只接受每个文本框一个整数。 然后在我的面板中,当一个键被释放时,我有这个代码。

     public void keyReleased(KeyEvent e) {
      SudokuTextBox tb = (SudokuTextBox) e.getSource();
      int row = tb.getRow();
      int col = tb.getCol();
      int value = toInteger(tb.getText());
      //System.out.println(value);
      if(sudoku.isValid(row, col, value)) {
       sudoku.set(row, col, value);
      }
      else {
       sudoku.set(row, col, 0);
       tb.setText(null);
      }
      tb.setCaretPosition(0);
      sudoku.print();
     }
    

    问题是,如果我在文本框中输入了一个有效值,然后我返回并输入一个无效值(根据数独规则),文本框将被清除。但是,当我向前制表时,文本框中会显示上一个有效值。 我的sudokumatrix包含了所有已输入的数字,它会像应该的那样清除该值,因此它只在相应的文本框中。

    当我将“SudokuTextBox extends JFormattedTextField”改为“SudokuTextBox extends JTextField”时,更让人困惑的是,它的工作方式很有魅力。但是我不能设置JTextField的大小,使其为正方形,并且不能为每个文本框强制使用一个整数。

    我错过了一些很明显的东西吗?

    3 回复  |  直到 14 年前
        1
  •  6
  •   trashgod    14 年前

    下面是一个可调整大小的组件的例子,它可能适合这样的游戏。尽管它不包含游戏逻辑,但它处理输入相当好。单击鼠标或按空格键弹出菜单,制表键和数字键按预期工作。特别地, Digit.EMPTY

    alt text

    import java.awt.*;
    import java.awt.event.*;
    import java.awt.image.BufferedImage;
    import java.util.EnumSet;
    import javax.swing.*;
    
    /** @see http://stackoverflow.com/questions/4148336 */
    public class CellTest extends JPanel {
    
        public static void main(String[] args) {
            EventQueue.invokeLater(new Runnable() {
                //@Override
                public void run() {
                    createGUI();
                }
            });
        }
    
        public static void createGUI() {
            JFrame frame = new JFrame();
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setLayout(new GridLayout(3, 3));
            for (Digit d : Digit.digits) {
                frame.add(new CellTest(d));
            }
            frame.pack();
            frame.setVisible(true);
        }
    
        CellTest(Digit digit) {
            this.setLayout(new BorderLayout());
            this.setBorder(BorderFactory.createLineBorder(Color.black, 1));
            this.setBackground(new Color(0x00e0e0));
    
            JLabel candidates = new JLabel("123456789");
            candidates.setHorizontalAlignment(JLabel.CENTER);
            this.add(candidates, BorderLayout.NORTH);
    
            JDigit cellValue = new JDigit(digit);
            add(cellValue, BorderLayout.CENTER);
        }
    }
    
    class JDigit extends JButton {
    
        private static final int SIZE = 128;
        private static final int BASE = SIZE / 32;
        private static final Font FONT = new Font("Serif", Font.BOLD, SIZE);
        private JPopupMenu popup = new JPopupMenu();
        private Digit digit;
        private Image image;
        private int width, height;
    
        public JDigit(Digit digit) {
            this.digit = digit;
            this.image = getImage(digit);
            this.setPreferredSize(new Dimension(64, 64));
            this.setBackground(new Color(0xe0e000));
            this.setForeground(Color.black);
            this.setBorderPainted(false);
            this.setAction(new ButtonAction());
            this.addFocusListener(new FocusHandler());
            for (Digit d : Digit.values()) {
                Action select = new SelectAction(d);
                JMenuItem item = new JMenuItem(select);
                getInputMap().put(KeyStroke.getKeyStroke(
                    KeyEvent.VK_0 + d.value(), 0), d.toString());
                getInputMap().put(KeyStroke.getKeyStroke(
                    KeyEvent.VK_NUMPAD0 + d.value(), 0), d.toString());
                getActionMap().put(d.toString(), select);
                popup.add(item);
            }
        }
    
        public Digit getDigit() {
            return digit;
        }
    
        public void setDigit(Digit digit) {
            this.digit = digit;
            this.image = getImage(digit);
            this.repaint();
        }
    
        @Override
        protected void paintComponent(Graphics g) {
            int w = this.getWidth();
            int h = this.getHeight();
            g.setColor(this.getBackground());
            int dx1 = w * width / height / 4;
            int dx2 = w - dx1;
            g.fillRect(dx1, 0, dx2 - dx1, h);
            g.drawImage(image,
                dx1, 0, dx2, h,
                0, 0, width, height, null);
        }
    
        private Image getImage(Digit digit) {
            BufferedImage bi = new BufferedImage(
                SIZE, SIZE, BufferedImage.TYPE_INT_ARGB);
            Graphics2D g2d = bi.createGraphics();
            g2d.setRenderingHint(
                RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
            g2d.setColor(this.getForeground());
            g2d.setFont(FONT);
            FontMetrics fm = g2d.getFontMetrics();
            width = fm.stringWidth(digit.toString());
            height = fm.getAscent();
            g2d.drawString(digit.toString(), 0, height - BASE);
            g2d.dispose();
            return bi;
        }
    
        private class ButtonAction extends AbstractAction {
            //@Override
            public void actionPerformed(ActionEvent e) {
                popup.show(JDigit.this, getWidth() - width, getHeight() / 2);
            }
        }
    
        private class SelectAction extends AbstractAction {
    
            private Digit digit;
    
            public SelectAction(Digit digit) {
                this.digit = digit;
                this.putValue(Action.NAME, digit.toString());
            }
    
            //@Override
            public void actionPerformed(ActionEvent e) {
                setDigit(digit);
            }
        }
    
        private class FocusHandler implements FocusListener {
    
            private Color background = getBackground();
    
            //@Override
            public void focusGained(FocusEvent e) {
                setBackground(background.brighter());
            }
    
            //@Override
            public void focusLost(FocusEvent e) {
                setBackground(background);
            }
        }
    }
    
    enum Digit {
    
        EMPTY(0, " "), ONE(1, "1"), TWO(2, "2"), THREE(3, "3"), FOUR(4, "4"),
        FIVE(5, "5"), SIX(6, "6"), SEVEN(7, "7"), EIGHT(8, "8"), NINE(9, "9");
        public static EnumSet<Digit> digits = EnumSet.range(Digit.ONE, Digit.NINE);
        private int i;
        private String s;
    
        Digit(int i, String s) {
            this.i = i;
            this.s = s;
        }
    
        @Override
        public String toString() {
            return s;
        }
    
        public int value() {
            return i;
        }
    }
    
        2
  •  2
  •   evading    14 年前

    好的,现在我发现了,“掩码格式化程序的缺点之一是,在当前实现(Java 5)的情况下,它不支持让用户在任何位置离开字段后,将字段还原为空白值(字段在用户输入之前的初始值)。”

    所以既然我用的是一个伪装者,我就不能清除这个区域。

        3
  •  0
  •   evernoob    12 年前

    虽然不是同一个问题,但我在搜索(太多)像这样的问题。在我的例子中,我希望能够填充另外两个字段(jtfStarePatReq和jtfStarePatFound是JTextFields),要么直接查找索引,要么使用一些微调器并创建一个字符串,然后再查找该字符串(好吧,也许这太模糊了,但我认为这已经足够上下文了)。我想要的是,如果用户删除或清除JFormattedTextField jftfStareOpsIndex中的值,那么其他两个字段也将被清除。我在JFormattedTextField上使用了.isEmpty()方法来决定是使用该字段还是使用更长的计算搜索方法。所以如果有人从查找自己的索引到让软件搜索索引,我需要它是空的。无论如何,我试图捕捉committedit()异常并将该值设置为null,它似乎起到了作用。

    public class stareOpsIndexListener extends KeyAdapter implements FocusListener {
    
        public void focusGained(FocusEvent e) {
        }
    
        public void focusLost(FocusEvent e) {
            try {
                JFormattedTextField jftf = (JFormattedTextField) e.getComponent();
                jftf.commitEdit();
                updateStareOpsIndex(jftf);
            } catch (ParseException ex) {
                    jtfStarePatReq.setText("");
                    jtfStarePatFound.setText("");
                    jftfStareOpsIndex.setValue(null);
            }
        }
    
        public void keyPressed(KeyEvent e) {
    
            int key = e.getKeyCode();
    
            if (key == KeyEvent.VK_ENTER) {
                try {
                    JFormattedTextField jftf = (JFormattedTextField) e.getComponent();
                    jftf.commitEdit();
                    updateStareOpsIndex(jftf);
                } catch (ParseException ex) {
                    jtfStarePatReq.setText("");
                    jtfStarePatFound.setText("");
                    jftfStareOpsIndex.setValue(null);
                }
            }
        }
    }
    
    推荐文章