Java 使用 JFileChooser 后 JSlider 不显示

Java JSlider not showing up after JFileChooser is used

当我使用 JFileChooser 然后尝试添加其他组件时,它们没有出现。如果我删除 JFileChooser,它们就会出现。我在eclipse上写java,有两个文件。

我删除了大部分代码以简化问题,但它仍然存在。

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

如果您在自己的机器上 运行 这个,您可以 select 任何文件来测试它,因为它对 selected 文件没有任何作用。

我对 JPanels 和 JFrames 比较陌生,因此非常感谢任何建议。 谢谢

按照同样的思路,你会得到

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

}

首先,绝对没有理由做任何定制绘画。您永远不应该尝试 add/remove 绘画方法中的 JPanel 组件。

应该在 class 的构造函数中将组件添加到面板中。所以这意味着应该将按钮添加到面板中。

然后在按钮上添加 ActionListener。单击按钮时,您会进行一些处理。

如果你想改变ActionListener面板上的组件,那么基本逻辑是:

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

因此您需要 revalidate() 来调用布局管理器。否则添加的组件大小为(0, 0),表示没有东西可以画

通过阅读 Swing Tutorial 学习 Swing 基础知识。也许从以下部分开始:

  1. 如何编写 ActionListener
  2. 如何使用滑块
  3. 如何使用 CardLayout(而不是 adding/removing 组件)。

我遇到了类似的问题,我用 updateUI() 方法找到了解决方案。往下看:

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

因此,当您的 JFilechooser 关闭时,您必须这样调用 refresh():

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

我希望这能奏效。