当JPanel更改时,旧JPanel的元素会被遗忘

时间:2011-11-11 01:26:47

标签: java swing jpanel jbutton jtabbedpane

我正在使用JTabbedPane,并且在每个选项卡上都有一个面板,当用户执行单击按钮等操作时,该面板会发生变化。我得到的问题是前一个面板中的元素被遗忘。通常在鼠标悬停在它们之前看不到它们,但有时你看不到 new 面板的元素,直到你将鼠标放在 所在的位置上是。所以通常起初只有一点点可见,然后:

when you run your mouse over more stuff it becomes visible

Then for some reason when you hit 'multiple choice', which is supposed to create the four new buttons, everything becomes perfectly visible

我几乎每一行都有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) {
}
}

3 个答案:

答案 0 :(得分:3)

  

并且在每个选项卡上都有一个面板,当用户执行单击按钮等操作时,该面板会发生变化。

     

在我更改GUI上的任何内容之前,我会删除所有();

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

答案 1 :(得分:2)

如果使用布局管理器,则需要在删除或向容器添加组件后调用revalidate。然后你打电话给repaint

你发布了很多代码,其中大部分与手头的问题完全无关,但另一方面,发布的代码不完整,无法编译,因此不是代码,我们可以测试。请下次尝试不发布大量与问题无关的代码。尝试通过不断删除代码来隔离问题,然后如果仍然卡住,发布一个我们可以研究,测试,运行和修改自己的最小 compiable 程序,sscce。< / p>

我已经浏览了一些你的GUI代码(为了gosh的缘故,不是全部!),并且那里有一些很大的时间,你正在踩着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方法中创建容器并将其添加到容器中,这是你永远不应该做的事情以及必然会弄乱程序图形的东西。

答案 2 :(得分:0)

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