簡體   English   中英

讓JTextField自動調整大小

[英]Let JTextField resize automatically

我想顯示JTextField的二維數組,以供用戶編輯。 初始化后(帶有文本),它們顯示為合適的大小。 當“文本”被編輯時,它們不會調整大小。 我將它們放在JSrolePane中帶有GridbagLayout的JPanel中。 試圖“手動”調整它們的大小,因此在接收事件時調用.setPrefferedSize,但是很難獲得不同的letterSize的TextLength精確原因。 而且所有JTextField都顯示在一行中,因此我可能對GridBagConstraints出錯了。 (以前使用過JTable,但不喜歡它)。

GridBagConstraints c = new GridBagConstraints();
    c.gridx = 0;
    c.gridy = 0;
    c.weighty = 0.1;
    c.weightx = 0.1;
    c.fill = GridBagConstraints.BOTH;
    for(int row=0; row<initText.length; row++) {
        for(int col=0; col<initText[row].length; col++) {
            jTextFields[row][col] = new JTextField(initText[row][col]);
            jTextFields[row][col].getDocument().addDocumentListener(new DocumentListener() {
                @Override
                public void removeUpdate(DocumentEvent arg0) {
                }
                @Override
                public void insertUpdate(DocumentEvent dE) {
                    int row = -1;
                    int col = -1;
                    for(int i=0; i<jTextFields.length; i++) {
                        for(int ii=0; ii<jTextFields[i].length; ii++) {
                            if(jTextFields[i][ii].getDocument()==dE.getDocument()) {
                                row=i;
                                col=ii;
                                break;
                            }
                        }
                        if(col!=-1) {
                            break;
                        }
                    }
                    //Tried it so to make resize "by Hand" but initalisation size is better
                    jTextFields[row][col].setPreferredSize(new Dimension(jTextFields[row][col].getText().length()*jTextFields[row][col].getPreferredSize().height, jTextFields[row][col].getPreferredSize().height));
                    System.out.println("insertUpdate in cell "+row+" "+col);
                    Main.gui.frame.repaint();
                }
                @Override
                public void changedUpdate(DocumentEvent arg0) {
                    // TODO Auto-generated method stub
                }
            });
            c.gridx = col;
            c.gridy = row;
            innerContentPane.add(jTextFields[row][col], c);
        }
    }
    contentPane = new JScrollPane(innerContentPane);
    frame.repaint();

您不想繼續重置組件的首選大小。 讓每個組件確定自己的首選大小。

相反,您想調用布局管理器,以便可以重新計算每個組件的大小並可以調整面板的布局。 一種簡單的方法是對包含文本字段的面板進行revalidate()

我不是多層次循環代碼和多層次循環代碼的忠實擁護者。 您可以通過創建要由所有文檔共享的通用DocumentListener來簡化代碼。

另外,您的代碼僅處理添加文本的情況。 如果刪除了文本,文本字段的大小不應該縮小嗎?

應用以上所有建議,邏輯將類似於:

//  Create shared DocumentListener

DocumentListener dl = new DocumentListener()
{
    @Override
    public void removeUpdate(DocumentEvent de)
    {
        resizeTextField(de);
    }

    @Override
    public void insertUpdate(DocumentEvent de)
    {
        resizeTextField(de);
    }

    @Override
    public void changedUpdate(DocumentEvent de) {}

    private void resizeTextField(DocumentEvent de)
    {
        innerContentPane.revalidate();
    }
};

GridBagConstraints c = new GridBagConstraints();
c.gridx = 0;
c.gridy = 0;
//c.weighty = 0.1;
//c.weightx = 0.1;
//c.fill = GridBagConstraints.BOTH;

//  Create text fields and add listener to the Document

for(int row = 0; row < 3; row++)
{
    for(int col = 0; col <3; col++)
    {
            JTextField textField = new JTextField("0");
            textFields[row][col] = textField;
            textField.getDocument().addDocumentListener(dl);
            c.gridx = col;
            c.gridy = row;
            innerContentPane.add(textField, c);
    }
}

注意,DocumentListener也應該作為內部類創建,以使代碼更加清晰。

而且所有JTextFields都顯示在一行中,所以我可能對GridBagConstraints有點誤解

JPanel的默認布局管理器是FlowLayout。如果要使用的布局,則需要將布局設置為GridBagLayout:

innerContentPane.setLayout( new GridBagLayout() );
GridBagConstraints c = new GridBagConstraints();

否則,GridBagConstraints對FlowLayout毫無意義。

閱讀有關布局管理器的Swing教程中的部分,以獲取更多信息。

暫無
暫無

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

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