2012-04-12 2 views
2

У меня есть главный JPanel (в JApplet), который содержит дочерний JPanel и кнопку. Я хочу нажать кнопку, чтобы удалить дочерний JPanel, а другой дочерний JPanel добавлен в основную JPanel, но проблема в том, что только когда я отбрасываю кнопку или корректирую размер JApplet, тогда будет второй дочерний JPanel apprear.Repaint JPanel не работает в JApplet

слушатель моей кнопки:

button.addActionListener(new ActionListener(){ 

     @Override 
     public void actionPerformed(ActionEvent e) { 
      panel.remove(custompanel); 
      panel.add(new CustomPanel("/hinhtu2.jpg"), BorderLayout.CENTER); 
      panel.repaint(); 
      panel.revalidate(); 

     } 
     }); 

Весь мой код:

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Graphics; 
import java.awt.Image; 
import java.awt.Toolkit; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.io.File; 
import java.io.IOException; 

import javax.imageio.ImageIO; 
import javax.swing.BorderFactory; 
import javax.swing.ImageIcon; 
import javax.swing.JApplet; 
import javax.swing.JButton; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 

public class applet extends JApplet { 
    public void init() { 

    try { 
     javax.swing.SwingUtilities.invokeLater(new Runnable() { 
      public void run() { 
       createGUI(); 
      } 
     }); 
    } catch (Exception e) { 
     //System.err.println("createGUI didn't successfully complete"); 
     e.printStackTrace(); 
    } 
} 

private void createGUI() { 
    final JPanel panel = new JPanel(new BorderLayout()); 
    JButton button = new JButton("CLICK ME"); 
    panel.add(button, BorderLayout.SOUTH); 
    final CustomPanel custompanel = new CustomPanel("/hinhtu.jpg"); 
    panel.add(custompanel, BorderLayout.CENTER); 

    button.addActionListener(new ActionListener(){ 

     @Override 
     public void actionPerformed(ActionEvent e) { 
      panel.remove(custompanel); 
      panel.add(new CustomPanel("/hinhtu2.jpg"), BorderLayout.CENTER); 
      panel.repaint(); 
      panel.revalidate(); 

     } 

     }); 

    add(panel); 
    } 

public class CustomPanel extends JPanel{ 
    String resource; 
    public CustomPanel(String resource){ 
     super(); 
     this.resource = resource; 



    } 
    public void paintComponent(Graphics g) { 



     Image x = Toolkit.getDefaultToolkit().getImage(getClass().getResource(resource)); 
     g.drawImage(x, 0, 0, null); 

    } 



} 

}

Мой экран записи: http://www.screenr.com/prx8

+1

Можете ли вы уточнить, почему именно этот образ вам нужен, почему бы не поместить это изображение в «JLabel», а затем добавить его в «JPanel», кроме того, загрузка изображений в JApplets всегда должна выполняться в отдельном потоке, как также указано в [Java Docs] (http://docs.oracle.com/javase/tutorial/uiswing/components/applet.html#images). +1, эта вещь заставила меня чему-то научиться сегодня :-) –

+1

1) * «Весь мой код:» * Для лучшей помощи раньше, отправьте сообщение [SSCCE] (http://sscce.org/). У этого кода нет импорта, и у нас нет «hinhtu2.jpg» здесь. 2) Будьте внимательны при использовании форматирования кода, который пропустил закрытие '' '3. Методы рисования по-прежнему совершают те же ошибки, что и ваш последний вопрос. 4) Вместо удаления компонентов используйте «CardLayout». 5) Было бы лучше, если бы вы описали, что делает этот апплет, и конечный эффект, который вы пытаетесь достичь, поскольку «способ, которым вы собираетесь добиваться» обычно «очень субоптимальный». –

+0

@AndrewThompson: 1. Я отредактировал вопрос, hinhtu2.jpg добавлен в тот же путь с моими файлами класса java. 3. Не могли бы вы сказать, с какими ошибками сталкиваются? 5. Я начал с апплета, так что это просто попытка здесь :). –

ответ

4

Вы должны позвонить перепроверить, прежде чем перекрашивать здесь:

 panel.remove(custompanel); 
     panel.add(new CustomPanel("/hinhtu2.jpg"), BorderLayout.CENTER); 
     panel.repaint(); 
     panel.revalidate(); 

Revalidate call обновляет контейнерную иерархию, и после этого может потребоваться перекраска. Размер контейнера делает оба (revalidate and repaint), поэтому панель появляется после изменения размера апплета.

Также я заметил 1 плохо в yuor кода:

public void paintComponent(Graphics g) { 
    Image x = Toolkit.getDefaultToolkit().getImage(getClass().getResource(resource)); 
    g.drawImage(x, 0, 0, null); 
} 

Вы загружаемое изображению каждый времени пользовательских перерисовки компонентов. Лучше переместите загрузку изображения в конструктор и загрузите его только один раз.

+0

revalidate перед тем, как перекрасить не получится. –

+1

Вы хотите добавить панель только один раз или с каждой кнопкой щелкнуть? Поскольку ваш код будет делать это только один раз - custompanel всегда будет иметь старое значение первой панели ... И еще одно угадающее предположение - ваш метод paintComponent может не загружать первый вызов image @, который заставит его «отображаться» только после второй/третьей перерисовки. Попробуйте загрузить загружаемую картинку за пределы метод рисования и посмотреть, помогает ли это. –

+0

Кажется странным, когда я обращаюсь к апплету в браузере на другом компьютере, кнопка щелчка работает хорошо ... –