java - 第二个 JFrame 中的组件未显示

标签 java swing user-interface jframe jbutton

我想通过按下 JFrame 中的按钮来启动另一个 JFrame。 但是,如果我按下按钮,它会显示 JFrame,但不会显示其中的按钮和 slider 。

public class MainMenu extends JFrame {


private JFrame klick;
private static final long serialVersionUID = 9002;


public static void main(String[] args) {

    new MainMenu();

}


public MainMenu() {
    buildGUI1();

}
public void buildGUI1() throws NullPointerException {
    setTitle("Hauptmenü");      
    setSize(800, 480);
    setLayout(new GridLayout());
    setAlwaysOnTop(false);
    setLocation((Toolkit.getDefaultToolkit().getScreenSize().width)/4, (Toolkit.getDefaultToolkit().getScreenSize().height)/4);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setResizable(false);
    setVisible(true);
    final JButton startclickbt = new JButton("Start Clicker");
    startclickbt.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            dispose();
            if(klick == null ) {
                klick =new Clicker();
                add(klick);
            }


        }
    });

    add(startclickbt);


    }

}

第二个具有完全相同的构造函数。 slider 和按钮不是静态的。 在按钮应该出现的地方,屏幕是黑色的。

希望你能帮助我:)

编辑:

public class Clicker extends JFrame {

    private static final long serialVersionUID = 9001;
    protected JPanel panel;
    static Click j = null;
    protected JSlider jsl;
    protected JTextField tf;
    static final int CPS_MIN= 0;
    static final int CPS_MAX= 100;
    static final int CPS_INIT= 25;
    private int amount;
    private boolean visible;

    public int getDelay() {
        return Math.abs(jsl.getValue()-100);
    }
    public int getAmount() {
        return amount;
    }
    public boolean getVisible() {
        return visible;
    }
    public void setOpen(boolean visible) {
        this.visible=visible;
    }

    public Clicker(boolean visible) {

        buildGUI(visible);
        j = new Click(false).addPosition(new Point((Toolkit.getDefaultToolkit().getScreenSize().width)/2, (Toolkit.getDefaultToolkit().getScreenSize().height)/2)).addPosition(new Point(getLocation().x+1, getLocation().y+20));
        while(true) {

            j.runClicks(getDelay());
        }
    }

    public Clicker() {
        buildGUI(true);
        j = new Click(false).addPosition(new Point((Toolkit.getDefaultToolkit().getScreenSize().width)/2, (Toolkit.getDefaultToolkit().getScreenSize().height)/2)).addPosition(new Point(getLocation().x+1, getLocation().y+20));
        while(true) {

            j.runClicks(getDelay());
        }
    }
    public void buildGUI(boolean visible) {

        setTitle("Clicker");
        setSize(340, 200);
        setLayout(new GridLayout());
        setAlwaysOnTop(true);
        setLocation(0, 0);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setResizable(false);
        setVisible(visible);

        final JButton bt1 = new JButton("Schließen");
        bt1.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                System.exit(0);
            }
        });
        final JButton bt2 = new JButton("Start  ");
        bt2.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                j.setClick(true);
            }
        });
        final JButton bt3 = new JButton("Stop       ");
        bt3.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                j.setClick(false);
                JOptionPane.showMessageDialog(null, "Klicken gestoppt. Klicks: " + j.getClickAmount());
                j.setClickAmout(0);
            }
        });
        final JButton bt4 = new JButton("StartAnzahl");
        bt4.addActionListener(new ActionListener() {
            private int amount;

            public void actionPerformed(ActionEvent e) {
                String wert = tf.getText();
                try {
                    amount = Integer.parseInt(wert);
                }catch(Exception ee) {
                    JOptionPane.showMessageDialog(null,"Das war keine Zahl oder mehr als ein Integer");
                }

                j.doClick(amount);


            }
        });
        tf = new JTextField("Anzahl gewünschte Clicks max "+ Integer.MAX_VALUE, 10);
        tf.setEditable(true);


        jsl = new JSlider(JSlider.HORIZONTAL,CPS_MIN,CPS_MAX,CPS_INIT);
        jsl.setMinorTickSpacing(5);
        jsl.setMajorTickSpacing(10);
        jsl.setPaintTicks(true);
        jsl.setPaintLabels(true);

        panel = new JPanel();
        panel.addMouseMotionListener(new MouseMotionListener() {

            @Override
            public void mouseDragged(MouseEvent event) {
                j.setClick(false);  
            }

            @Override
            public void mouseMoved(MouseEvent event) {
                j.setClick(false);          
            }
        });

        panel.addKeyListener(new KeyAdapter() {

            @Override
            public void keyPressed(KeyEvent e) {
                if(e.getKeyCode() == KeyEvent.VK_F1) {
                    j.setClick(true);
                }
                if(e.getKeyCode() == KeyEvent.VK_F2) {
                    j.setClick(false);
                }
            }

        });


        add(panel);
        add(bt2);
        add(bt3);
        add(bt1);
        add(bt4);
        add(jsl);
        add(tf);

        pack();
    }

}

最佳答案

setVisible 设为您最后调用的...

public void buildGUI1() throws NullPointerException {
    setTitle("Hauptmenü");
    setSize(800, 480);
    setLayout(new GridLayout());
    setAlwaysOnTop(false);
    setLocation((Toolkit.getDefaultToolkit().getScreenSize().width) / 4, (Toolkit.getDefaultToolkit().getScreenSize().height) / 4);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setResizable(false);
    final JButton startclickbt = new JButton("Start Clicker");
    startclickbt.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            dispose();
            if (klick == null) {
                klick = new Clicker();
                add(klick);
                // Add this when you need to add/remove components
                revalidate();
                repaint();
            }

        }
    });

    add(startclickbt);
    // Move to here
    setVisible(true);

}

此外,使用 revalidate()repaint() 鼓励容器在添加新组件时更新其布局

建议:

  • 确保您的 UI 在 EDT 上下文中启动,请参阅 Initial Threads了解更多详情
  • 避免直接从 JFrame 等顶级容器进行扩展,而是考虑使用 JPanel 作为基础容器。这样可以让您的 UI 适应更广泛的用例,并防止您被锁定(因为您无法将框架添加到其他框架)
  • The Use of Multiple JFrames, Good/Bad Practice?

已更新

您有两个迫在眉睫的问题

  1. ClickerJFrame 扩展而来,但您试图将其添加到另一个容器,这在 Swing 中是不可能的,并且会导致异常,但是...
  2. 您正在使用 while (true) 循环阻塞事件调度线程,这意味着 Swing 无法处理任何新事件,包括 repaint 事件

例如...

public Clicker(boolean visible) {

    buildGUI(visible);
    j = new Click(false).addPosition(new Point((Toolkit.getDefaultToolkit().getScreenSize().width) / 2, (Toolkit.getDefaultToolkit().getScreenSize().height) / 2)).addPosition(new Point(getLocation().x + 1, getLocation().y + 20));
    // This is bad
    while (true) {

        j.runClicks(getDelay());
    }
}

public Clicker() {
    buildGUI(true);
    j = new Click(false).addPosition(new Point((Toolkit.getDefaultToolkit().getScreenSize().width) / 2, (Toolkit.getDefaultToolkit().getScreenSize().height) / 2)).addPosition(new Point(getLocation().x + 1, getLocation().y + 20));
    // This is bad
    while (true) {

        j.runClicks(getDelay());
    }
}

现在,Click 看起来像是 UI 组件,会带来许多其他问题,但我们没有相应的代码,因此无法发表评论。

直接的解决方案可能是使用:

要记住的事情

  • Swing(像大多数 UI 框架一样)是单线程的,任何阻塞该线程的东西(比如永无休止的循环)都会阻止它处理新事件,包括绘制事件,这将使您的应用程序看起来像是“挂起”,因为它有
  • Swing 不是线程安全的。与 UI 的所有交互都必须在事件调度线程的上下文中进行。 SwingWorker 和 Swing Timer 都提供安全更新 UI 的功能。

关于java - 第二个 JFrame 中的组件未显示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31599723/

相关文章:

java - 本地方法调用中的 EJB 事务

java - 从Java中的另一个方法调用paint()

java - 将 JPanel 包裹在 JCheckBox 周围,不留任何空间 - Swing

c# - 如何在单击游戏对象时创建菜单? (统一)

java - SonarQube,finally block 中的跳转语句(squid :S1143)

java - 尝试反序列化对象时出错

java - 3 级可扩展 ListView 第三级被截断

java - 如何使用 Swing 暂停 Java 模拟

c++ - 未定义对 QMediaPlayer 和 QVideoWidget 的引用

java - 在鼠标事件上添加 Java GUI 组件