【问题标题】:How do you create a label inside actionPerformed after a click?点击后如何在 actionPerformed 中创建标签?
【发布时间】:2014-05-07 07:50:19
【问题描述】:

点击后如何创建标签? (我必须在actionPerformed方法中创建一个标签,不要问我为什么)ty!

 public static void main (String [] args)
 {
       JFrame Frame = new JFrame ();
       Frame.setSize(WIDTH_FRAME,HEIGHT_FRAME);
       Frame.setLayout(null);
       JButton Button = new JButton("x");
       Button.setBounds(a,b,c,d);
       Button.addActionListener(new ActionListener() {
                                 public void actionPerformed(ActionEvent e) {

             JLabel v = new JLabel ("xxxxxxxxxx");
            v.setBounds(50,50,50,50);
          Frame.add(v);
          Frame.revalidate();
          Frame.repaint();
          }
       });

       Frame.add(Button);
       Frame.setVisible(true);

【问题讨论】:

  • "..不要问我为什么.." 为什么? (不要告诉我/我们该怎么做。)
  • 遵循 Java 命名约定。变量名不应以大写字符开头。

标签: java swing user-interface scope jlabel


【解决方案1】:

您了解范围的概念吗? JLabel v 是本地范围的,不能从 actionPerformed 外部访问。你可以把Frame.add(v);里面放在actionPerformed里面。然后你需要 revalidate()repaint() 框架,就像在运行时添加组件时应该做的那样


旁注

  • null 布局会导致很多问题,因此您应该考虑使用布局管理器。查看Laying out Components Within a Container 了解更多详情。

  • Swing 应用程序应在事件调度线程上运行。您可以通过将main 中的代码包装在SwingUtilities.invokeLater(...) 中来实现。更多信息请访问Initial Threads

  • 注意setBounds 的硬编码值。这将导致只有一个添加的标签可见。我强烈建议研究像FlowLayoutBoxLayout 这样的布局管理器。使动态添加组件更加“自然”的布局。


框布局示例

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;

public class BoxLayoutDemo {

    private Box box;
    private int count = 1;
    public BoxLayoutDemo() {
        box = Box.createVerticalBox();
        JButton button = createButton();

        JScrollPane scroll = new JScrollPane(box);
        scroll.setPreferredSize(new Dimension(200, 300));
        JFrame frame = new JFrame();
        frame.add(scroll);
        frame.add(button, BorderLayout.NORTH);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    private JButton createButton() {
        JButton button = new JButton("Add Label");
        button.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e) {
                box.add(new JLabel("JLabel " + count));
                box.add(Box.createVerticalStrut(10));
                box.revalidate();
                box.repaint();
                count++;
            }
        });
        return button;
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable(){
            public void run() {
                new BoxLayoutDemo();
            }
        });
    }
}

【讨论】:

  • 在运行时添加组件时也需要调用Frame.revalidate(); Frame.repaint();
  • 你能举个例子吗?
  • 为什么需要示例?我只是告诉你你需要做什么。 Frame.add(v); Frame.revalidate(); Frame.repaint();
  • @MadProgrammer 好像是这样。
  • 我编辑了我的代码,你能检查一下吗?但我如何实例化框架?只是“JFrame 框架”?
【解决方案2】:

您似乎没有事件驱动环境的概念,并且正在以程序化方式思考......

这...

Button.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) {
        JLabel v = new JLabel ("xxxxxxxxxx");
        v.setBounds(50,50,50,50);
    }
});

actionPerformed 执行时不调用方法,因此v 在你点击的时候还没有创建

Frame.add(v);  // this does not work

尽管v 具有actionPerformed 方法的本地内容并且不能被外部引用。

actionPerformed 只会在Button 以某种支付方式被操作(即用户点击它)时被调用。

相反,您应该做一些类似...的事情

Button.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) {
        JLabel v = new JLabel ("xxxxxxxxxx");
        v.setBounds(50,50,50,50);
        Frame.add(v);
    }
});

但是现在你遇到了另一个问题,Frame 只有main 方法的本地上下文。您可以通过将Frame 声明为final 来纠正此问题...

final JFrame Frame = new JFrame ();

注意事项:

其中大部分都在迭代并支持 peeskillet (+1) 并已完成,因为它很重要并完善了答案

  • 不要使用null 布局。 Swing 旨在与布局管理器一起使用,如果没有它们,您将无法更新屏幕,此外,像素完美布局是现代用户界面设计中的一种错觉,您无法控制字体、渲染管道或其他目标系统的某些方面可能会影响文本等大型元素的呈现方式。
  • 通读并理解Initial Threads
  • 通读并使用Code Conventions for the Java Programming Language

【讨论】:

  • 我放了final,但是当我点击按钮时,什么都没有显示。我也尝试删除 Frame.setLayout(null);,但是按钮变得超级大....
  • 尝试将布局管理器设置为FlowLayoutFrame.setLayout(new FlowLayout()),添加标签后添加Frame.revalidate()和可能的Frame.repaint()
猜你喜欢
  • 1970-01-01
  • 2013-07-05
  • 1970-01-01
  • 1970-01-01
  • 2020-05-15
  • 1970-01-01
  • 2011-09-11
  • 1970-01-01
  • 2016-06-19
相关资源
最近更新 更多