JScrollPane + JPanel

Crom
Crom used Ask the Experts™
on
My problem is that I have this class that extends JApplet and has 3 JPanel and an instance from another class that extends JPanel (I will call it class2) inside it.

My problem is that I'm inserting class2 inside a JScrollPane than I insert JScrollPane inside my JApplet, but whenever I move my JScrollPane which should just move the content from class2 (lines, numbers, ...), but I'm getting a messed screen like if the computer was mixing the old content (before using JScrollPane) with the new content (after moving)...something like the JScrollPane listener isnt refreshing the screen when I use it.

If anyone know a fix for this, please contact me and if you want to check the code, email me (marcos@dytz.com.br).
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®

Commented:
A few common problems with JScrollPane and overridden JPanels:

- Overriding a paint(Graphics) or paintComponent(Graphics) method without first calling super.paintComponent(...).
- Explicitly calling repaint() can cause problems.
- JScrollPane uses the preferred size of its viewport to scroll. Set the preferred size of the components within the scrollpane

Can you post a smaller example that demonstrates the problem? You will probably get more people willing to help you if you post some code.

Author

Commented:
package huffman;

// Bibliotecas que fazem parte da implementagco do applet
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import java.util.*;
import javax.swing.*;
import java.text.DecimalFormat;

public class Huff extends JApplet implements ActionListener, ComponentListener {

/******************************************************************************
 *
 * Objetos que farco parte da GUI do programa, onde se tem a ocorrencia de
 *  dois botoes para o controle do fluxo do programa, uma caixa para a entrada
 *  das probabilidades, um classe instanciada para controlar as mensagens ao
 *  usuario e outra que fara a apresentagco de todo contezdo
 *
 * Declaragco de todas as variaveis utilizadas para armazenar as probabilidades
 *  onde o maior nzmero de variaives que podem ser implementadas i 20 *
 *
 ******************************************************************************/
  JButton reset_button, step_button, end_button;
  JTextField input_string;
  cent Cent = new cent();
  ErrorCanvas stdout = new ErrorCanvas();
  DecimalFormat f = new DecimalFormat("0.000"); // Define um formato para os valores
  DecimalFormat f2 = new DecimalFormat("0.00");
  JScrollPane scroll = new JScrollPane(Cent);

  boolean inAnApplet = true;                    // Testa a validade do applet
  protected int numProbabilidade;               // Numero total de probabilidades
  protected int numProbabilidadeTemp;           // Numero total de probabilidades
  protected int[] marcador;                     // Marca a prsxima probabilidade
  protected double[][] probabilidade;
  protected String[][] simbolo;                 // Guarda os csdigos binarios
  protected int passo;                          // Controle quanto ao fim das probs.
  protected boolean proximo = true;             // Idem acima
  double entropia = 0.0;                        // Entropia;
  protected boolean inic = true;

/******************************************************************************
 *
 * Construtor para a classe Huff (inicializa todo o GUI)
 *
 ******************************************************************************/

  public Huff() {

//    JPanel centFrame = new JPanel();
    getContentPane().setLayout(new BorderLayout());
    scroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
    scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
//    centFrame.add(Cent);
    //scroll.add(Cent);
    getContentPane().add("Center", scroll);
//    getContentPane().add("Center", Cent);
    Font def = new Font("Dialog", 0, 12);
    Cent.setFont(def);
//    Panel r = new Panel(new BorderLayout());
//    r.setSize(800,600);
//    r.add(Cent);
//    scroll.add(r);
//    add(scroll, "Center");
//    scroll.add(Cent);
//    add(scroll,"Center");

    JPanel  p = new JPanel(new GridLayout(2, 0));
    JPanel  q = new JPanel(new GridLayout(2, 0));
    JPanel  r = new JPanel(new FlowLayout());
//    p.getContentPane().setLayout(new GridLayout(2, 0));
//    r.getContentPane().setLayout(new FlowLayout());
    r.add(reset_button = new JButton("Reiniciar"));
    r.add(step_button = new JButton("Proximo"));
    r.add(end_button = new JButton("Concluir"));
    p.add(r);
    p.add(input_string = new JTextField());

/******************************************************************************
 *
 *  O visualizador grafico que i utilizado por ErrorCanvas para emitir
 *   mensagens para o usuario
 *
 ******************************************************************************/
//    q.getContentPane().setLayout(new GridLayout(2, 0));
    q.add(p);
    q.add(stdout);
    getContentPane().add("South", q);
    reset_button.addActionListener(this);
    step_button.addActionListener(this);
    end_button.addActionListener(this);
    input_string.addActionListener(this);
    scroll.addComponentListener(this);
  }

/******************************************************************************
 *
 *  Mitodo utilizado para inicializar o mndice dos arrays utilizados e zerar
 *   o valor de todas as probabilidades utilizadas
 *
 ******************************************************************************/
  public void init()  {

    marcador = new int[200];
    probabilidade = new double[200][400];
//    probabilidade = new double[20][25];
    simbolo = new String[200][250];

    for(int i = 0; i < 200; i++)
      for(int j = 0; j < 400; j++) {
        probabilidade[i][j]=0.0;
      }

    JOptionPane.showMessageDialog(null, " ", "Bem vindo",
        JOptionPane.INFORMATION_MESSAGE);
    if(inic)
      iniciarProbabilidade(probabilidade[0]);
    this.reset();
  }
/*****************************************************************************/
  void contarProbabilidade() {

    StringTokenizer st = new StringTokenizer(input_string.getText());
    double teste = 0.0;

    if(input_string.getText().length() > 0 && input_string.getText() != null) {
      while (st.hasMoreTokens()) {
        try {
          teste = Double.valueOf(st.nextToken()).doubleValue();
          if(teste < 0) {
            JOptionPane.showMessageDialog(null,"Probabilidade negativa.", "Erro",
                JOptionPane.ERROR_MESSAGE);
            input_string.setText("");
            numProbabilidade = 0;
            break;
//            return(false);
          }
          if(teste > 1.0) {
            JOptionPane.showMessageDialog(null,"Probabilidade maior que 1.", "Erro",
                JOptionPane.ERROR_MESSAGE);
            input_string.setText("");
            numProbabilidade = 0;
            break;
//            return(false);
          }
          if(teste == 0.0) {
            JOptionPane.showMessageDialog(null,"Probabilidade igual a 0.", "Erro",
                JOptionPane.ERROR_MESSAGE);
            input_string.setText("");
            numProbabilidade = 0;
            break;
//            return(false);
          }
        } catch (NumberFormatException e) {
          JOptionPane.showMessageDialog(null,"Entrada incorreta.", "Erro",
              JOptionPane.ERROR_MESSAGE);
          input_string.setText("");
          numProbabilidade = 0;
          break;
//          return(false);
        }
        numProbabilidade++;
        if(numProbabilidade > 200)
          if(st.hasMoreTokens()) {
            JOptionPane.showMessageDialog(null,"Sco permitidos ati 200 probabilidade",
             "Erro", JOptionPane.ERROR_MESSAGE);
            input_string.setText("");
            numProbabilidade = 0;
            break;
          }
      }
    } else
     JOptionPane.showMessageDialog(null,"Insria algum valor.",
       "Erro", JOptionPane.ERROR_MESSAGE);
    stdout.println("Num " + numProbabilidade);
//    return(true);
  }
/*****************************************************************************/
  public void componentResized(ComponentEvent e)
  {
      scroll.getSize();
  }

  public void componentMoved(ComponentEvent e)
  {
  }
  public void componentShown(ComponentEvent e)
  {
  }
  public void componentHidden(ComponentEvent e)
  {
  }

  public void actionPerformed(ActionEvent evt) {

      if(evt.getSource() == reset_button) {               // Botco de Reiniciar
        end_button.setEnabled(true);
        step_button.setEnabled(true);
        numProbabilidade = 0;
        contarProbabilidade();
        if(input_string.getText().length() > 0) {
          if(parseProbabilidade(input_string.getText()))
            this.reset();
//          return(true);
        }
        stdout.println("Applet reinicializado");
        this.reset();

/******************************************************************************
 *
 *  O botco de Proximo pode ser visto abaixo e ele quem fara todo o controle
 *   grafico, assim como matematico em relagco aos prsximos valores a serem
 *   impressos na tela utilizando diversos mitodo diferentes
 *
 ******************************************************************************/
      } else if(evt.getSource() == step_button) {
        if(proximo) {
          if(calcProbabilidade(passo)) {
            proximo = false;
            marcador[passo] = -1;
            passo--;
          } else {
            int tmp = 0;
            for(; tmp < 400; tmp++)
              if(probabilidade[passo-1][tmp] == 0.0)
                break;
            Cent.printNextStep(passo, probabilidade[passo], marcador[passo]);
            stdout.println("As duas probabilidades inferiores da coluna " + passo
                            +" foram somadas: " +
                            f.format(probabilidade[passo-1][tmp-1]) + " + " +
                            f.format(probabilidade[passo-1][tmp-2]) + " = " +
                            f.format(probabilidade[passo][marcador[passo]]), false);
            stdout.println(1, "A soma i mostrada em negrito na coluna 2.",false);
            passo++;
          }
        }
        if(!proximo) {
          if(passo < 0) {
            Cent.setReverseStep(-1,-1,-1);
            end_button.setEnabled(false);
            step_button.setEnabled(false);
            for(int k = 0; k < 200; k++)
              if (probabilidade[0][k] != 0)
                entropia += probabilidade[0][k]*(-Math.log(probabilidade[0][k])) *
                    Math.log(10) / Math.log(2) * Math.log(Math.exp(1/(Math.log(10))));
            Double ent = new Double(entropia);
            entropia = 0;
            String cod = new String("Codigo correspondente:\n\n");
            for(int m = 0; m < 200; m++)           // Exibe o csdigo em input_string
            if (simbolo[0][m].length() > 0)
              cod += simbolo[0][m] + "\n";
            JOptionPane.showMessageDialog(null, cod, "Codigo", JOptionPane.INFORMATION_MESSAGE);
            stdout.println("Num. Prob.: " + numProbabilidade +
              "         Entropia: " + ent);
          } else {
            designaSimbolo(passo);
            Cent.printReverseStep(passo,simbolo[passo]);
            passo--;
          }
        }
      } else if(evt.getSource() == end_button) {             // Botco de conclusco
        end_button.setEnabled(false);
        step_button.setEnabled(false);
        entropia = 0;
        for(int k = 0; k < 400; k++) {
          if(proximo) {
            if(calcProbabilidade(passo)) {
              proximo = false;
              marcador[passo] = -1;
              passo--;
            } else {
              int tmp = 0;
              for(; tmp < 400; tmp++)
                if(probabilidade[passo-1][tmp] == 0.0)
                  break;
              Cent.printNextStep(passo, probabilidade[passo], marcador[passo]);
              passo++;
            }
          }
          if(!proximo) {
            if(passo < 0) {
              Cent.setReverseStep(-1,-1,-1);
            } else {
              designaSimbolo(passo);
              Cent.printReverseStep(passo,simbolo[passo]);
              passo--;
            }
          }                                   // Calculo da entropia abaixo
          if (probabilidade[0][k] != 0)
            entropia += probabilidade[0][k]*(-Math.log(probabilidade[0][k])) *
              Math.log(10) / Math.log(2) * Math.log(Math.exp(1/(Math.log(10))));
        }
        Double ent = new Double(entropia);
        entropia = 0;
        stdout.println("Entropia " + f.format(ent));
        String cod = new String("Codigo correspondente:\n\n");
        for(int m = 0; m < 200; m++)           // Exibe o csdigo em input_string
          if (simbolo[0][m].length() > 0)
            cod += simbolo[0][m] + "\n";
            JOptionPane.showMessageDialog(null, cod, "Codigo", JOptionPane.INFORMATION_MESSAGE);
            stdout.println("Num. Prob.: " + numProbabilidade +
              "         Entropia: " + ent);

//      return(true);
    } else if(evt.getSource() == input_string) {        // Utilizagco da TextBox
        end_button.setEnabled(true);
        step_button.setEnabled(true);
        numProbabilidade = 0;
        contarProbabilidade();
        if(input_string.getText().length() > 0) {
          if(parseProbabilidade(input_string.getText()))
            this.reset();
//          return(true);
        }
        stdout.println("Applet reinicializado");
        this.reset();

//        return(true);
/*  } else if(evt.getSource() == open_button) {
      numProbabilidade = 0;
      JFileChooser fileChooser = new JFileChooser();
      fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY):
//      int result = fileChooser.showSaveDialog(this);
      File fileName = fileChooser.getSelectedFile();
      if (fileName == null || fileName.getName().equals(""))
        JOptionPane.showMessageDialog(null, "Arquivo invalido.", "Erro",
          JOptionPane.ERROR_MESSAGE);
      else {
        try {
          ObjectInputStream output = new ObjectInputStream(new FileInputStream(fileName));
          ObjectOutputStream output = new ObjectOutputStream(new FileOutputStream(fileName));
        } catch (IOException e) {
          JOptionPane.showMessageDialog(null, "Erro abrindo arquivo.", "Erro",
            JOptionPane.ERROR_MESSAGE);

// Close
      try{
      output.close();
      }

// Read

      try{
        String s = (String) output.readObject();
        // Trabalhar string
      catch (EOFException, ClassNotFoundException, IOException)

      contarProbabilidade();*/
    } else {                                            // Problema!
      stdout.println("Evento desconhecido ");
//      return(false);
  }}



/******************************************************************************
 *
 *  Mitodo utilizado para se fazer o controle em relagco aos eventos controlados
 *   pela utilizagco do mouse como o clique nos dois botues existentes
 *
 ******************************************************************************/
/*  public boolean action(Event evt, Object obj) {

    String StringSimb = null;

    if(evt.target instanceof Button) {

      if(evt.target == reset_button) {                  // Botco de Reiniciar
        end_button.setEnabled(true);
        step_button.setEnabled(true);
        numProbabilidade = 0;
        contarProbabilidade();
        if(input_string.getText().length() > 0) {
          if(parseProbabilidade(input_string.getText()))
            this.reset();
          return(true);
        }
        stdout.println("Applet reinicializado");
        this.reset();

/******************************************************************************
 *
 *  O botco de Proximo pode ser visto abaixo e ele quem fara todo o controle
 *   grafico, assim como matematico em relagco aos prsximos valores a serem
 *   impressos na tela utilizando diversos mitodo diferentes
 *
 ******************************************************************************/
/*      } else if(evt.target == step_button) {
        if(proximo) {
          if(calcProbabilidade(passo)) {
            proximo = false;
            marcador[passo] = -1;
            passo--;
          } else {
            int tmp = 0;
            for(; tmp < 25; tmp++)
              if(probabilidade[passo-1][tmp] == 0.0)
                break;
            Cent.printNextStep(passo, probabilidade[passo], marcador[passo]);
            stdout.println("As duas probabilidades inferiores da coluna " + passo
                            +" foram somadas: " +
                            f.format(probabilidade[passo-1][tmp-1]) + " + " +
                            f.format(probabilidade[passo-1][tmp-2]) + " = " +
                            f.format(probabilidade[passo][marcador[passo]]), false);
            stdout.println(1, "A soma i mostrada em negrito na coluna 2.",false);
            passo++;
          }
        }
        if(!proximo) {
          if(passo < 0) {
            Cent.setReverseStep(-1,-1,-1);
            end_button.setEnabled(false);
            step_button.setEnabled(false);
            for(int k = 0; k < 25; k++)
              if (probabilidade[0][k] != 0)
                entropia += probabilidade[0][k]*(-Math.log(probabilidade[0][k])) *
                    Math.log(10) / Math.log(2) * Math.log(Math.exp(1/(Math.log(10))));
            Double ent = new Double(entropia);
            String cod = new String();
            for(int m = 0; m < 20; m++)           // Exibe o csdigo em input_string
            if (simbolo[0][m].length() > 0)
              cod += simbolo[0][m] + " ";
            JOptionPane.showMessageDialog(null, ent, "Entropia",
              JOptionPane.INFORMATION_MESSAGE);
            stdout.println(cod);
          } else {
            designaSimbolo(passo);
            Cent.printReverseStep(passo,simbolo[passo]);
            passo--;
          }
        }
      } else if(evt.target == end_button) {             // Botco de conclusco
        end_button.setEnabled(false);
        step_button.setEnabled(false);
        entropia = 0;
        for(int k = 0; k < 25; k++) {
          if(proximo) {
            if(calcProbabilidade(passo)) {
              proximo = false;
              marcador[passo] = -1;
              passo--;
            } else {
              int tmp = 0;
              for(; tmp < 25; tmp++)
                if(probabilidade[passo-1][tmp] == 0.0)
                  break;
              Cent.printNextStep(passo, probabilidade[passo], marcador[passo]);
              passo++;
            }
          }
          if(!proximo) {
            if(passo < 0) {
              Cent.setReverseStep(-1,-1,-1);
            } else {
              designaSimbolo(passo);
              Cent.printReverseStep(passo,simbolo[passo]);
              passo--;
            }
          }                                   // Calculo da entropia abaixo
          if (probabilidade[0][k] != 0)
            entropia += probabilidade[0][k]*(-Math.log(probabilidade[0][k])) *
              Math.log(10) / Math.log(2) * Math.log(Math.exp(1/(Math.log(10))));
        }
        Double ent = new Double(entropia);
        stdout.println("Entropia " + f.format(ent));
        String cod = new String();
        for(int m = 0; m < 20; m++)           // Exibe o csdigo em input_string
          if (simbolo[0][m].length() > 0)
            cod += simbolo[0][m] + " ";
        JOptionPane.showMessageDialog(null, ent, "Entropia",
          JOptionPane.INFORMATION_MESSAGE);
        stdout.println(cod);
      }
      return(true);

    } else if(evt.target instanceof TextField) {        // Utilizagco da TextBox
      if(parseProbabilidade((String)obj))reset();
        return(true);

    } else {                                            // Problema!
      stdout.println("Evento desconhecido " + obj);
      return(false);
    }
  }
*/
/******************************************************************************
 *
 *  Mitodo utilizado quando o botco Reiniciar i pressionado, ele reinicia os
 *   valores para todas variaveis, limpa o GUI e coloca na primeira coluna
 *   os primeiros valores utilizados na zltima experimentagco
 *
 ******************************************************************************/
  void reset() {
    int i = 0, j = 0;
    Cent.clearScreen(probabilidade[0]);
    proximo = true;
    passo = 1;
    for(i = 0; i < 200; i++)
      marcador[i] = -1;
    for(i = 0; i < 200; i++)
      for(j = 0; j < 250; j++)
        simbolo[i][j] = "";
  }

/******************************************************************************
 *
 *  Testa quanto a viabilidade das probabilidades inseridas no TextBox estarem
 *   de acordo com os criterios adotados e i bem simples para ser compreendida
 *
 ******************************************************************************/
  boolean parseProbabilidade(String s) {

    int linha = 0, i = 0;
    double soma = 0.0;
    double[] d = new double[200];
    StringTokenizer st = new StringTokenizer(s);

    for(i = 0; i < 200; i++)
      d[i] = 0.0;

    i = 0;

    while (st.hasMoreTokens()) {
      try {
        d[i] = Double.valueOf(st.nextToken()).doubleValue();
        if(d[i] < 0) {
//    JOptionPane.showMessageDialog(null, "Probabilidade negativa.", "Erro",
//        JOptionPane.ERROR_MESSAGE);
//          stdout.println("Erro: Probabilidade negativa.");
          return(false);
        }
        if(d[i] > 1.0) {
//    JOptionPane.showMessageDialog(null, "Probabilidade maior que 1. ", "Erro",
//        JOptionPane.ERROR_MESSAGE);
//          stdout.println("Erro: Probabilidade maior que 1.");
          return(false);
        }
        if(d[i] == 0.0) {
//    JOptionPane.showMessageDialog(null, "Probabilidade ihual a 0.", "Erro",
//        JOptionPane.ERROR_MESSAGE);
//          stdout.println("Erro: Probabilidade igual a 0.");
          return(false);
        }
      } catch (NumberFormatException e) {
        JOptionPane.showMessageDialog(null, "Os nzmeros nco estao em sua forma correta",
            "Erro", JOptionPane.ERROR_MESSAGE);
//        stdout.println("Erro: Os nzmeros nco estao em sua forma correta.");
        return(false);
      }
      i++;
/*      if(i > 200) {
        if(st.hasMoreTokens()) {
          stdout.println("Erro: Sco permitidos ati 20 Tokens.");
          return(false);
        }
      }*/
    }

    bubblesort(d);
    for(i = 0; i < 200; i++) {
      soma += d[i];
    }

    if((soma <= 0.999999) || (soma >= 1.000001)) {
//    JOptionPane.showMessageDialog(null, "A soma das probabilidadades nco e igual a 1." +
//          "\nA soma das probabilidade foi " + soma, "Erro", JOptionPane.ERROR_MESSAGE);
      stdout.println(linha,"Erro: A soma das probabilidades nco i igual a 1.");
      stdout.println("A soma das probabilidades foi " + soma);
      return(false);
    }

    for(i = 0; i < 200; i++)
      probabilidade[0][i] = d[i];

    stdout.println("Entrada de probabilidades correta. Pressione " + '\"' +
                      "Proximo" + '\"' + " para continuar.");
//    stdout.println(" " + numProbabilidade);
    return(true);
  }

/******************************************************************************
 *
 *  Este mitodo sera utilizado como sentinela pra a inicializagco das
 *   probabilidades
 *
 ******************************************************************************/
  void iniciarProbabilidade(double[] p) {
    inic = false;
    iniciarProbabilidade(p, p.length-1);
  }

/******************************************************************************
 *
 *  Executa a inicializagco para alguns valores das probabilidades a partir
 *   do objeto Rand()
 *
 ******************************************************************************/
  void iniciarProbabilidade(double[] p, int n) {

    Random rand = new Random();
    double soma = 0.0, s = 0.0;
    int i = 0;
    String input = " ";
    stdout.println(null);                     // Limpa o texto abaixo

    for(; i < 20; i++) {
        p[i] = rand.nextDouble() + 0.1;       // Gera os nzmeros iniciais
        soma += p[i];                         //  onde se deseja valores prsximos
    }

    for(i = 0; i < 20; i++) {
      p[i] /= soma;                           // Escalonamento
      p[i] = Math.floor(p[i]*100) / 100.0;    // Truncamento
      s += p[i];
    }

    for(i = 0; i < 20; i++)                   // Utilizado para equilibrar as
      if(p[i] < 0.001) {                      //  probabilidades
        p[i] += 0.01;
        s -= 0.01;
      }

    if (s < 1.000) {                          // Utilizado para inteirar a soma
      double resto = 1.0 - s;
      p[0] += resto;
    }

    bubblesort(p);

    for(int k = 0; k < 20; k++)               // Constroi string a ser exibida
      input += f2.format(p[k]) + " ";         //  dentro de string_input
    String input2 = input.replace(',','.');

    input_string.setText(input2);
    contarProbabilidade();
  }

/******************************************************************************
 *
 *  Faz um sort bem comum de todos as probabilidades inseridas
 *
 ******************************************************************************/
  void bubblesort(double[] d) {
    for(int i = 0; i < (d.length - 1); i++)
      for(int j = 0; j < (d.length - 1); j++)
        if(d[j] < d[j+1]) {
          double t = d[j];
          d[j] = d[j+1];
          d[j+1] = t;
        }
  }

/******************************************************************************
 *
 *  Calcula o valor da probabilidade resultante a partir da soma das duas
 *   probabilidades anteriores e seu csdigo i representando somente por loops
 *   que setam estes valores  
 *
 ******************************************************************************/
  boolean calcProbabilidade(int passo) {

    int n = 0, i = 0;
    double soma = 0.0;

    if(passo >= 0) {
      for(; i < 400; i++)
        if(probabilidade[passo-1][i] == 0.0)
          break;
      n = i;
      soma = probabilidade[passo-1][n-1] + probabilidade[passo-1][n-2];

      for(i = 0; i < 200; i++)
        if(probabilidade[passo-1][i] >= soma) {
          probabilidade[passo][i] = probabilidade[passo-1][i];
        } else
          break;

      marcador[passo] = i;
      probabilidade[passo][i] = soma;
      for(; i < 200; i++)
        probabilidade[passo][i+1] = probabilidade[passo-1][i];
      probabilidade[passo][n-1] = 0.0;
      probabilidade[passo][n] = 0.0;

      if(n == 2)
        return(true);
      else
        return(false);
    }
    return(true);
  }

/******************************************************************************
 *
 *  Designa todos os smmbolos ou csdigos para as probabilidades inseridas
 *   a partir do controle feito pelos mitodos "actionPerformed" e
 *   "calcProbabilidade"
 *
 ******************************************************************************/
  void designaSimbolo(int passo) {

    int i = 0, m = marcador[passo+1];
    String str = "";

    if(m == -1) {
      simbolo[passo][0] = "0";
      simbolo[passo][1] = "1";
      stdout.println("Os primeiros valores (0 e 1) foram designados na coluna" +
                     " da extrema direita.", false);
    } else {
      for(; i < 400; i++)
        if(probabilidade[passo+1][i] != 0.0) {
          if(m == i) {
            str = simbolo[passo+1][i];
          } else if(m < i) {
            simbolo[passo][i-1] = simbolo[passo+1][i];
          } else if(m > i) {
            simbolo[passo][i] = simbolo[passo+1][i];
          } else
            System.out.println("Problema!!!");
        } else
          break;
      Cent.setReverseStep(passo,i,m);
      stdout.println("O csdigo correspondente a probabilidade marcada (" +
                       f.format(probabilidade[passo+1][m]) +
                     ") foi usado como base para se designar os valores.", false);
      stdout.println(1,"O csdigo das duas probabilidade inferiores (" +
                       f.format(probabilidade[passo][i-1]) + ")(" +
                       f.format(probabilidade[passo][i]) + ")" +
                       " foram modificados. Os outros csdigos permanecem" +
                       " os mesmos.", false);

      simbolo[passo][i-1] = str + "0";
      simbolo[passo][i] = str + "1";
    }
  }

/******************************************************************************
 *
 *  Inicializa todo o aplicativo
 *
 ******************************************************************************/
/*  public static void main(String args[]) {

    JFrame f = new JFrame("Csdigo de Huffman");
    Huff codigo = new Huff();

    codigo.inAnApplet = false;
    codigo.init();
    f.getContentPane().add("Center", codigo);
    f.setSize(800,600);
    f.show();
    codigo.start();
  }*/
}

/******************************************************************************
 *
 *  A classe abaixo i utilizada para o controle de todas as mensagens exibidas
 *   ao usuario do applet a partir do JPanel stdout, assim como comunicagco
 *   via interface MS-DOS
 *
 ******************************************************************************/
class ErrorCanvas extends Canvas {

  private String output, output2;

  public void paint(Graphics g) {
    if(output == null) {
      g.drawString("Csdigo de Huffman", 350, 20);
      g.drawString("Arildo Franga Oliva Filho - 99/32810", 20, 40);
      g.drawString("Leonardo Lobo Pulcineli - 99/20064", 20, 60);
      g.drawString("Marcos Garrison Dytz - 99/20102", 550, 40);
      g.drawString("Octavio do Vale Rocha - 99/20129", 550, 60);
    } else {
      g.drawString(output,20,20);
    }
  }

  void println(String s)
  {
    println(0,s);
  }

  void println(String s,boolean echo)
  {
    println(0,s,echo);
  }

  void println(int linha,String s)
  {
    println(linha,s,true);
  }

  void println(int linha,String s,boolean echo)
  {
    if(linha == 0)
    {
      output = s;
      output2 = "";
    } else
      output2 = s;
    this.repaint();
    if(s != null && echo)
      System.out.println(s);
  }
}

/******************************************************************************
 *
 *  A classe abaixo i utilizada na criagco de toda a interface grafica utilizada
 *   pelo programa como as diversas setas que ligam as probabilidades, a criagco
 *   das colunas e controle em relagco as cores dos csdigos.
 *  Grande parte do csdigo deste classe deve ser creditado a Paul Williams.
 *
 ******************************************************************************/
class cent extends JPanel {

  private int reverse_step = -1;
  private int rs_y, rs_m;
  private String[][] buffer;       // O conjunto de variaveis abaixo controlam
  private int[] xoffsets;          //  todo o posicionamento dos diferentes
  private int[] yoffsets;          //  objetos na tela
  private int[] lines;
  private int yoffset,yhalfoffset,linexoffset,
              ybelowoffset,xrightoffset;
  protected boolean isinit = false;
  protected boolean repainting = false;
  Font boldfont = null, deffont;
  DecimalFormat f = new DecimalFormat("0.00");

/******************************************************************************
 *
 *  Executa a inicializagco de todas variaveis e arrays, assim como dos objetos
 *   que serco manipulados pela interface grafica caso eles nco tenham ocorrido
 *
 ******************************************************************************/
  void init() {

    if(!isinit) {
      xoffsets = new int[200];
      for(int k =0; k < xoffsets.length; k++)
        xoffsets[k] = 40 + k * 60;

      yoffset = 16;
      yoffsets = new int[400];

      int i;
      for(i = 0; i < 400; i++)
        yoffsets[i] = 30 * (i+1) + 60;

      buffer = new String[200][400];

      int j;
      for(i = 0; i < 200; i++)
        for(j = 0; j < 400; j++)
          buffer[i][j] = "";

      lines = new int[400];
      for(i = 0; i < lines.length; i++)
        lines[i] = -1;
      linexoffset = 45;   // offset of left of line from left of text
      xrightoffset = 5;   // offset between forward and reverse(red) text
      ybelowoffset = 12;  // offset between forward and reverse(red) text
      yhalfoffset = 5;    // offset for lines (half a character)

      deffont = new Font("Dialog", 0, 12);
      boldfont = new Font("Dialog", Font.BOLD, 12);

      if(deffont == null || boldfont == null) {
        boldfont = null;
        System.out.println("Nco foi possmvel indicar o valor para as fontes.");
      }

      isinit = true;
      repainting = false;
    }
  }
 
/******************************************************************************
 *
 *  Construtor para essa classe e define que se a classe nco tive sido inicia-
 *   lizada, entco sera por este construtor
 *
 ******************************************************************************/
  public cent()
  {
    if(!isinit)
      this.init();
  }

/******************************************************************************
 *
 *  Limpa todo o contezdo exibido no JPanel Cent
 *  
 *****************************************************************************/
  void clearScreen(double[] p) {

    int i,j;

    for(i = 0; i < 200; i++)
      for(j = 0; j < 400; j++)
        buffer[i][j] = "";
    for(i = 0;i < lines.length; i++)
      lines[i] = -1;

    for(i = 0; i < 200; i++) {
      if(p[i] == 0.0)
        buffer[0][i*2] = "";
      else
        buffer[0][i*2] = f.format(p[i]);
    }

    repaint();
  }

/******************************************************************************
 *
 *  Imprime a prsxima coluna a ser exibida na tela
 *
 ******************************************************************************/

  void printNextStep(int number, double[] p, int marker) {

    int i;

    for(i = 0; i < 200; i++) {
      if(p[i] == 0.0)
        buffer[number][i*2] = "";
      else if(i == marker) {
        buffer[number][i*2] = "b" + f.format(p[i]);
      } else
        buffer[number][i*2] = f.format(p[i]);
    }

    Graphics g = getGraphics();
    drawForward(g,number);
  }

/******************************************************************************
 *
 *  Imprime o prsximo passo no sentido reverso
 *
 ******************************************************************************/
  void printReverseStep(int number, String[] p) {

    int i;

    for(i = 0; i < 200; i++) {
      buffer[number][i*2+1] = p[i];
    }

    Graphics g = getGraphics();
    drawReverse(g, number);
    highlightReverse(g, Color.blue);
  }

/******************************************************************************
 *
 *  Indica o prsximo passo reverso
 *
 ******************************************************************************/
  void setReverseStep(int i, int j, int m) {

    Graphics g = getGraphics();
    highlightReverse(g, Color.red);
    reverse_step = i;
    rs_y = j;
    rs_m = m;
  }

/******************************************************************************
 *
 *  Desenha o prsximo passo, assim como configura as cores e os valores a serem
 *   utilizados no proximo passo
 *
 ******************************************************************************/
  void drawForward(Graphics g, int column) {

    if((g != null) && (xoffsets != null) && (yoffsets != null))
      for(int i = 0; i < 200; i++)  {
      if((buffer[column][i*2].indexOf("b") == 0) && (boldfont != null)) {
        g.setFont(boldfont);
        g.drawString(buffer[column][i*2].substring(1), xoffsets[column],
                                                      yoffsets[i]);
        g.setFont(deffont);
        addLine(g, column, i);
      } else
        g.drawString(buffer[column][i*2], xoffsets[column], yoffsets[i]);
    }
  }

/******************************************************************************
 *
 *  Desenha o prsximo passo, assim como configura  as cores e e os valores a
 *  serem utilizado no proximo sentido reverso
 *
 ******************************************************************************/
  void drawReverse(Graphics g,int column) {

    if((g != null) && (xoffsets != null) && (yoffsets != null)) {
      FontMetrics fmd = getFontMetrics(deffont);
      FontMetrics fmb = getFontMetrics(boldfont);
      FontMetrics fm = fmd;
      int ascentd = fmd.getAscent(), width, x, y, ascentb = fmb.getAscent();

      Color col = g.getColor();
      g.setColor(Color.red);

      int ascent = ascentd, tmp;
      for(tmp = 0; tmp < 400; tmp++)
        if(buffer[column][tmp*2+1].length() == 0)
          break;
      if(tmp != 2)
        tmp -= 2;

      for(int i = 0; i < 200; i++) {

        if(i == tmp) {
          ascent = ascentb;
          fm = fmb;
        }
        width = fm.stringWidth(buffer[column][i*2+1]);
        x = xoffsets[column] + xrightoffset;
        y = yoffsets[i] + ybelowoffset;

        int lo = linexoffset - 10;
        g.clearRect(x+lo, y-ascent, width-lo, ascent);
        g.drawString(buffer[column][i*2+1], x, y);
      }

      g.setFont(deffont);
      g.setColor(col);
    }
  }
 
/******************************************************************************
 *
 *  Coloca numa cor diferente o codigo que sera modificado no proximo passo
 *   reverso
 *
 ******************************************************************************/
  void highlightReverse(Graphics g, Color col) {

    if((g != null) && (reverse_step >= 0)) {
      Color c = g.getColor();
      String s;
      g.setColor(col);
      g.drawString(buffer[reverse_step+1][rs_m*2+1],
                   xoffsets[reverse_step+1]+xrightoffset,
                   yoffsets[rs_m]+ybelowoffset);
      s = buffer[reverse_step][rs_y*2+1];
      if(s.length() > 0)
        g.drawString(s.substring(0, s.length()-1),
                   xoffsets[reverse_step] + xrightoffset,
                   yoffsets[rs_y] + ybelowoffset);
      s = buffer[reverse_step][(rs_y-1)*2+1];
      if(s.length() > 0)
        g.drawString(s.substring(0, s.length()-1),
                   xoffsets[reverse_step] + xrightoffset,
                   yoffsets[rs_y-1] + ybelowoffset);
      g.setColor(c);
    }
  }

/******************************************************************************
 *
 *  Adiciona uma linha ligando a soma de duas probabilidade a probablidade
 *   resultante, faz o papel lsgico nessa etapa
 *
 ******************************************************************************/

  void addLine(Graphics g,int column,int to) {

    int from;

    for(from = 0; buffer[column][from*2] != ""; from++);
      lines[2*column] = from;
      lines[2*column+1] = to;
      drawLine(g, column);
  }

/******************************************************************************
 *
 *  Desenha uma linha ligando a soma de duas probabilidade a probablidade
 *   resultante utilizando uma "escovagco" dos pixels nas tela, faz o parte
 *   grafico nesta etapa
 *
 ******************************************************************************/
  void drawLine(Graphics g, int column) {

    int fromx, fromy, tox, toy;

    if((g != null) && (xoffsets != null) && (yoffsets != null) &&
      lines[2*column+1] != -1) {

      fromx = xoffsets[column-1] + linexoffset;
      fromy = yoffsets[lines[2*column]] -
              (yhalfoffset + (yoffsets[lines[2*column]] -
                            yoffsets[lines[2*column] - 1]) / 2);
      tox = xoffsets[column] - 3;
      toy = yoffsets[lines[2*column+1]] - yhalfoffset;

      Color col = g.getColor();
      g.setColor(Color.blue);
      g.drawLine(fromx, fromy, tox, toy);

      g.drawLine(fromx-1, fromy-15, fromx-1, fromy+15);
      g.drawLine(fromx-1, fromy+15, fromx-5, fromy+15);
      g.drawLine(fromx-1, fromy-15, fromx-5, fromy-15);

      double theta = Math.atan2(toy-fromy, tox-fromx);
      Polygon poly = new Polygon();
      poly.addPoint(tox, toy);
      poly.addPoint((int)Math.round(tox-12*Math.cos(theta+0.2)),
                    (int)Math.round(toy-12*Math.sin(theta+0.2)));
      poly.addPoint((int)Math.round(tox-12*Math.cos(theta-0.2)),
                    (int)Math.round(toy-12*Math.sin(theta-0.2)));

      g.fillPolygon(poly);

      g.setColor(col);
    }
  }

/******************************************************************************
 *
 *  Executa toda a pintura de acordo com os princmpios da interface AWT
 *
 ******************************************************************************/
  public void paint(Graphics g) {

    int i;

    for(i = 0; i < 200; i++)                  // Desenha prsximas probabilidades
      drawForward(g,i);
    for(i = 0; i < 200; i++)                  // Desenha linha ligando probs.
      drawLine(g,i);
    for(i = 0; i < 200; i++)                  // Desenha csdigos para cada prob.
      drawReverse(g,i);
    highlightReverse(g, Color.blue);
  }

/******************************************************************************
 *
 *  Define um tamanho para o JPanel que sera instanciado em Huff
 *  
 ******************************************************************************/
  public Dimension getPreferredSize()
  {
        return new Dimension(800, 600);
  }
}
Commented:
If you change the paint(Graphics) method to paintComponent(Graphics) in your "cert" class it seems to cure the rendering issue. When overriding Swing paint classes always override the paintComponent() method and not paint().

Your painting methods take a long time, so scrolling is probably slower than you want. You may want to try to optimize them.

Here's how I changed the paint(Graphics) method to paintComponent(Graphics):
public void paintComponent(Graphics g) {
      super.paintComponent(g);
   int i;
   for(i = 0; i < 200; i++)                  // Desenha próximas probabilidades
     drawForward(g,i);
   for(i = 0; i < 200; i++)                  // Desenha linha ligando probs.
     drawLine(g,i);
   for(i = 0; i < 200; i++)                  // Desenha códigos para cada prob.
     drawReverse(g,i);
   highlightReverse(g, Color.blue);
 }

Author

Commented:
Great help!!!
Mick BarryJava Developer
Top Expert 2010

Commented:
Marcus,
Sorry I missed that one.
In Swing the paint() method also performs a lot of other operations, so should generally not be overridden (and if you need to then be sure to call super.paint(g).

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial