簡體   English   中英

使用Swing JTable重繪表問題

[英]Repaint Table issue with Swing JTable

我正在使用Swing JTable ,但在重新繪制表時遇到了麻煩。 我用以下代碼繪制了一個JTable

Object[] column = new Object[]{"Entity", "Attribute"};
Object[][] rowData = new Object[][]{{"E1", "A1"},{"E2", "A2"}};
TableCellRenderer cellRenderer = new TableCellRenderer();

JTable table = new JTable(new DefaultTableModel(rowData, column));

table.setCellSelectionEnabled(true);

table.getColumnModel().getColumn(0).setCellRenderer(cellRenderer);

下面是我的表格渲染器代碼..

public class TableCellRenderer implements javax.swing.table.TableCellRenderer {

//private JPanel panel;
JTextField field;
private JTable table;   

@Override
public Component getTableCellRendererComponent(final JTable table, final Object value,
        boolean isSelected, boolean hasFocus, final int row, final int column) {

    this.table = table;
    //JTextField field = null;
    System.out.println("Rendere : Row : " + row + "Column : " + column);
    final JPanel panel = new JPanel();
    panel.setLayout(new BorderLayout());

    JButton button = new JButton("?");
    button.setPreferredSize(new Dimension(20, panel.getHeight()));
    button.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent arg0) {
            new SelectionDialog(panel, table, value, row, column);

        }
    });
    if(table.getValueAt(row, column) != null){
        field = new JTextField(table.getValueAt(row, column).toString());
    }else{
        field = new JTextField(table.getValueAt(row, column).toString());
    }
    field.setPreferredSize(new Dimension(30, panel.getHeight()));
    panel.add(field, BorderLayout.WEST);
    panel.add(button, BorderLayout.EAST);

    return panel;

}

這就是我更新表中單元格內容的方式。

SelectionDialog.this.table.getModel().setValueAt("E7", 0, 0);

我正在通過SelectionDialog更新表模型數據,例如將行0,列0更改為E7等。在表模型中更改數據后,我嘗試了以下選項,但是它們均未刷新視圖中的表數據,但是該數據在JTable模型中已正確更新。 如果我即時添加新行,然后調用以下方法,則一切正常,但如果我修改現有行模型中的數據,則以下提到的解決方案均無法正常工作

//((DefaultTableModel)SelectionDialog.this.table.getModel()).addRow(new Object[]{"E3", "A3"});
            //((DefaultTableModel)SelectionDialog.this.table.getModel()).fireTableCellUpdated(SelectionDialog.this.row, SelectionDialog.this.column);
            //((DefaultTableModel)SelectionDialog.this.table.getModel()).fireTableChanged(new TableModelEvent(SelectionDialog.this.table.getModel()));
            //((DefaultTableModel)SelectionDialog.this.table.getModel()).fireTableStructureChanged();
            //SelectionDialog.this.table.repaint();
        //  SelectionDialog.this.table.revalidate();

請提供有關此問題的任何見解,因為我可能會錯過一些非常突出的事情。

編輯1:只是添加了一個我想更早放置的音符,但不知道我怎么想念。 表格通常不會更新,但是如果我將注意力從進行更改的單元格中移開,或者我更改了表格的大小,那么它將立即將該特定單元格的內容更改為新的選定值。

問題解決了:

我將我的發現寄給面臨類似問題的人。

我在表格的每個單元格內渲染了一個按鈕和一個文本框。 單擊按鈕時(未提供編輯器代碼,因為它似乎與我無關,請單擊此處),將出現一個對話框,從用戶輸入值並更新特定的列和行。 我在帖子末尾(在編輯1之前)提到的行無法正常工作,但是渲染器無法執行,除非我手動將焦點從所選單元格中移出(單擊了其按鈕)或手動更改了jtable的大小,感覺就像按鈕在編輯器中,單擊按鈕表明該單元已被編輯,除非完成編輯(這需要聚焦或輸入鍵等),否則將不執行偏離路線的渲染器。我將以下代碼用作

table.editCellAt(-1, -1);

它從已編輯的單元格(通過按鈕進行編輯)中移出焦點,因此渲染器按預期執行並正常工作。

當您使用DefaultTableModel並想要更新某個值時,需要使用DefaultTableModel#setValueAt方法。

調用此方法(當然是在事件調度線程上)將更新您的模型並觸發必要的事件。 這些事件將導致您的JTable自行更新。

有關渲染器的其他幾點說明:

  • 在渲染器的每次調用中創建新組件都不是可行的方法。 對於大型表,這變得異常緩慢。 在渲染器的構造函數中一次創建所有組件,然后更新它們的狀態
  • 除非還具有編輯器,否則將JButton添加到渲染器中的表無效。 該按鈕將不可單擊,並且您附加到該按鈕的動作偵聽器將永遠不會被調用。 有關更多信息,請參見JTable教程中渲染器和編輯器部分
  • 無需在渲染器中調用getValueAt 該值作為參數之一傳入

暫無
暫無

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

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