JButton不是选定的组件,而是更改为最近添加的按钮值

时间:2017-11-04 08:08:20

标签: java swing user-interface

我正在为一个学校项目开发一个小型UI构建器,我可以使用DocumentListener//DragListener: for isolating changes on a particular component DragListener drag = new DragListener(UIBuilder.this); //Add new button on mouseclick addButton.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent arg0) { JButton button = new JButton("JButton"); button.setBounds(50,20, 90,20); internalFrame.getContentPane().add(button); button.addMouseListener(drag); button.addMouseMotionListener(drag); repaint(); System.out.println("Button added."); } }); 更改按钮的文本值。

然而,在尝试添加另一个按钮时,我发现当我在新按钮上选择时,它会变回最近选择的组件的值。

DragListener

然后将组件传递给public class DragListener extends MouseInputAdapter { Point location; MouseEvent pressed; private UIBuilder uiBuilder; public DragListener(UIBuilder ui){ this.uiBuilder = ui; } public void mousePressed(MouseEvent me) { pressed = me; Component component = me.getComponent(); if (component instanceof JButton){ JButton button = (JButton) component; uiBuilder.getTxtFieldsetText().setText(button.getText()); uiBuilder.getTextFieldName().setText(button.getName()); uiBuilder.getTxtFieldsetText().getDocument().addDocumentListener(new DocumentListener() { @Override public void removeUpdate(DocumentEvent e) { ((JButton) component).setText(uiBuilder.getTxtFieldsetText().getText()); } @Override public void insertUpdate(DocumentEvent e) { ((JButton) component).setText(uiBuilder.getTxtFieldsetText().getText()); } @Override public void changedUpdate(DocumentEvent e) { ((JButton) component).setText(uiBuilder.getTxtFieldsetText().getText()); } }); } } public void mouseDragged(MouseEvent me) { Component component = me.getComponent(); location = component.getLocation(location); int x = location.x - pressed.getX() + me.getX(); int y = location.y - pressed.getY() + me.getY(); component.setLocation(x, y); }

SELECT a.* FROM table_name a left outer join table_name b ON b.f_key = a.id
WHERE b.id is null

因为我在如何标题和描述这个问题时遇到麻烦...我不太确定如何进一步解释我的问题,所以我想我会把这个gif放到任何阅读的人身上要更好地理解。

1 个答案:

答案 0 :(得分:0)

嗯,再次调用DocumentListener时似乎没有移除mousePressed

看看你的代码......

public void mousePressed(MouseEvent me)
{
   pressed = me;
   Component component = me.getComponent();

   if (component instanceof JButton){
       JButton button = (JButton) component;
       uiBuilder.getTxtFieldsetText().setText(button.getText());
       uiBuilder.getTextFieldName().setText(button.getName());

       uiBuilder.getTxtFieldsetText().getDocument().addDocumentListener(new DocumentListener() {
           //...

调用mousePressed时,您可以使用按钮的属性设置UIBuilder s属性,但由于DocumentListener尚未从最后一个按钮中删除,因此它会更新以前选择的按钮的文本会自动显示。

您需要稍微改变一下这个概念。 DragListener应将自己注册为UIBuilder的观察者,然后应生成DragListener可以响应的事件。通过这种方式,您可以解析代码,但也可以减少像这样的错误。

然后,您将保留对所选组件的引用,并在UIBuilder通知时,相应地更新其状态。

这可能意味着您需要生成自己的侦听器界面和事件模型,但由于您习惯于处理MouseListenerDocumentListener,已经基本了解这些工作方式

实施例...

从一个基本界面开始,该界面描述了构建器可以生成的事件

public interface UIBuilderListener extends EventListener {
    public void componentTextDidChange(ComponentTextEvent evt);
    public void componentNameDidChange(ComponentTextEvent evt);
}

可能会有多个监听器,每个监听器专门用于特定系列的事件,但我只是保持简单。

对象事件处理程序传递有关事件的信息,例如......

public class ComponentTextEvent extends EventObject {

    private String text;

    public ComponentTextEvent(UIBuilder source, String text) {
        super(source);
        this.text = text;
    }

    public UIBuilder getBuilder() {
        return (UIBuilder) getSource();
    }

    public String getText() {
        return text;
    }

}

然后您的DragListener会注册有关这些更改的通知......

public class DragListener extends MouseInputAdapter implements UIBuilderListener {

    Point location;
    private UIBuilder uiBuilder;
    private Component selectedComponent;

    public DragListener(UIBuilder ui) {
        this.uiBuilder = ui;
        ui.addBuilderListener(this);
    }

    public void mousePressed(MouseEvent me) {
        selectedComponent = me.getComponent();
    }

    @Override
    public void componentTextDidChange(ComponentTextEvent evt) {
        if (selectedComponent instanceof JButton) {
            JButton btn = (JButton) selectedComponent;
            btn.setText(evt.getText());
        }
    }

    @Override
    public void componentNameDidChange(ComponentTextEvent evt) {
        if (selectedComponent instanceof JButton) {
            JButton btn = (JButton) selectedComponent;
            btn.setName(evt.getText());
        }
    }

}

这非常香草(这很好),我们希望DragListener尽可能少地了解UIBuilder,这会解除代码并允许您改变方式构建器(或DragListener)工作时不会相互影响,因为它们依赖于API描述的内容而不是它们的实现方式(我个人也将UIBuilder作为一个接口,但那就是我)

然后,在UIBuilder中,您将DocumentListener注册到JTextField本身......

JTextField componentTextField;
componentTextField.getDocument().addDocumentListener(new DocumentListener() {

    protected void generateTextEvent(DocumentEvent e) {
        try {
            Document doc = e.getDocument();
            generateTextEvent(doc.getText(0, doc.getLength()));
        } catch (BadLocationException ex) {
            // Handle possible exception
        }
    }

    @Override
    public void removeUpdate(DocumentEvent e) {
        generateTextEvent(e);
    }

    @Override
    public void insertUpdate(DocumentEvent e) {
        generateTextEvent(e);
    }

    @Override
    public void changedUpdate(DocumentEvent e) {
        generateTextEvent(e);
    }
});

最终会打电话给...

protected void generateTextEvent(String text) {
    ComponentTextEvent evt = new ComponentTextEvent(this, text);
    // Loop through listener register and call componentTextDidChange
}

将执行事件的实际调度