javaswingjpaneljfilechooserjslider

Java JSlider not showing up after JFileChooser is used


When I use JFileChooser then try to add other components, they don't show up. If I remove JFileChooser they do show up. I'm writing in java on eclipse, and there are two files.

I have removed a majority of my code to simplify the problem, but it still exists.

Main.java:

import java.awt.Color;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import javax.swing.JFrame;

public class Main {
    public static void main(String args[]) throws InterruptedException, IOException {
        int width = 1280;
        int height = 720;

        Frame f = new Frame(Color.BLACK, width, height);
        JFrame frame = new JFrame("Title"); //create a new window and set title on window
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //set the window to close when the cross in the corner is pressed
        frame.setSize(width,height);

        frame.add(f); //add the content of the game object to the window
        frame.setVisible(true);

        long interval = (long)10 * 10000000;
        long t = 0;
        while(true) {
            if(System.nanoTime() - t >= interval) { //repaints at a certain fps
                t = System.nanoTime();
                f.repaint();
            }
            TimeUnit.NANOSECONDS.sleep(10);
        }
    }
}

Frame.java:

import java.awt.Color;
import java.awt.Graphics;
import java.io.IOException;
import javax.swing.JSlider;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JPanel;

public class Frame extends JPanel {
    int menuNum = 0;
    boolean first = true;

    JButton nextButton = new JButton("Next");
    JSlider slider = new JSlider(0,255,0);
    JFileChooser fileChooser = new JFileChooser();

    public Frame(Color background, int w, int h) throws IOException { //initialize
        this.setBackground(background);
        setFocusable(true);
    }

    public void paintComponent(Graphics G) {
        super.paintComponent(G);

        G.setColor(Color.WHITE);
        G.drawString("MenuNum: " + menuNum, 1000, 500); //for debugging

        if(menuNum == 0) { //first menu
            if(first) { //only run once
                first = false;

                this.removeAll();
                this.add(nextButton);

                System.out.println("HERE");
            }
            if(fileChooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) { //if "Done" is selected
                menuNum = 1; //go to next menu
                first = true;
            }
        }

        if(menuNum == 1) { //second menu
            if(first) { //only run once
                first = false;

                this.removeAll();
                this.add(nextButton);
                this.add(slider); //<This is the slider that is not showing up

                System.out.println("HERE2");
            }
        }
    }
}

If you are running this on your own machine, you can select any file to test it, since it does nothing with the selected file.

I am somewhat new to JPanels and JFrames so any advice will be well appreciated. Thanks.


Solution

  • First of all there is absolutely no reason to do any custom painting. You should never try to add/remove components from a JPanel in a painting method.

    The components should be added to the panel in the constructor of your class. So this means the button should be added to the panel.

    Then you add an ActionListener to the button. When the button is clicked you do some processing.

    If you want to alter the components on the panel in the ActionListener then the basic logic is:

    panel.remove(...);
    panel.add(...);
    panel.revalidate();
    panel.repaint();
    

    So you need the revalidate() to invoke the layout manager. Otherwise the size of the added component is (0, 0), which means there is nothing to paint.

    Learn Swing basics by reading the Swing Tutorial. Maybe start with section on:

    1. How to Write an ActionListener
    2. How to Use Sliders
    3. How to Use CardLayout (instead of adding/removing components).