简体   繁体   中英

Components in second JFrame not showing up

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


    }

}

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

Hope you can help me :)

EDIT:

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

}

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

}

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

Recommendations:

  • 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?

Updated

You have two immediate problems

  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

For example...

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

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:

Things to remember

  • 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.

Try with repaint() or revalidate() at the end of you constructor. And also try with calling setVisible(true) at the end.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM