我正在为一个学校项目开发一个小型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
因为我在如何标题和描述这个问题时遇到麻烦...我不太确定如何进一步解释我的问题,所以我想我会把这个放到任何阅读的人身上要更好地理解。
答案 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
通知时,相应地更新其状态。
这可能意味着您需要生成自己的侦听器界面和事件模型,但由于您习惯于处理MouseListener
和DocumentListener
,已经基本了解这些工作方式
从一个基本界面开始,该界面描述了构建器可以生成的事件
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
}
将执行事件的实际调度