簡體   English   中英

Java GUI重繪JPanel JFrame的問題

[英]problems with Java GUI repainting JPanel JFrame

計划是讓程序在搜索另一首歌曲時用不同的歌詞替換屏幕上的歌詞。

}public void lyricPrinter(){
    if(scroll != null){
    scroll.removeAll(); //--> temporary test
    System.out.println("removed scroll");
    scroll.repaint();
    }

    JTextArea textarea = new JTextArea(lyrics);
    textarea.setBackground(Color.LIGHT_GRAY);
    textarea.setEditable(false);


    scroll = new JScrollPane (textarea,JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);

    GUI.frame.remove(scroll);
    GUI.frame.add(scroll);
    GUI.frame.setVisible(true);




}

我以為使用removeall()可以解決問題,但這最終發生了。

第一次打印歌詞 第一次打印歌詞 在我更改歌詞並嘗試替換以前的歌詞之后。 在我更改歌詞並嘗試替換以前的歌詞之后。

  • 為什么要添加和刪除組件? 這是實現目標的一種落后而危險的方式。
  • 即使您的計划還可以,您實際上也不會在任何地方刪除原始的JScrollPane。 此調用GUI.frame.remove(scroll); ,刪除新的 JScrollPane(尚未添加的JScrollPane),而不是當前駐留在GUI中的舊JScrollPane。
  • 相反,為什么不集中精力保留組件並交換它們持有的數據-他們的文本呢? 這就是我要做的,也是我強烈建議的。
  • 您的GUI.frame....呼叫表明您可能GUI.frame....靜態字段。 除非您不關心維護數據和行為的封裝,否則JFrame不應由靜態字段保存。

編輯
我推薦的是

  • 您有一個JTextArea字段,其中包含您的歌曲歌詞的文本,
  • 它是您類中的一個非靜態字段,由於未在構造函數或方法內部聲明,因此在整個類中都是可見的。
  • 在您要交換歌詞的事件代碼中,只需在此JTextArea變量上調用setText(...) ,並傳入包含新歌詞的String。

假設您有一個名為songLyricsTextArea的JTextArea,要交換文本,您要做的就是

String newLyrics = somehowGetNewLyricsToSong(); 
songLyricsTextArea.setText(newLyrics);

例如,在下面的演示程序中,我閱讀了Java Swing教程中包含的幾個演示程序的Java代碼。 我將程序名稱放在右側的JList中,並給JList一個ListSelectionListener,該ListSelectionListener交換JTextArea(此處稱為programTextArea)中的文本,類似於我建議您執行的操作。 我的演示中的關鍵代碼在此處的偵聽器中:

  demoList.addListSelectionListener(new ListSelectionListener() {

     @Override    // a new program has been selected
     public void valueChanged(ListSelectionEvent e) {
        if (!e.getValueIsAdjusting()) {
           if (demoList.getSelectedIndex() != -1) { // make sure selection valid
              DemoProgram demoProgram = demoList.getSelectedValue(); // get selection
              programTextArea.setText(demoProgram.getText());  // get text and pass into text area
           }
        }
     }
  });

因此,您應該編譯並運行以查看其工作原理的整個程序是:

import java.awt.BorderLayout;
import java.io.IOException;
import java.net.URL;
import java.util.Scanner;

import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

@SuppressWarnings("serial")
public class SwapTextExample extends JPanel {
   private static final String[][] DEMO_PROGS = {
         {     "BorderDemo.java",
               "http://docs.oracle.com/javase/tutorial/uiswing/examples/"
                     + "components/BorderDemoProject/src/components/BorderDemo.java" },
         {     "ButtonDemo.java",
               "http://docs.oracle.com/javase/tutorial/uiswing/examples/"
                     + "components/ButtonDemoProject/src/components/ButtonDemo.java" },
         {     "ButtonHtmlDemo.java",
               "http://docs.oracle.com/javase/tutorial/uiswing/examples/"
                     + "components/ButtonHtmlDemoProject/src/components/ButtonHtmlDemo.java" },
         {     "CheckBoxDemo.java",
               "http://docs.oracle.com/javase/tutorial/uiswing/examples/"
                     + "components/CheckBoxDemoProject/src/components/CheckBoxDemo.java" },
         {     "ComboBoxDemo.java",
               "http://docs.oracle.com/javase/tutorial/uiswing/examples/"
                     + "components/ComboBoxDemoProject/src/components/ComboBoxDemo.java" }, };

   private DefaultListModel<DemoProgram> model = new DefaultListModel<>();
   private JList<DemoProgram> demoList = new JList<DemoProgram>(model);
   private JTextArea programTextArea = new JTextArea(40, 70);

   public SwapTextExample() throws IOException {
      for (String[] demoProgText : DEMO_PROGS) {
         String name = demoProgText[0];
         String link = demoProgText[1];
         URL url = new URL(link);
         Scanner scanner = null;
         try {
            scanner = new Scanner(url.openStream());
            StringBuilder sb = new StringBuilder();
            while (scanner.hasNextLine()) {
               sb.append(scanner.nextLine() + "\n");
            }
            String text = sb.toString();
            DemoProgram demoProg = new DemoProgram(name, link, text);
            model.addElement(demoProg);
         } finally {
            if (scanner != null) {
               scanner.close();
            }
         }

      }

      demoList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
      demoList.addListSelectionListener(new ListSelectionListener() {

         @Override    // a new program has been selected
         public void valueChanged(ListSelectionEvent e) {
            if (!e.getValueIsAdjusting()) {
               if (demoList.getSelectedIndex() != -1) { // make sure selection valid
                  DemoProgram demoProgram = demoList.getSelectedValue(); // get selection
                  programTextArea.setText(demoProgram.getText());  // get text and pass into text area
               }
            }
         }
      });

      setLayout(new BorderLayout());
      add(new JScrollPane(demoList), BorderLayout.WEST);
      add(new JScrollPane(programTextArea), BorderLayout.CENTER);
   }

   private static void createAndShowGui() {
      SwapTextExample mainPanel;
      try {
         mainPanel = new SwapTextExample();
         JFrame frame = new JFrame("Swap Text Example");
         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
         frame.getContentPane().add(mainPanel);
         frame.pack();
         frame.setLocationByPlatform(true);
         frame.setVisible(true);
      } catch (IOException e) {
         e.printStackTrace();
      }

   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

class DemoProgram {
   private String name;
   private String link;
   private String text;

   public DemoProgram(String name, String link, String text) {
      this.name = name;
      this.link = link;
      this.text = text;
   }

   public String getName() {
      return name;
   }

   public String getLink() {
      return link;
   }

   public String getText() {
      return text;
   }

   @Override
   public String toString() {
      return name;
   }
}

您永遠不會刪除舊的滾動窗格。 移動您的GUI.frame.remove(scroll); 在創建新的滾動窗格之前。

我通過簡單地刪除文本區域然后讀取更新的區域來解決此問題。 比從滾動窗格中刪除文本更容易,但是仍然保留實際的窗格,然后嘗試在其頂部添加一個新窗格。

}public void lyricPrinter(){
    if(scroll != null){
    //scroll.removeAll(); //--> temporary test
    //System.out.println("removed scroll");
    //scroll.repaint();
    GUI.frame.remove(scroll);
    }

    JTextArea textarea = new JTextArea(lyrics);
    textarea.setBackground(Color.LIGHT_GRAY);
    textarea.setEditable(false);


    scroll = new JScrollPane (textarea,JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);


    GUI.frame.add(scroll);
    GUI.frame.setVisible(true);




}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM