JButton 没有出现在其设置的位置

JButton is not appearing at its set location

我遇到了 JButton 无法到达其设定位置的问题...... 我的代码:

package com.company;

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

public class GUI implements ActionListener {

    private int clickCount = 0;
    private JFrame frame;
    private JPanel panel;
    private JButton button;
    private JLabel label;
    private Dimension buttonDim;

    public GUI() {

        frame = new JFrame();
        panel = new JPanel();
        button = new JButton("Click me");
        label = new JLabel("Number of clicks 0");

        button.addActionListener(this);

        button.setBorder(null);
        button.setLocation(0, 0);


        panel.setBorder(BorderFactory.createEmptyBorder(300/2, 300, 300/2, 300));
        panel.setLayout(new GridLayout(0, 1));
        panel.add(button);
        panel.add(label);

        frame.add(panel, BorderLayout.CENTER);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setTitle("Our GUI");
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        new GUI();
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        clickCount++;
        label.setText("Number of clicks " + clickCount);
    }
}

如果你们真的不介意的话,能告诉我我的按钮是如何通过 this 关键字知道 ActionListener 的吗?我一周前开始 java。

在布局上

请注意,虽然您可以通过设置它们的位置和大小来手动定位您的组件,但这样做很少有用。您不会在基于 Web 的 UI、Apps 或 Swing UI 中执行此操作,原因如下:

  • 用户的屏幕尺寸和分辨率各不相同,因此如果屏幕本身很小,高分辨率屏幕可能需要更大的组件。
  • 操作系统具有多种外观和感觉(PLAF = 平台外观和感觉),而且差异很大。
  • 现在 UI 经常吃多种语言,几乎每种语言都有不同的 运行-长度。

所有这些原因使得即使不是不可能,也很难创建满足所有需求的像素完美布局,而且几乎没有必要。因此,相比之下,每个系统都有自己的方式来使用 GridLayoutBorderLayout 等布局管理器使用 Swing 布局组件

在你的情况下,你已经使用 GridLayout 作为应该包含按钮的面板,并且由于你将 rows = 0cols = 1 传递给构造函数,你有效地创建了一个布局行数和一列。如果您现在将按钮添加到面板,GridLayout 管理器将相应地调整按钮的位置。

此外,您的面板有一个边框,它也会影响该面板的内容区域,即内容的位置 0/0 所在的位置。

因此 button.setLocation(0, 0); 不会产生预期的效果,因为布局管理器将根据可用内容区域重新定位(和调整大小)按钮。

关于布局管理器的更多提示:

  • 您可能想要熟悉各种可用的选项。
  • 查看 add(Component, ...) 的各种版本,它们还允许您传递影响布局的“约束”。这些约束的类型取决于您使用的布局管理器。
  • 您可以为您的组件定义首选大小(以及 min/max)以对布局产生一些影响。许多布局管理器会尽量符合您的意愿。
  • 如果您真的想要自己定位您的组件,您需要设置null布局管理器。但请注意,您必须自己处理很多事情,而且通常您实际上并不想这样做。通常认为需要使用 null 布局来自于缺乏内置布局管理器的感觉。在那种情况下,您可能会探索一些第 3 方布局管理器。我发现过去特别有用的一个(它甚至带有调试视图)是 MiG layout.

最后一些关于如何设计布局的提示:

以 UI 应有的最小尺寸在纸上或某些应用程序中画出预期的布局。如果你想让它调整大小(例如,通过增加宽度),那么想想你获得的额外 space 应该如何使用。

同时将自己置于用户的位置,面临以下场景(可能还有更多):

  • 可用的 space 比您的 UI 所使用的多,并且您的 UI 并未将所有可用信息显示在屏幕上。如果有额外的 space?
  • ,您能否更改您的布局以提供更多信息
  • 可用的数量少于 UI 所需的数量 space。是否仍然可以轻松访问所有相关部分,例如通过滚动?

在 ActionListeners 上

您可以为许多组件设置一个动作侦听器,然后在执行某些动作(例如单击按钮)时调用该侦听器。要创建一个动作侦听器,您需要实现 ActionListener 接口及其 void actionPerformed(ActionEvent) 方法 - 就像您的 GUI 已经在做的那样。

因此,在 button.addActionListener(this); 中,您设置了 GUI 的当前封闭实例,this 指的是按钮的动作侦听器。

请注意,通常你要么有明确的 类 来实现 ActionListener,要么创建匿名的 类 或 lambda,例如像这样:

//pre-Java 8 way
button.addActionListener(new ActionListener(){ 
  public void actionPerformed(ActionEvent e) {
    System.out.println("button clicked");
  }
});

//using lambdas (ActionListener meets the requirements for functional interfaces)
button.addActionListener(actionEvent -> System.out.println("button clicked") );

致谢:感谢 Andrew Thompson 提供的宝贵意见:)