第二个 JFrame 中的组件未显示 [英] Components in second JFrame not showing up

查看:29
本文介绍了第二个 JFrame 中的组件未显示的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

i want to start another JFrame from pressing a button in a JFrame. But if I press the Button it shows the JFrame but not the Buttons and Sliders in it.

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);


    }

}

第二个具有完全相同的 costructor.sliders 和按钮不是静态的.在按钮应该出现的地方,屏幕是黑色的.

The second has quite the same costructor.sliders and buttons are not static. At the places where Buttons should appear the screen is black.

希望你能帮助我:)

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 成为你调用的最后一件事...

Make setVisible the last thing you call...

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() 来鼓励容器在添加新组件时更新其布局

Also, use revalidate() and repaint() to encourage the container to update it's layout when adding new components

建议:

  • 确保您的 UI 在 EDT 的上下文中启动,请参阅 初始线程了解更多详情
  • 避免直接从 JFrame 等顶级容器扩展,而是考虑使用 JPanel 作为基础容器.这个免费的用户界面可以让您使用更广泛的用例,并防止您陷入困境(因为您无法将框架添加到其他框架)
  • 使用多个 JFrame,好/坏做法?
  • Make sure your UI is started within the context of the EDT, see Initial Threads for more details
  • Avoid extending directly from top level containers like JFrame and instead consider using a JPanel as you base container. This free's up you UI to a wider range of use-cases and prevents you from getting locked in (as you can't add frames to other frames)
  • The Use of Multiple JFrames, Good/Bad Practice?

更新

你有两个直接的问题

  1. ClickerJFrame 扩展而来,但是您正试图将其添加到另一个容器中,这在 Swing 中是不可能的并且会导致异常,但是...
  2. 您正在使用 while (true) 循环阻塞事件调度线程,这意味着 Swing 无法处理任何新事件,包括 repaint 事件
  1. Clicker extends from a JFrame, but you are trying to add it to another container, this is not possible in Swing and will cause an exception, however...
  2. You are blocking the Event Dispatching Thread with your while (true) loop, meaning that Swing is unable to process any new events, including repaint events

例如...

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 组件,它带来了许多其他问题,但我们没有相应的代码,因此无法评论.

Now, Click looks like it's UI component which brings up a bunch of other problems, but we don't have the code for that so it's impossible to comment.

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

The immediate solutions might be to use a:

  • SwingWorker, see Worker Threads and SwingWorker for more details

Swing Timer,参见 如何使用摆动计时器了解更多详情

Swing Timer, see How to use Swing Timers for more details

要记住的事情

  • Swing(与大多数 UI 框架一样)是单线程的,任何阻塞该线程的事物(例如永无止境的循环)都会阻止它处理新事件,包括绘制事件,这会使您的应用看起来像是挂起",因为它有
  • Swing 不是线程安全的.与 UI 的所有交互都必须在事件调度线程的上下文中进行.SwingWorker 和 Swing Timer 都提供了安全更新 UI 的能力.
  • Swing (like most UI frameworks) is single threaded, anything which blocks this thread (like never ending loops), will prevent it from processing new events, including paint events, which will make your application look like it's "hung", because it has
  • Swing is NOT thread safe. All interactions with the UI MUST be made from within the context of the Event Dispatching Thread. Both SwingWorker and Swing Timer provide the capability to update the UI safely.

这篇关于第二个 JFrame 中的组件未显示的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆