Java 如何使GUI按钮正确响应?

Java 如何使GUI按钮正确响应?,java,swing,jpanel,awt,jbutton,Java,Swing,Jpanel,Awt,Jbutton,我已经编写了以下代码,除了信息框中的“退出信息”按钮和信息框中的文本外,它似乎工作顺利。首先,信息框中的文本(在标签上)拒绝显示。其次,“退出信息”按钮不会出现在我为其设置的位置。有什么建议我可以做,使这个运行正常? 谢谢 注意:我对Java非常缺乏经验,因此可能无法完全理解答案,除非它们是为幼儿园学生编写的:) }您的主要问题,即为什么没有显示infoLabel,是因为在将保存它的JPanel添加到其内容窗格之前,您在其JFrame上调用了setVisible(true)。将所有组件添加到JF

我已经编写了以下代码,除了信息框中的“退出信息”按钮和信息框中的文本外,它似乎工作顺利。首先,信息框中的文本(在标签上)拒绝显示。其次,“退出信息”按钮不会出现在我为其设置的位置。有什么建议我可以做,使这个运行正常? 谢谢

注意:我对Java非常缺乏经验,因此可能无法完全理解答案,除非它们是为幼儿园学生编写的:)


}

您的主要问题,即为什么没有显示infoLabel,是因为在将保存它的JPanel添加到其内容窗格之前,您在其JFrame上调用了
setVisible(true)
。将所有组件添加到JFrame后,始终调用
setVisible(true)
。由于inFrame使用BorderLayout,您还可以通过在JFrame之后添加JPanel来覆盖JLabel

其他问题:

  • 是的,对JButton使用ActionListeners,而不是鼠标侦听器。如果按钮有焦点且空格键被按下,ActionListener将做出响应——这是预期的且正确的行为。一个听话的人不会。另外,如果禁用JButton,ActionListener将无法工作,这也是预期的,也是正确的,而且mouseStener在这里也会出现错误行为
  • 不要设置GUI组件的绝对大小或位置,而是让组件默认首选大小,容器布局管理器为您完成这项繁重的工作
  • info窗口应该是JDialog而不是JFrame,因为一个可见的应用程序应该只有一个主框架窗口,一个JFrame
例如:

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dialog.ModalityType;
import java.awt.Dimension;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;

import javax.swing.*;

public class CombineInput2 {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            MainPanel mainPanel = new MainPanel();
            JFrame frame = new JFrame("Main GUI");
            frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            frame.add(mainPanel);
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        });
    }

}

class MainPanel extends JPanel {
    public MainPanel() {
        setPreferredSize(new Dimension(400, 400));
        add(new JButton(new InfoAction("Info", this)));
        add(new JButton(new ExitAction()));
    }
}

class InfoAction extends AbstractAction {
    private MainPanel mainPanel;
    private JDialog dialog;

    public InfoAction(String name, MainPanel mainPanel) {
        super(name);
        this.mainPanel = mainPanel;
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if (dialog == null) {
            Window win = SwingUtilities.getWindowAncestor(mainPanel);
            dialog = new JDialog(win, "Info", ModalityType.APPLICATION_MODAL);
            dialog.add(new DialogPanel());
            dialog.pack();
            dialog.setLocationRelativeTo(win);
        }
        dialog.setVisible(true);
    }
}

class DialogPanel extends JPanel {
    private static final int DP_WIDTH = 250;
    private static final int DP_HEIGHT = 100;
    private String text = "This is the info text.";
    private JLabel infoLabel = new JLabel(text, SwingConstants.CENTER);

    public DialogPanel() {
        JPanel btnPanel = new JPanel();
        Action exitAction = new ExitAction();
        exitAction.putValue(Action.NAME, "Exit Info");
        btnPanel.add(new JButton(exitAction));

        setLayout(new BorderLayout());
        add(infoLabel, BorderLayout.CENTER);
        add(btnPanel, BorderLayout.PAGE_START);
    }

    @Override
    public Dimension getPreferredSize() {
        Dimension prefSz = super.getPreferredSize();

        if (isPreferredSizeSet()) {
            return prefSz;
        }
        int width = Math.max(prefSz.width, DP_WIDTH);
        int height = Math.max(prefSz.height, DP_HEIGHT);
        return new Dimension(width, height);
    }
}

class ExitAction extends AbstractAction {
    public ExitAction() {
        super("Exit");
        putValue(MNEMONIC_KEY, KeyEvent.VK_X);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        Component c = (Component) e.getSource();
        if (c == null) {
            return;
        }
        Window win = SwingUtilities.getWindowAncestor(c);
        if (win != null) {
            win.dispose();
        }
    }
}

您不想对jbutton使用鼠标侦听器,请尝试改用事件侦听器。@EliSadoff:MouseListener是事件侦听器。也许你想说“ActionListener”,如果是的话,你是对的。@dontknowmuchbutgetting我的意思是
ActionListener
而不是事件侦听器。对不起,谢谢!谢谢我尝试了你的建议,效果比我原来的计划好得多;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dialog.ModalityType;
import java.awt.Dimension;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;

import javax.swing.*;

public class CombineInput2 {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            MainPanel mainPanel = new MainPanel();
            JFrame frame = new JFrame("Main GUI");
            frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            frame.add(mainPanel);
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        });
    }

}

class MainPanel extends JPanel {
    public MainPanel() {
        setPreferredSize(new Dimension(400, 400));
        add(new JButton(new InfoAction("Info", this)));
        add(new JButton(new ExitAction()));
    }
}

class InfoAction extends AbstractAction {
    private MainPanel mainPanel;
    private JDialog dialog;

    public InfoAction(String name, MainPanel mainPanel) {
        super(name);
        this.mainPanel = mainPanel;
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if (dialog == null) {
            Window win = SwingUtilities.getWindowAncestor(mainPanel);
            dialog = new JDialog(win, "Info", ModalityType.APPLICATION_MODAL);
            dialog.add(new DialogPanel());
            dialog.pack();
            dialog.setLocationRelativeTo(win);
        }
        dialog.setVisible(true);
    }
}

class DialogPanel extends JPanel {
    private static final int DP_WIDTH = 250;
    private static final int DP_HEIGHT = 100;
    private String text = "This is the info text.";
    private JLabel infoLabel = new JLabel(text, SwingConstants.CENTER);

    public DialogPanel() {
        JPanel btnPanel = new JPanel();
        Action exitAction = new ExitAction();
        exitAction.putValue(Action.NAME, "Exit Info");
        btnPanel.add(new JButton(exitAction));

        setLayout(new BorderLayout());
        add(infoLabel, BorderLayout.CENTER);
        add(btnPanel, BorderLayout.PAGE_START);
    }

    @Override
    public Dimension getPreferredSize() {
        Dimension prefSz = super.getPreferredSize();

        if (isPreferredSizeSet()) {
            return prefSz;
        }
        int width = Math.max(prefSz.width, DP_WIDTH);
        int height = Math.max(prefSz.height, DP_HEIGHT);
        return new Dimension(width, height);
    }
}

class ExitAction extends AbstractAction {
    public ExitAction() {
        super("Exit");
        putValue(MNEMONIC_KEY, KeyEvent.VK_X);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        Component c = (Component) e.getSource();
        if (c == null) {
            return;
        }
        Window win = SwingUtilities.getWindowAncestor(c);
        if (win != null) {
            win.dispose();
        }
    }
}