簡體   English   中英

Java Swing中,100個TextField具有相似的任務,所以我想編寫一個函數

[英]Java Swing, 100 TextFields have similar task, So I want to write the one function to do so

我正在做一個小項目(使用NetBeans的Java GUI Builder),其中有100個TextField,它們對不同的數據執行完全相同的操作 它們排列成10行 10列 ,(變量)名稱如下:

txt11,  txt12,  ... txt110
txt21,  txt22,  ... txt210
  .       .     ...   .
txt101, txt102, ... txt1010

因此,可以通過行和列號輕松生成名稱,也可以輕松提取其所屬的TextField的行和列(但我不能)。

由於它們執行相似的任務,因此我可以編寫一個rowcol作為參數的方法 ,並在用戶在任何TextField中寫入內容時執行。 為了完成任務,我必須找出它們所屬的行和列。

我試圖在事件監聽器中使用以下代碼(我為所有JTextField添加了相同的事件監聽器):

private void TextFieldAnswerTyped(java.awt.event.KeyEvent evt) {
    String name = ((JTextField)evt.getSource()).getName();

    int row,col;
    if(name.endsWith("10"))
    {
        col=10;
        name=name.substring(0, name.length()-2);
    }
    else
    {
        col=Integer.parseInt(name.substring(name.length()-1,name.length()));
        name=name.substring(0, name.length()-1);
    }

    if(name.endsWith("10"))
        row=10;
    else
        row=Integer.parseInt(name.substring(name.length()-1,name.length()));

    checkForCell(row, col); //Performs the task
}

每當事件發生時,它的namenull 我在這里做任何錯誤還是有什么好的選擇?

您的問題是您將變量名稱與JTextField的名稱字段混淆了。 在JTextField上調用getName()返回后者的名稱字段,正如您所發現的那樣,默認情況下將其設置為null。 有幾種解決方案:

  • 您可以嘗試使用反射來獲取您感興趣的變量所引用的對象,這是一個糟糕,脆弱且笨拙的想法,只是不要這樣做。
  • 實際上,您可以通過在創建JTextField之后在JTextField上調用setName(...)來將name字段設置為與變量名稱相同的方法-另一個糟糕的做法
  • 最好將所有JTextField對象放入一維或二維數組或集合中。 這樣,很容易找出您的字段位於哪一行。
  • 也許最好的解決方案(很難知道而又不知道更多要求)將是使用JTable,它具有10行10列。

您的問題聽起來似乎實際上是一個XY問題 ,當真正的解決方案是完全使用另一種方法時,您會問“我如何修復此代碼”。 請確實告訴我們有關您的“問題空間”的更多信息-您要解決的是什么總體問題,因為我再次認為您可能會找到更好的解決方案。


另一個問題:您似乎正在嘗試將KeyListener與JTextFields一起使用,我也不建議這樣做,因為這會干擾文本字段的本機鍵處理。 相反,使用DocumentListener或DocumentFilter幾乎總是更好。


另一個選擇是將Swing組件方法putClientProperty(...)為讓JTextFields“知道”它們所在的行和列。使用上述方法加上與getter等效的方法的示例,並且使用JTextField中用於獲取數據的ActionListener如下:

import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;

@SuppressWarnings("serial")
public class ManyFields extends JPanel {

    private static final int ROWS = 10;
    private static final int COLS = ROWS;
    private static final int GAP = 2;
    private static final int TF_COLS = 5;
    public static final String ROW = "row";
    public static final String COL = "col";
    private JTextField[][] fieldGrid = new JTextField[ROWS][COLS];

    public ManyFields() {
        setLayout(new GridLayout(ROWS, COLS, GAP, GAP));
        setBorder(BorderFactory.createEmptyBorder(GAP, GAP, GAP, GAP));

        TFieldListener tFieldListener = new TFieldListener();

        for (int row = 0; row < fieldGrid.length; row++) {
            for (int col = 0; col < fieldGrid[row].length; col++) {
                JTextField tField = new JTextField(TF_COLS);
                tField.putClientProperty(ROW, row);
                tField.putClientProperty(COL, col);
                tField.addActionListener(tFieldListener);

                add(tField);
                fieldGrid[row][col] = tField;
            }
        }
    }

    private class TFieldListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            JTextField field = (JTextField) e.getSource();
            int row = (int) field.getClientProperty(ROW);
            int col = (int) field.getClientProperty(COL);

            // or another way to get row and column using the array:
            int row2 = -1;
            int col2 = -1;
            for (int r = 0; r < fieldGrid.length; r++) {
                for (int c = 0; c < fieldGrid[r].length; c++) {
                    if (field == fieldGrid[r][c]) {
                        row2 = r;
                        col2 = c;
                    }
                }
            }
            // now here row2 and col2 are set

            String text = field.getText();

            String title = String.format("Text for Cell [%d, %d]", col, row);
            String message = "text: " + text;
            int messageType = JOptionPane.INFORMATION_MESSAGE;
            JOptionPane.showMessageDialog(ManyFields.this, message, title, messageType);
            field.transferFocus(); // move to next component
        }
    }

    private static void createAndShowGui() {
        ManyFields mainPanel = new ManyFields();

        JFrame frame = new JFrame("Many Fields");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }
}

但是同樣,JTable可能會提供更好的解決方案,但是很難在沒有更多需求信息的情況下確切地知道如何創建它。

暫無
暫無

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

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