Java 当JPanel发生变化时,旧JPanel的元素就被抛在了后面

Java 当JPanel发生变化时,旧JPanel的元素就被抛在了后面,java,swing,jpanel,jbutton,jtabbedpane,Java,Swing,Jpanel,Jbutton,Jtabbedpane,我使用的是JTabbedPane,每个选项卡上都有一个面板,当用户执行单击按钮之类的操作时,面板会发生变化。我遇到的问题是,上一个面板中的元素落后了。通常,只有将鼠标移到新面板上,才能看到它们,但有时,只有将鼠标移到它们应该位于的位置,才能看到新面板的元素。因此,通常一开始只有一点点可见,然后: 我有repaint()几乎每隔一行,在更改GUI上的任何内容之前,我会执行removeAll()第一,但它总是回来!有什么建议吗?此面板的代码如下,如果可能有帮助的话 package com.GC0

我使用的是JTabbedPane,每个选项卡上都有一个面板,当用户执行单击按钮之类的操作时,面板会发生变化。我遇到的问题是,上一个面板中的元素落后了。通常,只有将鼠标移到新面板上,才能看到它们,但有时,只有将鼠标移到它们应该位于的位置,才能看到新面板的元素。因此,通常一开始只有一点点可见,然后:

我有
repaint()几乎每隔一行,在更改GUI上的任何内容之前,我会执行
removeAll()第一,但它总是回来!有什么建议吗?此面板的代码如下,如果可能有帮助的话

package com.GC01.gui;

import java.awt.Color;

public class PracticeQuizPanel extends JPanel implements MouseListener {
    /**
     * This panel will allow the user to practice quiz questions.
     */
private static final long serialVersionUID = 1L;

private User user = new User("misha");

boolean isMultipleChoice=false;
boolean usedClue=false;
boolean isStarted=false;

Calendar calendar = Calendar.getInstance();
AnswerAnalysis aA = new AnswerAnalysis();   
private Quiz qz = new Quiz( Quiz.getQuestionsFromDisk(), 4, TabbedQuiz.getUser().getNumLogins() );

private JTextArea questionArea;
private JTextArea clueArea;
private JTextArea answerArea;

private JButton clueButton;
private JButton multiButton;
private JButton answerButton;
private JButton startButton; 

private int index=0;
private Calendar startCalendar, endCalendar;

private JPanel backPanel;

public PracticeQuizPanel(){
    add(new StartButtonPanel());
}

PracticeQuizPanel(int index) {
    createVisualElements(index);
}

public void offerAnswer(){
    endCalendar = Calendar.getInstance();
    aA.setTimeSpent((int) (endCalendar.getTimeInMillis()-startCalendar.getTimeInMillis()));
    aA.setRight(answerArea.getText());
    JOptionPane.showMessageDialog(null, aA.toString());
    answerArea.setEditable(false);
    qz.setAnswersAnalysis(index, aA);
    index++;
    removeAll(); 
    if( index<qz.getLength() ) createVisualElements(index);
    else {
        removeAll();
        JOptionPane.showMessageDialog(null, qz.toFriendlyString());
        addQuizResultsToUserProgress();
        JOptionPane.showMessageDialog(null, qz.toFriendlyString());
        UserProgress uP = new UserProgress(user);
        System.out.println(uP.toString());
    }
    repaint();
    startCalendar = Calendar.getInstance();
    //JOptionPane.showMessageDialog(null, isStarted);
}

public void addQuizResultsToUserProgress(){
    UserProgress userProgress = new UserProgress(user);
    ArrayList<AnswerAnalysis> asA = userProgress.getAnswersAnalysis();
    for (int i=0; i<qz.getLength(); i++){
        asA.add( qz.getAnswersAnalysis()[i]);
    }
    userProgress.setAnswersAnalysis(asA);
    userProgress.saveProgress();
}



/**
 * This method creates/recreates all the text boxes, buttons etc. without resetting the quiz and
 * the objects in memory.
 */
private void createVisualElements(int index){
    if (TabbedQuiz.getUser().getNumLogins()<0) 
        JOptionPane.showMessageDialog(null, "There was an error. You may have done this quiz before.");
    removeAll();
    repaint();
    startCalendar = Calendar.getInstance();
    this.index=index;
    setBackground(new Color(112, 128, 144)); 
    setBounds(0,0,728,380);
    setLayout(null);

    questionArea = new JTextArea();
    questionArea.setFont(TabbedQuiz.getDefaultFont().deriveFont(20));//new Font("Courier New", 0, 20));
    questionArea.setEditable(false);
    questionArea.setLineWrap(true);
    questionArea.setWrapStyleWord(true);
    questionArea.setBounds(295, 11, 423, 74);
    add(questionArea);
    //int index=0;
    Question q = qz.getQuestions().get(index);
    aA = new AnswerAnalysis(q.getQuestionID());
    questionArea.setText(q.getQuestionText() );

    clueArea = new JTextArea();
    clueArea.setFont(TabbedQuiz.getDefaultFont().deriveFont(20));
    clueArea.setEditable(false);
    clueArea.setLineWrap(true);
    clueArea.setWrapStyleWord(true);
    clueArea.setBounds(295, 104, 423, 55);
    add(clueArea);

    JLabel lblQuestion = new JLabel("QUESTION:");
    lblQuestion.setFont(TabbedQuiz.getDefaultFont().deriveFont(40));
    lblQuestion.setBounds(43, 11, 216, 61);
    add(lblQuestion);

    answerArea = new JTextArea();//index+"");
    answerArea.setFont(TabbedQuiz.getDefaultFont().deriveFont(20));
    answerArea.setLineWrap(true);
    answerArea.setWrapStyleWord(true);
    answerArea.setBounds(295, 301, 423, 50);
    answerArea.addKeyListener(new KeyAdapter() {
        @Override
        public void keyPressed(KeyEvent e) {
            if(e.getKeyCode() == KeyEvent.VK_ENTER) offerAnswer();
        }
    });

    add(answerArea);
    answerArea.setFocusable(true);
    answerArea.requestFocusInWindow();

    clueButton = new JButton("CLUE?");
    clueButton.setFont(TabbedQuiz.getDefaultFont().deriveFont(40));
    clueButton.addMouseListener(this);
    clueButton.setBounds(15, 104, 244, 55);
    add(clueButton);

    multiButton = new JButton("MULTIPLE CHOICE?");
    multiButton.setFont(TabbedQuiz.getDefaultFont().deriveFont(20));
    multiButton.addMouseListener(this);
    multiButton.setBounds(15, 195, 244, 55);
    add(multiButton);

    answerButton = new JButton("ANSWER!");
    answerButton.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent arg0) {
        }
    });
    answerButton.setFont(TabbedQuiz.getDefaultFont().deriveFont(40));
    answerButton.setBounds(15, 301, 244, 55);
    answerButton.addMouseListener(this);
    add(answerButton);

    backPanel = new JPanel();
    backPanel.setBounds(0, 0, 728, 380);
    //add(backPanel);

    this.setVisible(true);
    repaint();
}

@Override
public void mouseClicked(MouseEvent e) {
    if      ( e.getSource().equals(startButton)  ) {
        remove(startButton); repaint(); isStarted=true;
        startCalendar = Calendar.getInstance();
    }
    else if ( e.getSource().equals(answerButton) ) offerAnswer();
    else if ( e.getSource().equals(clueButton )  ) {
        clueArea.setText(clueArea.getText() + qz.getQuestions().get(index).getClueText() + "\n");
        aA.setUsedClue(true);
        //JOptionPane.showMessageDialog(null, "hi");
        }
    else if ( e.getSource().equals(multiButton)  ) {            
        String[] answerOptions = qz.getQuestions().get(index).getAnswerOptions(3);
        JButton[] optionsButtons = new JButton[4];
        for(int j=0;j<4;j++){
            optionsButtons[j]=new JButton(answerOptions[j]);
            if(optionsButtons[j].getText().length()>13) 
                optionsButtons[j].setFont(TabbedQuiz.getDefaultFont().deriveFont(10));
            else optionsButtons[j].setFont(TabbedQuiz.getDefaultFont().deriveFont(15));
            if(j<2) optionsButtons[j].setBounds(295+211*j       , 170, 211, 55);
            else    optionsButtons[j].setBounds(295+211*(j-2)   , 226, 211, 55);
            optionsButtons[j].addMouseListener(this);
            optionsButtons[j].setName("optionsButton"+"["+j+"]");
            add(optionsButtons[j]);
            repaint();
        }
        aA.setMultipleChoice(true);
    }
    else if ( ( (JButton) e.getSource() ).getName().startsWith("optionsButton") ) {
        String answerOffered = ( (JButton) e.getSource() ).getText();
        answerArea.setText(answerOffered);
        offerAnswer();
    }
}

@Override
public void mouseEntered(MouseEvent e) {
    if(e.getSource()!=startButton && e.getSource().getClass().equals( answerButton.getClass()) ){
        ( (JButton) e.getSource() ).setBackground(Color.green);
    }if(index>0 && e.getSource()==startButton) remove(startButton);
}

@Override
public void mouseExited(MouseEvent e) {
    if(e.getSource()!=startButton && e.getSource().getClass().equals( answerButton.getClass()) ){
        ( (JButton) e.getSource() ).setBackground(UIManager.getColor("control"));
    }
}

@Override
public void mousePressed(MouseEvent e) {
}

@Override
public void mouseReleased(MouseEvent e) {
}
}
package com.GC01.gui;
导入java.awt.Color;
公共类实践Quizpanel扩展JPanel实现MouseListener{
/**
*此面板将允许用户练习测验问题。
*/
私有静态最终长serialVersionUID=1L;
私人用户=新用户(“misha”);
布尔isMultipleChoice=false;
布尔usedClue=false;
布尔值isStarted=false;
日历=Calendar.getInstance();
AnswerAnalysis aA=新的AnswerAnalysis();
私人测验qz=新测验(quick.getQuestionsFromDisk(),4,tabbedquick.getUser().getNumLogins());
私人住宅区;
私人区域俱乐部;
私人区域应答区;
私人JButton clueButton;
私有JButton多按钮;
私人JButton answerButton;
私有JButton开始按钮;
私有整数指数=0;
私人日历开始日历,结束日历;
私人JPanel背板;
公共实践Quizpanel(){
添加(新的开始按钮面板());
}
实习指导小组(国际索引){
创建可视化元素(索引);
}
公开无效要约人(){
endCalendar=Calendar.getInstance();
aA.setTimePent((int)(endCalendar.getTimeInMillis()-startCalendar.getTimeInMillis());
aA.setRight(answerArea.getText());
showMessageDialog(null,aA.toString());
answerArea.setEditable(假);
qz.设定应答分析(指数,aA);
索引++;
removeAll();

如果(index您需要在使用布局管理器将组件移除或添加到容器后调用
revalidate
。然后调用
repaint

您发布了大量代码,其中大部分与当前问题完全无关,但另一方面,发布的代码不完整,无法编译,因此不是我们可以测试的代码。请下次尝试不要发布大量与问题无关的代码。尝试通过不断剪切代码来隔离问题,例如然后,如果仍然卡住,发布一个最小的可执行程序,我们可以自己学习、测试、运行和修改

我已经看过了您的一些GUI代码(看在上帝的份上,不是全部!),您在Swing绘制中遇到了一些大问题,例如ProgressPanel.java中的以下代码:

   public void paintComponent(Graphics g) {
      super.paintComponent(g);
      Graphics2D g2d = (Graphics2D) g;
      createAndShowGUI(g2d);
      // drawDifficultyChart(g2d, fontComboBox.getSelectedIndex());
   }

   private void createAndShowGUI(Graphics2D g2d) {
      JButton showChartButton = new JButton("Show new chart!");
      user = TabbedQuiz.getUser();
      showChartButton.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent e) {
            try {
               if (categoryComboBox.getSelectedIndex() == 0
                     && difficultyComboBox.getSelectedIndex() != 0) {
                  drawDifficultyChart((Graphics2D) getGraphics(),
                        difficultyComboBox.getSelectedIndex());
               } else if (difficultyComboBox.getSelectedIndex() == 0
                     && categoryComboBox.getSelectedIndex() != 0) {
                  drawCategoryChart((Graphics2D) getGraphics(),
                        (String) categoryComboBox.getSelectedItem());
               } else
                  drawGeneralChart((Graphics2D) getGraphics(),
                        (String) categoryComboBox.getSelectedItem(),
                        difficultyComboBox.getSelectedIndex());
            } catch (NullPointerException e1) {
               JOptionPane.showMessageDialog(null, "Sign in first.");
            }
         }
      });
      showChartButton.setBounds(10, 90, 96, 26);
      showChartButton.setFont(font);
      add(showChartButton);
   }

问题在于,您正在使用paint/paintComponent方法创建组件并将其添加到容器中,这是您永远不应该做的事情,而且肯定会弄乱程序的图形。

如果使用布局管理器,则在移除或添加组件到容器中后,需要调用
重新验证在您调用
重新绘制后

您发布了大量代码,其中大部分与当前问题完全无关,但另一方面,发布的代码不完整,无法编译,因此不是我们可以测试的代码。请下次尝试不要发布大量与问题无关的代码。尝试通过不断剪切代码来隔离问题,例如然后,如果仍然卡住,发布一个最小的可执行程序,我们可以自己学习、测试、运行和修改

我已经看过了您的一些GUI代码(看在上帝的份上,不是全部!),您在Swing绘制中遇到了一些大问题,例如ProgressPanel.java中的以下代码:

   public void paintComponent(Graphics g) {
      super.paintComponent(g);
      Graphics2D g2d = (Graphics2D) g;
      createAndShowGUI(g2d);
      // drawDifficultyChart(g2d, fontComboBox.getSelectedIndex());
   }

   private void createAndShowGUI(Graphics2D g2d) {
      JButton showChartButton = new JButton("Show new chart!");
      user = TabbedQuiz.getUser();
      showChartButton.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent e) {
            try {
               if (categoryComboBox.getSelectedIndex() == 0
                     && difficultyComboBox.getSelectedIndex() != 0) {
                  drawDifficultyChart((Graphics2D) getGraphics(),
                        difficultyComboBox.getSelectedIndex());
               } else if (difficultyComboBox.getSelectedIndex() == 0
                     && categoryComboBox.getSelectedIndex() != 0) {
                  drawCategoryChart((Graphics2D) getGraphics(),
                        (String) categoryComboBox.getSelectedItem());
               } else
                  drawGeneralChart((Graphics2D) getGraphics(),
                        (String) categoryComboBox.getSelectedItem(),
                        difficultyComboBox.getSelectedIndex());
            } catch (NullPointerException e1) {
               JOptionPane.showMessageDialog(null, "Sign in first.");
            }
         }
      });
      showChartButton.setBounds(10, 90, 96, 26);
      showChartButton.setFont(font);
      add(showChartButton);
   }
问题是,您正在从paint/paintComponent方法中创建组件并将其添加到容器中,这是您永远不应该做的事情,而且肯定会弄乱程序的图形

每个选项卡上都有一个面板,当用户点击按钮时,面板会发生变化

在更改GUI上的任何内容之前,请先删除所有()

每当我看到这样的评论,我觉得你应该使用一个新的,这样你就不必担心所有这些问题

每个选项卡上都有一个面板,当用户点击按钮时,面板会发生变化

在更改GUI上的任何内容之前,请先删除所有()


每当我看到这样的评论时,我觉得你应该使用一个,这样你就不必担心所有这些问题。

对于其他有此问题的人:我最终解决了这个问题。
setVisible(false);setVisible(true)
。把它放在任何地方。

对于其他有这个问题的人:我最终解决了这个问题。
setVisible(false);setVisible(true);
。把它放在任何地方。

我知道,对不起,我刚刚创建了一个相当大且庞大的项目。我会给
revalidate()
a现在就试试。谢谢!@user1002973:我正试图看完你的大量代码帖子,但是有太多悬而未决的引用,无法理解逻辑。我发现一个不相关的问题是,你为什么要将MouseListener添加到JButtons?没有意义,以后可能会导致问题。为什么不使用Actionlisteners呢?我使用了Mouse侦听器,因为当鼠标悬停在按钮上时,我希望按钮改变颜色。因此,没有必要为实际的单击使用单独的ActionListener。
revalidate()
似乎没有做到这一点,我可能用错了…如果我仍然无法解决它,我将尝试在单个类项目中重现该问题。这不是使用MouseListener的好理由。这样做会发生什么