1

我只想在单击按钮时移动一个按钮,并且我想更改标签文本。

我编写了移动按钮的代码,它对我来说工作正常。但是当我想将标签文本更改为不同的名称时,它不会发生。

按钮正在从其位置移动或标签文本已更改。但我想同时执行这两个操作,即按钮单击事件。我尝试了很多东西。一些身体可以帮助我吗?

import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class JavaGUI extends JPanel {

    private Control control = new Control();
    private Keys keys = new Keys("Original starting value.");

    public JavaGUI() {        
        this.add(keys);
        this.add(control);
    }

    private class Control extends JPanel {

        public Control() {
            this.add(new JButton(new AbstractAction("Update") {

                @Override
                public void actionPerformed(ActionEvent e) {
                    System.out.println("Command: " + e.getActionCommand());
                    keys.string = String.valueOf(System.nanoTime());
                    //keys.label.setText(keys.string);          
                    // If I remove these comments button will not move. bt I want both...
                    JButton j = (JButton) e.getSource();
            j.setLocation(j.getX()+10,j.getY()+10);
                }
            }));
        }
    }

    private class Keys extends JPanel {

        private String string;
        private JLabel label = new JLabel();

        public Keys(String s) {
            this.string = s;
            label.setText(s);
            this.add(label);
        }
    }

    private void display() {
        JFrame f = new JFrame("JavaGUI");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(this);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                new JavaGUI().display();
            }
        });
    }
}
4

2 回答 2

1

您不能像那样移动按钮,布局管理器会告诉它应该在哪里。调用 setText 会触发整个组件层次结构的布局管理器的效果。如果你真的想这样做,你应该设置一个空布局管理器,并手动管理所有组件的所有大小和位置。

即使您的按钮在您的原始代码中移动,它在离开其原始位置时也没有正确绘制 - 您可能会不小心滥用 Swing,但并非完全如此。

工作解决方案:

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class MovingButton {
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                buildFrame();
            }
        });
    }

    private static void buildFrame() {
        JFrame f = new JFrame("Test");
        f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

        JPanel p = new JPanel();
        p.setPreferredSize(new Dimension(500, 500));
        p.setLayout(null);

        final JLabel label = new JLabel("Starting Text on Label");
        label.setLocation(200, 0);
        label.setSize(label.getPreferredSize());
        p.add(label);

        final JButton b = new JButton("Button");
        b.setSize(b.getPreferredSize());
        b.setLocation(0, 0);
        p.add(b);
        b.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                b.setLocation((int)b.getLocation().getX() + 20, (int)b.getLocation().getY() + 20);
                label.setText(String.valueOf(System.nanoTime()));
            }
        });


        f.add(p);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }
}
于 2013-01-09T16:45:58.763 回答
1

您需要为持有 JLabel 的类提供一个接受 String 的公共方法,并在其他对象希望更改标签持有的文本时调用该方法,例如:

public void setLabelText(String text) {
   label.setText(text);
}

然后,任何引用 JLabel 显示对象的对象都可以轻松更改标签的文本。

关于您的移动按钮,您需要阅读布局管理器。JPanels 默认使用 FlowLayout,这不接受 setBounds(...) 或 setLocation(...) 的组件。

于 2013-01-09T16:46:18.777 回答