0
votes

Java JSlider ne s'affiche pas après l'utilisation de JFileChooser

Lorsque j'utilise JFileChooser et que j'essaye d'ajouter d'autres composants, ils n'apparaissent pas. Si je supprime JFileChooser, ils apparaissent. J'écris en java sur eclipse, et il y a deux fichiers.

J'ai supprimé la majorité de mon code pour simplifier le problème, mais il existe toujours.

Main.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");
            }
        }
    }
}

Frame.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);
        }
    }
}

Si vous l'exécutez sur votre propre ordinateur, vous pouvez sélectionner n'importe quel fichier pour le tester, car il ne fait rien avec le fichier sélectionné.

Je suis un peu nouveau sur JPanels et JFrames, donc tout conseil sera apprécié. Merci.


2 commentaires

NE JAMAIS, JAMAIS, modifier l'état du composant à partir de la méthode paintComponent - vous ne comprenez clairement pas comment fonctionne la peinture personnalisée (ou comment le système). Vous devez revenir aux bases, en commençant par Créer une interface graphique avec JFC / Swing et disposer les composants dans un conteneur


Quelle est la fonctionnalité que vous essayez d'atteindre?


3 Réponses :


0
votes

Suivez simplement la même idée, vous obtiendrez

public MyControlPanel() {
    initComponents();
    JSlider slider = new JSlider();
    slider.setMajorTickSpacing(10);
    slider.setPaintLabels(true);
    slider.setPaintTicks(true);

    JTextField boundary_length = new JTextField("Boundary Length");
    JTextField area = new JTextField("Area");

    setLayout(new FlowLayout());

    this.add(slider);
    this.add(area);
    this.add(boundary_length);

}


1 commentaires

Mais le problème est que même si j'appelle "this.add ()", le composant n'apparaît toujours pas.



1
votes

Tout d'abord, il n'y a absolument aucune raison de faire une peinture personnalisée. Vous ne devriez jamais essayer d'ajouter / supprimer des composants d'un JPanel dans une méthode de peinture.

Les composants doivent être ajoutés au panneau dans le constructeur de votre classe. Cela signifie donc que le bouton doit être ajouté au panneau.

Ensuite, vous ajoutez un ActionListener au bouton. Lorsque vous cliquez sur le bouton, vous effectuez un traitement.

Si vous souhaitez modifier les composants du panneau dans ActionListener la logique de base est la suivante:

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

Vous avez donc besoin de revalidate() pour appeler le gestionnaire de disposition. Sinon, la taille du composant ajouté est (0, 0), ce qui signifie qu'il n'y a rien à peindre.

Apprenez les bases de Swing en lisant le tutoriel Swing . Peut-être commencer par la section sur:

  1. Comment écrire un ActionListener
  2. Comment utiliser les curseurs
  3. Comment utiliser CardLayout (au lieu d'ajouter / supprimer des composants).


0 commentaires

0
votes

J'ai eu un problème similaire et j'ai trouvé la solution avec la méthode updateUI (). Regardez ci-dessous:

if(fileChooser.showOpenDialog(null) == 0 // this is the value for JFileChooser.APPROVE_OPTION) 
        { //if "Done" is selected
            menuNum = 1; //go to next menu
            first = true;
        }
else    {
            refresh();
        }

Ainsi, lorsque votre JFilechooser se ferme, vous devez appeler le refresh () ainsi:

private void refresh()
{
   if(slider != null)
        {
           slider.updateUI();
        }
}

J'espère que cela devrait fonctionner.


0 commentaires