JTable设计与后端数据结构同步 [英] JTable design to synchronize with back-end data-structure

查看:115
本文介绍了JTable设计与后端数据结构同步的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

 表格格式:
范围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格式:
键值
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

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



我需要验证数据(例如从上面 - 假设用户想要的编辑值30.1.He应该只允许在12.1和45.6之间输入值。由于数据表是字符串(一旦加载),我打算使用正则表达式和密钥监听器,并消耗所有不会匹配正则表达式和值不在范围内的值。我不知道这是一个好主意或什么是含义。我想就此提出一些建议。

解决方案

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



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

  import java.awt。*; 
import java.awt.event。*;
import javax.swing。*;
import javax.swing.table。*;

/ *
*打开对话框的编辑器按钮。
* /
// 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);

//使用JButton作为编辑器组件

editorComponent = new JButton();
editorComponent.setBackground(Color.white);
editorComponent.setBorderPainted(false);
editorComponent.setContentAreaFilled(false);

//设置实际编辑的对话框

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;


/ *
*包含实际编辑组件的简单对话框
* /
class PopupDialog扩展JDialog实现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.addActionListener(this);
JButton ok = new JButton(Ok);
ok.setPreferredSize(cancel.getPreferredSize());
ok.addActionListener(this);

JPanel按钮= 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)
}

/ *
*在隐藏弹出窗口之前保存更改的文本
* /
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 };
对象[] [] data =
{
{项目1,项目1的说明},
{项目2,项目2的说明 },
{项目3,项目3的描述}
};

JTable table = new JTable(data,columnNames);
table.getColumnModel()。getColumn(1).setPreferredWidth(300);
table.setPreferredScrollableViewportSize(table.getPreferredSize());
JScrollPane scrollPane = new JScrollPane(table);

//在第二列使用弹出式编辑器

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);
}
}


I have a JTable which is loaded from a data-structure using table model.The data-structure is of the format NavigableMap<Float,NavigableMap<Float,Boolean>>.An example data is:

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

The above data format is represented in the DS as

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

I have managed to represent the above given data in Jtable using table-model.Once the data is loaded from the DS to the table I have to allow user edit.Now this is where I have problem.My doubt is whether is should keep the data structure synchronized with the changes in the table or should i recreate the DS from the table once the user finish editing and then replace it with the old one.

More over I need to validate the data(for example from above - Suppose the user want's to edit the value 30.1.He should only be allowed to enter values between 12.1 and 45.6.Since data the tables are string's (once loaded) I'm planning to use regex and key-listener and consume all user key presses which doesn't match the regex and values which doesn't come within the range.I'm not sure is this is a good idea or what are implications.I would like to get some suggestions on this.

解决方案

I would recreate your DS once the user is finised editing the table.

You can always create a custom editor to display a popup dialog where you have two separate text fields for each value of the range. Then you can edit each field as a double value within your specified range and recreate the formatted string before saving it to the model. Here's an old example I have lying around to get you started:

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);
    }
}

这篇关于JTable设计与后端数据结构同步的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆