我有一个JTable,它是使用表模型从数据结构加载的。数据结构的格式为NavigableMap<Float,NavigableMap<Float,Boolean>>。示例数据为:
NavigableMap<Float,NavigableMap<Float,Boolean>>
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,true>,<32,false>,<45,true>,<50,false>> 30.2 <<30,true>,<32.4,true>,<45,true>,<50.1,true>> 45.6 null
我已经成功地使用表模型在Jtable中表示了上述给定的数据。一旦将数据从DS加载到表中,我就必须允许用户编辑。现在这是我遇到的问题。我的疑问是是否应该保留数据结构与表中的更改同步,还是应该在用户完成编辑后从表中重新创建DS,然后将其替换为旧的DS。
我还需要验证数据(例如,从上面开始-假设用户想要编辑值30.1。他应该只被允许输入12.1和45.6之间的值。由于数据表是字符串的(一旦加载)我计划使用正则表达式和键侦听器并消耗所有与正则表达式不匹配的用户按键和不在范围内的值。我不确定这是个好主意还是暗示什么。想获得一些建议。
一旦用户确定编辑表,我就会重新创建DS。
您始终可以创建一个自定义编辑器来显示一个弹出对话框,其中每个范围值都有两个单独的文本字段。然后,您可以将每个字段编辑为指定范围内的双精度值,并在将其保存到模型之前重新创建格式化的字符串。这是我为了让您起步而使用的一个旧示例:
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(p.x, p.y + 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); } }