【问题标题】:Creating a JButton with the click of a JButton通过单击 JButton 创建 JButton
【发布时间】:2019-07-10 00:17:26
【问题描述】:

我正在做一个项目,我需要单击一个按钮来制作另一个按钮。最终,我希望能够更好地控制新按钮的定位并能够多次创建新按钮,但现在......我只想让一个 JButton 创建另一个 JButton。

使用下面的代码,我的目标是让白色 B1 创建一个红色 B3 按钮。我还希望蓝色 B2 按钮创建一个绿色 B4 按钮。

最后,我还希望 B3 和 B4(从按钮生成的按钮)让用户能够单击它们并使其消失。

两个按钮似乎都没有做任何事情,我不知道为什么。我有 3 个类文件。知道我哪里可能出错了吗?

Window.Java

package gui;

import javax.swing.JFrame;

public class Window {

public static void main(String[] args) {

    //frame creation
    JFrame frame = new MainFrame("Button Create Button Test");

    //frame size
    frame.setSize(800, 800);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible(true);

}
}

DetailsPanel.Java

package gui;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class DetailsPanel extends JPanel {
    public DetailsPanel() {
        Dimension size = getPreferredSize();
        size.width = 400;
        setPreferredSize(size);

        ///Buttons

        JButton button1 = new JButton("B1");
        button1.setPreferredSize(new Dimension (72, 73));
        button1.setBackground(Color.WHITE);
        button1.setBorderPainted(true);

        JButton button2 = new JButton("B2");
        button2.setPreferredSize(new Dimension (72, 73));
        button2.setBackground(Color.BLUE);
        button2.setBorderPainted(true);


        setLayout (new GridBagLayout());

        GridBagConstraints gc = new GridBagConstraints();

        /// Layout ///
        /// Row 1 ///

        gc.anchor = GridBagConstraints.NORTH;

        gc.weightx = 0.5;
        gc.weighty = 0.5;

        gc.gridx = 1;
        gc.gridy = 1;

        add(button1, gc);

        gc.gridx = 1;
        gc.gridy = 2;

        add(button2, gc);

        button1.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                JButton button3 = new JButton("B3");
                button3.setPreferredSize(new Dimension (72, 73));
                button3.setBackground(Color.RED);
                button3.setBorderPainted(true);

                gc.gridx = 1;
                gc.gridy = 3;

                add(button3, gc);
            }
        });

        button2.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                JButton button4 = new JButton("B3");
                button4.setPreferredSize(new Dimension (72, 73));
                button4.setBackground(Color.GREEN);
                button4.setBorderPainted(true);

                gc.gridx = 1;
                gc.gridy = 4;

                add(button4, gc);
            }
        });
    }
}

MainFrame.Java

    package gui;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextArea;

public class MainFrame extends JFrame {

    private DetailsPanel detailsPanel;

    public MainFrame(String title) {
        super(title);

        // set layout manager
        setLayout (new BorderLayout());

        // Create Swing Component
        detailsPanel = new DetailsPanel();
        detailsPanel.setBackground(Color.BLACK);

        // Add swing components to content pane
        Container container = getContentPane();

        container.add(detailsPanel, BorderLayout.WEST);



            }       
    }

【问题讨论】:

  • 嗯,为什么不预先创建按钮并让它们可见?
  • 对于我最终想做的事情,它对我不起作用。最终,我将拥有更多的按钮 70+,而不是另一个很棒的按钮,但在 GUI 的较小面板中一次只能显示 5-10 个。我也想让它动态化。因此,如果我单击 B1,然后单击 B2,它会创建 B3 和 B4,并按该顺序显示。如果我单击 B2 然后 B1 然后它显示 B4 和 B3 (再次按视觉顺序)。 B3 左侧的 B4。希望这是有道理的
  • “希望这是有道理的” 我希望有一匹会排泄冰淇淋的飞行小马。看来我们俩今天的希望都不会实现。 创建所有这些按钮的最终目的是什么?如果按钮具有有意义的名称(例如 processStep7)来暗示它们的用途,将会有所帮助。
  • 在您的Window 类中,您不会向JFrame 添加任何组件。你确定你没有不小心遗漏了一些代码吗? MainFrame.java 的内容也与DetailsPanel.java 相同。这也是意外吗?
  • 感谢您的关注!我已经更新了代码以反映正确的课程信息!

标签: java swing user-interface jbutton software-design


【解决方案1】:

为了在单击按钮 B1 后显示按钮 B3,您需要添加...

revalidate();
repaint();

行后...

add(button3, gc);

在文件DetailsPanel.java.
按钮 B2 也是如此。

【讨论】:

    【解决方案2】:

    添加按钮后,您必须触发布局管理器的重绘。

    之后

      add(button3, gc);
    

    添加

    invalidate();
    validate();
    

    有关详细信息,请参阅 Swing 文档和 invalidate() 和 validate() 的 javadoc。

    【讨论】:

    • FYI revalidate 会同时调用这两者并且更容易输入......因为我很懒 ;)
    • 感谢上述cmets。我对重新验证和重新绘制进行了更多研究,这似乎是我需要实现的,但我不确定我是否找到了这样做的方法。我不确定是框架、面板还是其他需要重新粉刷的东西。我尝试将它放在按钮 1 和按钮 2 动作事件中,但没有任何运气。
    猜你喜欢
    • 2019-12-11
    • 2012-04-01
    • 2012-12-10
    • 2014-10-20
    • 2022-06-30
    • 2016-11-20
    • 1970-01-01
    • 2011-07-16
    • 1970-01-01
    相关资源
    最近更新 更多