[英]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()可以解決問題,但這最終發生了。
第一次打印歌詞 在我更改歌詞並嘗試替換以前的歌詞之后。
GUI.frame.remove(scroll);
,刪除新的 JScrollPane(尚未添加的JScrollPane),而不是當前駐留在GUI中的舊JScrollPane。 GUI.frame....
呼叫表明您可能GUI.frame....
靜態字段。 除非您不關心維護數據和行為的封裝,否則JFrame不應由靜態字段保存。 編輯
我推薦的是
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.