当 JPanel 更改时,旧 JPanel 的元素会被留下

发布于 2024-12-14 13:31:28 字数 8001 浏览 4 评论 0原文

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

当您将鼠标移到更多内容上时,它就会变得可见< /a>

然后由于某种原因,当您点击“多项选择”时,应该创建四个新按钮,一切都变得完美可见

我已经得到了 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) {
}
}

I'm using a JTabbedPane, and on each tab there's a panel, which changes when the user does things like click buttons. The problem I'm getting is that elements from the previous panel get left behind. Usually you can't see them until you run the mouse over them, but sometimes you can't see elements of the new panel until you run your mouse over where they should be. So quite often at first only a little is visible, then:

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.

I've got repaint(); as pretty much every other line, and before I change anything on the GUI I do removeAll(); first, but it all keeps coming back! Any suggestions? The code for this panel is below, if it might help...

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) {
}
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

一袭白衣梦中忆 2024-12-21 13:31:28

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

在我更改 GUI 上的任何内容之前,我会执行 removeAll();

每当我看到这样的评论时,我觉得你应该使用 卡片布局让您不必担心所有这些问题。

and on each tab there's a panel, which changes when the user does things like click buttons.

and before I change anything on the GUI I do removeAll();

Whenever I see comments like that it sounds to me like you should be using a Card Layout so you don't have to worry about all these problems.

傲鸠 2024-12-21 13:31:28

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

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

我已经浏览了您的一些 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 方法中创建组件并将其添加到容器中,这是您永远不应该做的事情,而且肯定会弄乱程序的图形。

You need to call revalidate after removing or adding components to a container if using layout managers. Then after that you call repaint.

You've posted a lot of code, and most of it is completely unrelated to the problem at hand, but on the other hand, the code posted is incomplete, won't compile, and thus is not code that we can test. Please next time, try not posting a lot of code that's not relevant to the problem. Try to isolate the problem by continually cutting out code, and then if still stuck, post a minimal compiable program that we can study, test, run, and modify ourselves, an sscce.

I've gone through some of your GUI code (for gosh's sake, not all!), and there's some big time badness there where you're stepping on Swing painting such as this code from 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);
   }

The problem is that you're creating and adding components to a container from within a paint/paintComponent method, something you should never be doing and something that is bound to mess up your program's graphics.

鹿! 2024-12-21 13:31:28

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

To anyone else with this issue: I eventually solved the problem. setVisible(false); setVisible(true);. Put it EVERYWHERE.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文