0

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

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

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

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

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

我对 JPanels 和 JFrames 有点陌生,所以任何建议都将不胜感激。谢谢。

4

3 回答 3

1

首先,绝对没有理由进行任何定制绘画。您永远不应该尝试在绘画方法中从 JPanel 中添加/删除组件。

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

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

如果要更改面板上的组件,ActionListener那么基本逻辑是:

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

所以你需要revalidate()调用布局管理器。否则添加的组件的大小为 (0, 0),这意味着没有要绘制的内容。

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

  1. 如何编写 ActionListener
  2. 如何使用滑块
  3. 如何使用 CardLayout(而不是添加/删除组件)。
于 2019-07-01T14:37:53.033 回答
0

只要遵循同样的想法,你会得到

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

}
于 2019-07-01T03:46:26.400 回答
0

我有一个类似的问题,我找到了 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();
        }

我希望这应该有效。

于 2020-11-25T23:51:05.693 回答