SwingMetawidget,值没有绑定到JComboBox

时间:2016-09-05 18:17:14

标签: java swing metawidget

我正在使用SwingMetawidget。我的数据结构有一个Person类,其中一个属性是Title,它也是一个具有从PersonTitle的多对一关系的类。 我试图在MetaWidget中使用Title绑定的值获得JComboBox。我通过查找获取了我指定的值列表,但未在编辑模式中选择检查对象中的值。在只读模式下,显示正确的值(我已设置从标题到String的转换器)。

我的代码如下。我错过了什么?

只显示标题的模式:

enter image description here

编辑模式,但未选择值“Mr”:

enter image description here

编辑模式,显示所有查找值:

enter image description here

主要类别:

public class MetaWidgetFrame extends JFrame {

    private JPanel contentPane;
    private SwingMetawidget metawidget = new SwingMetawidget();
    private JPanel contentPanel;
    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    MetaWidgetFrame frame = new MetaWidgetFrame();
                    frame.setVisible(true);

                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the frame.
     */
    public MetaWidgetFrame() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 473, 281);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        contentPane.setLayout(new BorderLayout(0, 0));
        setContentPane(contentPane);

        contentPanel = new JPanel();
        contentPane.add(contentPanel, BorderLayout.CENTER);

        JPanel controlsPanel = new JPanel();
        contentPanel.setLayout(new BorderLayout(0, 0));

        contentPane.add(controlsPanel, BorderLayout.SOUTH);

        JButton btnSave = new JButton("Save");
        btnSave.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                savePerson();
            }
        });
        controlsPanel.add(btnSave);


        // Set up the objects 
        Person person = new Person();
        person.setUserID(new Integer(1));
        person.setFirstName("Raman");
        person.setLastName("C V");

        Title title = new Title();
        title.setTitleId(new Integer(1));
        title.setName("Mr");


        // Configure Inspectors 
        CompositeInspectorConfig inspectorConfig = new CompositeInspectorConfig().setInspectors(
                  new JpaInspector()
                , new PropertyTypeInspector()
                ,new MetawidgetAnnotationInspector()
                );

        BeansBindingProcessorConfig bbpc = new BeansBindingProcessorConfig();

        // Set up the converter from Title to String
        bbpc.setConverter(Title.class, String.class, new Converter<Title,String>() {
            @Override
            public String convertForward(Title title) {
                return title.getName();
            }

            @Override
            public Title convertReverse(String title) {
                if ( title == null || "".equals( title ) ) {
                    return null;
                }
                Title titleObj = new Title(title,null,null,1,1);
                return titleObj;
            }

        });

        BeansBindingProcessor bbp = new BeansBindingProcessor(bbpc);        

        metawidget.setInspector( new CompositeInspector( inspectorConfig ) );
        metawidget.addWidgetProcessor(new ReflectionBindingProcessor());
        metawidget.addWidgetProcessor(bbp);

        GridBagLayoutConfig gbc = new GridBagLayoutConfig();
        gbc.setLabelAlignment(SwingConstants.RIGHT);
        gbc.setRequiredText("");
        gbc.setRequiredAlignment(SwingConstants.RIGHT);
        gbc.setLabelSuffix(": ");
        GridBagLayout gbl = new GridBagLayout(gbc);

        metawidget.setMetawidgetLayout(gbl);

        metawidget.setToInspect(person);

        contentPanel.add(metawidget, BorderLayout.CENTER);

        JXLabel hintLabel = new JXLabel("New label");
        contentPanel.add(hintLabel, BorderLayout.NORTH);
        JGoodiesValidatorProcessorIMPL jgProcessor = new JGoodiesValidatorProcessorIMPL().setHintLabel(hintLabel);      
        metawidget.addWidgetProcessor(jgProcessor);

        //add a component to show validation messages
        JComponent validationResultsComponent = jgProcessor.getValidationResultsComponent();

        JPanel errorsPanel = new JPanel(new BorderLayout(0, 0));
        contentPanel.add(errorsPanel, BorderLayout.SOUTH);
        errorsPanel.add(validationResultsComponent,BorderLayout.CENTER);

        pack();
    }

    public void savePerson() {
        JGoodiesValidatorProcessorIMPL validationProcessor = metawidget.getWidgetProcessor(JGoodiesValidatorProcessorIMPL.class);
        ValidationResult result = validationProcessor.showValidationErrors().getValidationResults();
        if (!result.hasErrors()) {
            metawidget.getWidgetProcessor(BeansBindingProcessor.class).save(metawidget );
            Person personSaved = metawidget.getToInspect();
            System.out.println("" + personSaved);
        }
        pack();
    }
    public JPanel getContentPanel() {
        return contentPanel;
    }
}

人员类:

@Entity
@Table(name = "person", catalog = "mydb")
public class Person {

    private Integer userID;
    private Title title;
    private String firstName;
    private String lastName;

    public Person() {
    }       

    @Id
    @GeneratedValue(strategy = IDENTITY)

    @Column(name = "userID", unique = true, nullable = false)
    public Integer getUserID() {
        return userID;
    }

    @UiLookup (value={"Mr","Ms","Miss","Mrs"})
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "titleID", nullable = false)
    public Title getTitle() {
        return this.title;
    }

    @Column(name = "firstName", nullable = false, length = 10)
    public String getFirstName() {
        return firstName;
    }

    @UiSection ("Others")
    @Column(name = "lastName", nullable = false, length = 45)
    public String getLastName() {
        return lastName;
    }

    public void setUserID(Integer userID) {
        this.userID = userID;
    }

    public void setTitle(Title title) {
        this.title = title;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    @Override
    public String toString() {
        return "Person: "
                + "\n userID = " + userID  
                + "\n title = " + title
                + "\n titleID = " + title.getTitleId()                  
                + "\n firstName = " + firstName  
                + "\n lastName = " + lastName;
    }


}

标题类:

@Entity
@Table(name = "title", catalog = "emisdb")
public class Title implements java.io.Serializable {

    private Integer titleId;
    private String name;
    private Date createdDate;
    private Date modifiedDate;
    private int createdBy;
    private int modifiedBy;
    private Set<User> users = new HashSet<User>(0);

    public Title() {
    }

    @Override
    public String toString() {
        return name;
    }
    public Title(String name, Date createdDate, Date modifiedDate, int createdBy, int modifiedBy) {
        this.name = name;
        this.createdDate = createdDate;
        this.modifiedDate = modifiedDate;
        this.createdBy = createdBy;
        this.modifiedBy = modifiedBy;
    }

    public Title(String name, Date createdDate, Date modifiedDate, int createdBy, int modifiedBy, Set<User> users) {
        this.name = name;
        this.createdDate = createdDate;
        this.modifiedDate = modifiedDate;
        this.createdBy = createdBy;
        this.modifiedBy = modifiedBy;
        this.users = users;
    }

    @Id
    @GeneratedValue(strategy = IDENTITY)

    @Column(name = "titleID", unique = true, nullable = false)
    public Integer getTitleId() {
        return this.titleId;
    }

    public void setTitleId(Integer titleId) {
        this.titleId = titleId;
    }

    @Column(name = "name", nullable = false, length = 4)
    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @UiHidden
    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "createdDate", nullable = false, length = 19)
    public Date getCreatedDate() {
        return this.createdDate;
    }

    public void setCreatedDate(Date createdDate) {
        this.createdDate = createdDate;
    }

    @UiHidden
    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "modifiedDate", nullable = false, length = 19)
    public Date getModifiedDate() {
        return this.modifiedDate;
    }

    public void setModifiedDate(Date modifiedDate) {
        this.modifiedDate = modifiedDate;
    }

    @UiHidden
    @Column(name = "createdBy", nullable = false)
    public int getCreatedBy() {
        return this.createdBy;
    }

    public void setCreatedBy(int createdBy) {
        this.createdBy = createdBy;
    }

    @UiHidden
    @Column(name = "modifiedBy", nullable = false)
    public int getModifiedBy() {
        return this.modifiedBy;
    }
    public void setModifiedBy(int modifiedBy) {
        this.modifiedBy = modifiedBy;
    }

    @UiHidden
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "title")
    public Set<User> getUsers() {
        return this.users;
    }
    public void setUsers(Set<User> users) {
        this.users = users;
    }
}

1 个答案:

答案 0 :(得分:2)

感谢您对Metawidget的兴趣!

您的代码存在许多常见问题,从简单到概念上都很重要。这些都不是Metawidget问题本身。我会试着打破它们:

琐碎的问题

MetaWidgetFrame {}创建person = new Person()title = new Title(),但忘了person.setTitle( title )

概念上重要1

如您的代码所示,如​​果您尝试:

Title title1 = new Title();
title1.setTitleId(new Integer(1));
title1.setName("Mr");

Title title2 = new Title();
title2.setTitleId(new Integer(1));
title2.setName("Mr");

System.out.println( title1 == title1 );       // will return true
System.out.println( title1.equals( title2 )); // will return false

您可以看到两个具有相同字段的Title个对象,使用对象等效(equals方法)不匹配。 BeansBinding和大多数Java技术都依赖于对象等价。因此,您需要覆盖equals的{​​{1}}和hashCode方法。

概念上重要2

Title中,您只是尝试将字符串('Mr')转换为Converter对象:

Title

这会将titleObj = new Title(title,null,null,1,1);设置为name,但其他字段未初始化(title)或初始化为任意值(null)。特别是,1未初始化。根据您实现idequals方法的方式(见上文),这意味着它们永远不会匹配从数据库返回的记录。

结论

我修复了所有这3个,代码按预期工作。但是,您的具体实现会有所不同特别是您可能需要在hashCode中进行数据库查找。或者,理想情况下,每个会话执行一次数据库查找并缓存标题对象列表。

另外,在ConverterOneToMany可能会过度规范化(即会导致大量数据库连接)。您可能最好只在每个Title中将Title存储为字符串。您仍然可以使用Person对象,以便可以配置数据库中可能的标题列表。