JTable设计与后端数据结构同步

我有一个使用表模型从数据结构加载的JTable。数据结构的格式为NavigableMap<Float,NavigableMap> 。示例数据为:

 Table Format: Range f1,v1 f2,v2 f3,v3 f4,v4 12.1-30.2 30,true 32,false 45,true 50,false 30.2-45.6 30,true 32.4,true 45,true 50.1,true 

以上数据格式在DS中表示为

 DS Format: Key Value 12.1 <,,,> 30.2 <,,,> 45.6 null 

我已经设法使用table-model在Jtable中表示上面给出的数据。一旦数据从DS加载到表我必须允许用户编辑。现在我有问题。我怀疑是否应该保留数据结构与表中的更改同步,或者我应该在用户完成编辑后从表中重新创建DS,然后将其替换为旧的DS。

更多我需要validation数据(例如从上面 – 假设用户想要编辑值30.1。他应该只允许输入12.1和45.6之间的值。因为数据表是字符串的(一旦加载)我是计划使用正则表达式和键监听器,并使用所有用户键按下与正则表达式不匹配的值和不在范围内的值。我不确定这是一个好主意还是含义。我会想得到一些建议。

一旦用户完成编辑表格,我会重新创建您的DS。

您始终可以创建自定义编辑器以显示弹出对话框,其中您为该范围的每个值都有两个单独的文本字段。 然后,您可以将每个字段编辑为指定范围内的double值,并在将其保存到模型之前重新创建格式化的字符串。 这是一个让我开始的旧例子:

 import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.table.*; /* * The editor button that brings up the dialog. */ //public class TablePopupEditor extends AbstractCellEditor public class TablePopupEditor extends DefaultCellEditor implements TableCellEditor { private PopupDialog popup; private String currentText = ""; private JButton editorComponent; public TablePopupEditor() { super(new JTextField()); setClickCountToStart(2); // Use a JButton as the editor component editorComponent = new JButton(); editorComponent.setBackground(Color.white); editorComponent.setBorderPainted(false); editorComponent.setContentAreaFilled( false ); // Set up the dialog where we do the actual editing popup = new PopupDialog(); } public Object getCellEditorValue() { return currentText; } public Component getTableCellEditorComponent( JTable table, Object value, boolean isSelected, int row, int column) { SwingUtilities.invokeLater(new Runnable() { public void run() { System.out.println("run"); popup.setText( currentText ); // popup.setLocationRelativeTo( editorComponent ); Point p = editorComponent.getLocationOnScreen(); popup.setLocation(px, py + editorComponent.getSize().height); popup.show(); fireEditingStopped(); } }); currentText = value.toString(); editorComponent.setText( currentText ); return editorComponent; } /* * Simple dialog containing the actual editing component */ class PopupDialog extends JDialog implements ActionListener { private JTextArea textArea; public PopupDialog() { super((Frame)null, "Change Description", true); textArea = new JTextArea(5, 20); textArea.setLineWrap( true ); textArea.setWrapStyleWord( true ); KeyStroke keyStroke = KeyStroke.getKeyStroke("ENTER"); textArea.getInputMap().put(keyStroke, "none"); JScrollPane scrollPane = new JScrollPane( textArea ); getContentPane().add( scrollPane ); JButton cancel = new JButton("Cancel"); cancel.addActionListener( this ); JButton ok = new JButton("Ok"); ok.setPreferredSize( cancel.getPreferredSize() ); ok.addActionListener( this ); JPanel buttons = new JPanel(); buttons.add( ok ); buttons.add( cancel ); getContentPane().add(buttons, BorderLayout.SOUTH); pack(); getRootPane().setDefaultButton( ok ); } public void setText(String text) { textArea.setText( text ); } /* * Save the changed text before hiding the popup */ public void actionPerformed(ActionEvent e) { if ("Ok".equals( e.getActionCommand() ) ) { currentText = textArea.getText(); } textArea.requestFocusInWindow(); setVisible( false ); } } public static void main(String[] args) { String[] columnNames = {"Item", "Description"}; Object[][] data = { {"Item 1", "Description of Item 1"}, {"Item 2", "Description of Item 2"}, {"Item 3", "Description of Item 3"} }; JTable table = new JTable(data, columnNames); table.getColumnModel().getColumn(1).setPreferredWidth(300); table.setPreferredScrollableViewportSize(table.getPreferredSize()); JScrollPane scrollPane = new JScrollPane(table); // Use the popup editor on the second column TablePopupEditor popupEditor = new TablePopupEditor(); table.getColumnModel().getColumn(1).setCellEditor( popupEditor ); JFrame frame = new JFrame("Popup Editor Test"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.getContentPane().add( scrollPane ); frame.pack(); frame.setLocationRelativeTo( null ); frame.setVisible(true); } }